2012-08-22 34 views
7

Tôi cần đọc và lọc tệp thuộc tính từ một vị trí bên ngoài dự án của tôi, giả sử $ {user.home} /my.properties. Tệp thuộc tính này trông giống như sau:Làm thế nào để thiết lập các thuộc tính xây dựng từ một tệp trong Maven POM?

res.dir=/my/stuff/here 
resource.dir=C:/${res.dir} 
bin.dir=${resource.dir}/bin 
cfg.dir=${resource.dir}/config 

Tôi phải làm điều này trong cả bản dựng và trong ứng dụng khi chạy. Điều này rất dễ làm trong Ant, sử dụng PROPERTY tag. Tuy nhiên, dường như không có cách nào tốt để làm điều đó trong Maven.

Cho đến giờ tôi đã thử thẻ Maven <property>, thẻ Maven <filter> và các hoán vị khác nhau của các thẻ khác. Xây dựng của tôi không thành công hoặc kiểm tra đơn vị không thành công hoặc cả hai.

Nếu tôi mã hóa các thuộc tính này vào POM, mọi thứ đều hoạt động, vì vậy tôi biết vấn đề chỉ là đọc các thuộc tính.

Tôi đã xem properties-maven-plugin nhưng plugin dường như không còn được duy trì nữa.

Có cách nào để thực hiện việc này không?

+0

Tôi đã thấy nhận xét của bạn về plugin, vì vậy, hãy xóa câu trả lời của tôi. Chỉ muốn cho bạn biết rằng dù được duy trì hay không duy trì, nó hoạt động. (hoặc ít nhất, được sử dụng để làm việc). – crnlx

+0

Cảm ơn bạn đã phản hồi. Có, tôi sẽ nghĩ rằng nếu plugin không còn được duy trì hoặc thậm chí được phát triển (nó được liệt kê là "Alpha") thì có thể không phát triển thêm nữa (nghi ngờ) hoặc có cách tốt hơn để thực hiện việc này. Tôi hy vọng một người nào đó sẽ chỉ cho tôi hướng tới "cách tốt hơn". – user1071914

+1

Điều gì đưa bạn đến giả định rằng plugin sẽ không được duy trì nữa? Hơn nữa các thuộc tính bên ngoài dự án Maven sẽ làm cho dự án của bạn phụ thuộc vào những thứ sẽ phá vỡ khái niệm Maven để có mọi thứ cần thiết cho một dự án Maven bên trong dự án. Câu hỏi đặt ra là tại sao bạn cần điều này? – khmarbaise

Trả lời

7

Bạn chỉ cần triển khai maven-plugin của riêng mình để đảm bảo việc này cho bạn.

Dưới đây là một ví dụ với cấu trúc sau:

. 
|-- pom.xml 
|-- plugin 
| `-- pom.xml 
| `-- src 
|  `-- main 
|   `-- java 
`-- app 
    `-- pom.xml 
    `-- src 
     `-- main 
      `-- java 

Bạn sẽ cần phải tạo ra một Mojo mà mất tập các thuộc tính như một đầu vào và sau đó lan truyền các thuộc tính cho pom.xml của app.pom.xml thực sự sẽ không được cập nhật mà chỉ là dữ liệu dự án trong đó.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.stackoverflow</groupId> 
    <artifactId>Q12082277</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>pom</packaging> 

    <name>${project.artifactId}-${project.version}</name> 

    <modules> 
     <module>plugin</module> 
     <module>app</module> 
    </modules> 

</project> 

plugin/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <parent> 
     <groupId>com.stackoverflow</groupId> 
     <artifactId>Q12082277</artifactId> 
     <version>1.0-SNAPSHOT</version> 
    </parent> 

    <artifactId>Q12082277-plugin</artifactId> 
    <packaging>maven-plugin</packaging> 

    <name>${project.artifactId}-${project.version}</name> 

    <dependencies> 
     <dependency> 
      <groupId>org.apache.maven</groupId> 
      <artifactId>maven-plugin-api</artifactId> 
      <version>3.0.4</version> 
     </dependency> 
     <dependency> 
      <groupId>org.apache.maven</groupId> 
      <artifactId>maven-project</artifactId> 
      <version>2.2.1</version> 
     </dependency> 
    </dependencies> 
</project> 

plugin/src/main/java/com/stackoverflow/Q12082277/plugin/PropertiesMojo.java

package com.stackoverflow.Q12082277.plugin; 

import org.apache.maven.plugin.AbstractMojo; 
import org.apache.maven.plugin.MojoExecutionException; 
import org.apache.maven.plugin.MojoFailureException; 
import org.apache.maven.plugin.logging.Log; 
import org.apache.maven.project.MavenProject; 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.util.Properties; 

/** 
* @author maba, 2012-08-24 
* 
* @goal extract 
*/ 
public class PropertiesMojo extends AbstractMojo { 

    private Log log; 

    /** 
    * The current project representation. 
    * @parameter expression="${project}" 
    * @required 
    * @readonly 
    */ 
    private MavenProject project; 

    /** 
    * A properties file 
    * 
    * @parameter expression="${propertiesFile}" 
    * @required 
    */ 
    private File propertiesFile; 

    @Override 
    public void execute() throws MojoExecutionException, MojoFailureException { 
     log.info("Executing PropertiesMojo on " + propertiesFile.getAbsolutePath()); 

     try { 
      Properties fileProperties = new Properties(); 
      fileProperties.load(new FileInputStream(propertiesFile)); 
      Properties projectProperties = project.getProperties(); 
      for (Object key : fileProperties.keySet()) { 
       projectProperties.setProperty((String)key, (String) fileProperties.get(key)); 
      } 
      project.getProperties().list(System.out); 
     } catch (FileNotFoundException e) { 
      throw new MojoFailureException("The file " + propertiesFile.getAbsolutePath() + " was not found!", e); 
     } catch (IOException e) { 
      log.error(""); 
     } 

    } 

    @Override 
    public void setLog(Log log) { 
     this.log = log; 
    } 
} 

Bạn sẽ sử dụng plugin này từ sau app/pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <parent> 
     <groupId>com.stackoverflow</groupId> 
     <artifactId>Q12082277</artifactId> 
     <version>1.0-SNAPSHOT</version> 
    </parent> 

    <artifactId>Q12082277-app</artifactId> 

    <name>${project.artifactId}-${project.version}</name> 

    <build> 
     <plugins> 
      <plugin> 
       <groupId>com.stackoverflow</groupId> 
       <artifactId>Q12082277-plugin</artifactId> 
       <version>1.0-SNAPSHOT</version> 
       <executions> 
        <execution> 
         <phase>initialize</phase> 
         <goals> 
          <goal>extract</goal> 
         </goals> 
         <configuration> 
          <propertiesFile>${user.home}/my.properties</propertiesFile> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
      <plugin> 
       <groupId>org.codehaus.mojo</groupId> 
       <artifactId>exec-maven-plugin</artifactId> 
       <version>1.2.1</version> 
       <executions> 
        <execution> 
         <goals> 
          <goal>java</goal> 
         </goals> 
        </execution> 
       </executions> 
       <configuration> 
        <mainClass>com.stackoverflow.Q12082277.App</mainClass> 
       </configuration> 
      </plugin> 
     </plugins> 
     <resources> 
      <resource> 
       <directory>src/main/resources</directory> 
       <filtering>true</filtering> 
      </resource> 
     </resources> 
    </build> 
</project> 

Và sau đó bạn sẽ phải thêm app.properties sau sẽ hoạt động dưới dạng mẫu và lấy giá trị mà chúng tôi vừa đọc từ tệp và đặt chúng và tạo tệp bê tông app.properties sẽ có thể truy cập từ bên trong bình.

app/src/main/resources/app.properties

res.dir=${res.dir} 
resource.dir=${resource.dir} 
bin.dir=${bin.dir} 
cfg.dir=${cfg.dir} 

Và cuối cùng, đây là một ứng dụng thử nghiệm mà chỉ tải app.properties từ classpath và in kết quả.

app/src/main/java/com/stackoverflow/Q12082277/App.java

package com.stackoverflow.Q12082277; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Properties; 

/** 
* @author maba, 2012-08-23 
*/ 
public class App { 

    public static void main(String[] args) throws IOException { 
     ClassLoader loader = App.class.getClassLoader(); 
     InputStream in = loader.getResourceAsStream("app.properties"); 
     Properties properties = new Properties(); 
     properties.load(in); 
     properties.list(System.out); 
    } 
} 

Bây giờ bạn có thể đứng trong thư mục trên và thực hiện

mvn install 

Sau đó đi xuống vào thư mục app và thực hiện

mvn exec:java 

Và nó sẽ in

-- listing properties -- 
resource.dir=C://my/stuff/here 
cfg.dir=C://my/stuff/here/config 
bin.dir=C://my/stuff/here/bin 
res.dir=/my/stuff/here 

Đó là chính xác những gì bạn muốn.

+0

Điều này có vẻ là câu trả lời hay nhất - tôi không vui vì lỗ hổng này trong bộ công cụ của Maven chưa được giải quyết, nhưng tôi xin chào, tôi xin chào mừng bạn đến với nguồn mở. :-( – user1071914

3

Tôi nghĩ sẽ tốt hơn nếu bạn chuyển tệp thuộc tính thành tệp mẫu và lấy các thuộc tính từ pom.xml bằng cách sử dụng maven resource filtering.

Một thiết lập đơn giản có thể trông như thế này

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.stackoverflow</groupId> 
    <artifactId>Q12082277</artifactId> 
    <version>1.0-SNAPSHOT</version> 

    <name>${project.artifactId}-${project.version}</name> 

    <properties> 
     <res.dir>/default/stuff/here</res.dir> 
     <resource.dir>${res.dir}</resource.dir> 
     <bin.dir>${resource.dir}/bin</bin.dir> 
     <cfg.dir>${resource.dir}/config</cfg.dir> 
    </properties> 

    <dependencies> 
    <!-- Your dependencies --> 
    </dependencies> 

    <build> 
     <resources> 
      <resource> 
       <directory>src/main/resources</directory> 
       <filtering>true</filtering> 
      </resource> 
     </resources> 
    </build> 

</project> 

src/main/resources/app.properties

res.dir=${res.dir} 
resource.dir=${resource.dir} 
bin.dir=${bin.dir} 
cfg.dir=${cfg.dir} 

src/main/java/com/stackoverflow/Q12082277/App.java

package com.stackoverflow.Q12082277; 

import java.io.IOException; 
import java.io.InputStream; 
import java.util.Properties; 

/** 
* @author maba, 2012-08-23 
*/ 
public class App { 

    public static void main(String[] args) throws IOException { 
     ClassLoader loader = App.class.getClassLoader(); 
     InputStream in = loader.getResourceAsStream("app.properties"); 
     Properties properties = new Properties(); 
     properties.load(in); 
     properties.list(System.out); 
    } 
} 

System.out

-- listing properties -- 
resource.dir=/default/stuff/here 
cfg.dir=/default/stuff/here/config 
bin.dir=/default/stuff/here/bin 
res.dir=/default/stuff/here 

Các pom.xml sẽ có các thuộc tính mặc định được sử dụng bởi tất cả mọi người.

Nếu bạn muốn ghi đè các giá trị sau đó gọi maven với các thông số đầu vào:

mvn install -Dres.dir=/my/stuff/here -Dresource.dir="C:/${res.dir}" 

System.out

-- listing properties -- 
resource.dir=C://my/stuff/here 
cfg.dir=C://my/stuff/here/config 
bin.dir=C://my/stuff/here/bin 
res.dir=/my/stuff/here 

Bằng cách làm nó theo cách tất cả mọi người sẽ có quan điểm tương tự của các thuộc tính và bạn có thể ghi đè lên chúng nếu bạn muốn khi chạy trên máy tính của riêng bạn.

+0

Cảm ơn bạn đã đề xuất, không may cách nó hiện được đặt ra (với các thuộc tính trong một tệp riêng biệt) là một tiêu chuẩn của công ty và không được thảo luận, vì vậy tôi bị mắc kẹt khi sử dụng nó theo cách của nó. – user1071914

+0

@ user1071914 Hãy thử sử dụng plugin antaven maven. Nó có thể làm những gì bạn cần. – maba

+0

@ user1071914 Tôi đã thêm một câu trả lời khác thực hiện một mojo đơn giản thực hiện những gì bạn muốn. – maba

Các vấn đề liên quan