如何在maven pom中定义属性。xml并从命令行传递参数?

时间:2020-12-20 00:00:14

I need to pass two arguments, say shell and version from command line.

我需要从命令行传递两个参数,比如shell和version。

The issue is I am not able to understand how to define these two variables in pom.xml, and then fetch the parameters in my Java code at runtime.

问题是我不能理解如何在pom中定义这两个变量。然后在运行时从我的Java代码中获取参数。

Also when I run it as a Maven project , how do I set the parameter values?

另外,当我作为Maven项目运行时,如何设置参数值?

Any suggestions would be of great help. Thanks!!

任何建议都将大有帮助。谢谢! !

1 个解决方案

#1


4  

Option 1 - "storing" build arguments into compiled project to be retrieved when project is run

if you want to provide shell and version as arguments to the maven build at compile time (when you build your code into, say a *.jar file) and then, at some later point when your compiled code is run you want to retrieve those parameters back.

如果您希望在编译时为maven构建提供shell和version作为参数(当您将代码构建到*中时)。然后,在稍后运行编译后的代码时,您希望检索这些参数。

this is achievable by using the maven resources plugin's filtering capability:

这可以通过使用maven资源插件的过滤功能实现:

suppose your project structure was

假设您的项目结构是

pom.xml
src/
   main/
      java/
         Main.java
      resources/
         strings.properties

you could put property placeholders into strings.properties:

您可以将属性占位符放入字符串。

shell=${my.shell}
version=${my.version}

and then in the pom.xml configure the maven resources plugin (that copies src/main/resources/* into the target directory where the jar plugin will later pick it up from) to do a find-and-replace on the file (called filtering):

然后在pom中。xml配置maven资源插件(将src/main/resources/*复制到目标目录中,稍后jar插件将从该目录获取它),对文件进行查找和替换(称为过滤):

<project>
  ...
  <name>bob</name>
  ...
  <build>
    ...
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
      ...
    </resources>
    ...
  </build>
  ...
</project>

you could supply these parameters as system properties to maven (using -D[name]=[value] on the command line), like so:

您可以将这些参数作为系统属性提供给maven(在命令行上使用-D[name]=[value]),如下所示:

mvn clean install -Dmy.shell=X -Dmy.version=Y

then, if you were to look at the processed resource file (should be in /target) you would see the resources plugin has filtered the file into:

然后,如果您要查看已处理的资源文件(应该在/target中),您会看到资源插件已将该文件过滤为:

shell=X
version=Y

reading this back at runtime would be something like:

在运行时读回来的内容应该是这样的:

public class Main {
   public static void main (String[] args) {
      InputStream is = Main.class.getClassLoader().getResourceAsStream("strings.properties");
      Properties props = new Properties();
      props.load(is);
      System.out.println("shell is " + props.get("shell"));
   }
}

this is assumming your code is run "from inside" the jar file produced. various packaging/deployment form factors might requires slightly different ways of getting the input stream to read from.

假设您的代码是在生成的jar文件“内部”运行的。不同的打包/部署表单因素可能需要稍微不同的方法来获取要读取的输入流。

Option 2 - accessing arguments provided to the maven build from code that runs as part of the build (say unit tests)

in this scenario youre not concerned with storing these params embedded into your compiled project anywhere, you just want to access them at build time (say from your unit test code).

在这个场景中,您不需要将这些参数嵌入到编译后的项目中,您只需要在构建时访问它们(比如从您的单元测试代码)。

any argument provided to java in the form (note no spaces allowed):

在表格中提供给java的任何参数(注意不允许空格):

java <whatever> -Dprop.name=value

is available at runtime like this:

在运行时可用如下:

String propValue = System.getProperty("prop.name");

a slight complication here, specific to maven and unit tests, is that the maven surefire plugin (which is the plugin that runs unit tests) and also the maven failsafe plugin (which is the closely-related plugin that runs system tests) fork off a new JVM to run your unit tests in. however, according to their documentation:

这里有一个小问题,专门针对maven和单元测试,即maven surefire插件(即运行单元测试的插件)和maven failsafe插件(即运行系统测试的紧密相关插件)分离出一个新的JVM来运行单元测试。但是,根据他们的文件:

System property variables from the main maven process are passed to the forked process as well

主maven进程中的系统属性变量也被传递给分叉进程

so the above solution should work. if it doesnt you can either configure the plugin not to fork off the unit tests:

所以上面的解应该是成立的。如果它没有,你可以配置插件不要分开单元测试:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <forkCount>0</forkCount>
    </configuration>
</plugin>

or alternatively pass thise parameters to the forked process yourself:

或将参数传递给分叉过程:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <systemPropertyVariables>
            <my.schema>${my.schema}</my.schema>
        </systemPropertyVariables>
    </configuration>
</plugin>

and then they should be accessible in test code via System.getProperty()

然后通过System.getProperty()在测试代码中访问它们

#1


4  

Option 1 - "storing" build arguments into compiled project to be retrieved when project is run

if you want to provide shell and version as arguments to the maven build at compile time (when you build your code into, say a *.jar file) and then, at some later point when your compiled code is run you want to retrieve those parameters back.

如果您希望在编译时为maven构建提供shell和version作为参数(当您将代码构建到*中时)。然后,在稍后运行编译后的代码时,您希望检索这些参数。

this is achievable by using the maven resources plugin's filtering capability:

这可以通过使用maven资源插件的过滤功能实现:

suppose your project structure was

假设您的项目结构是

pom.xml
src/
   main/
      java/
         Main.java
      resources/
         strings.properties

you could put property placeholders into strings.properties:

您可以将属性占位符放入字符串。

shell=${my.shell}
version=${my.version}

and then in the pom.xml configure the maven resources plugin (that copies src/main/resources/* into the target directory where the jar plugin will later pick it up from) to do a find-and-replace on the file (called filtering):

然后在pom中。xml配置maven资源插件(将src/main/resources/*复制到目标目录中,稍后jar插件将从该目录获取它),对文件进行查找和替换(称为过滤):

<project>
  ...
  <name>bob</name>
  ...
  <build>
    ...
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
      ...
    </resources>
    ...
  </build>
  ...
</project>

you could supply these parameters as system properties to maven (using -D[name]=[value] on the command line), like so:

您可以将这些参数作为系统属性提供给maven(在命令行上使用-D[name]=[value]),如下所示:

mvn clean install -Dmy.shell=X -Dmy.version=Y

then, if you were to look at the processed resource file (should be in /target) you would see the resources plugin has filtered the file into:

然后,如果您要查看已处理的资源文件(应该在/target中),您会看到资源插件已将该文件过滤为:

shell=X
version=Y

reading this back at runtime would be something like:

在运行时读回来的内容应该是这样的:

public class Main {
   public static void main (String[] args) {
      InputStream is = Main.class.getClassLoader().getResourceAsStream("strings.properties");
      Properties props = new Properties();
      props.load(is);
      System.out.println("shell is " + props.get("shell"));
   }
}

this is assumming your code is run "from inside" the jar file produced. various packaging/deployment form factors might requires slightly different ways of getting the input stream to read from.

假设您的代码是在生成的jar文件“内部”运行的。不同的打包/部署表单因素可能需要稍微不同的方法来获取要读取的输入流。

Option 2 - accessing arguments provided to the maven build from code that runs as part of the build (say unit tests)

in this scenario youre not concerned with storing these params embedded into your compiled project anywhere, you just want to access them at build time (say from your unit test code).

在这个场景中,您不需要将这些参数嵌入到编译后的项目中,您只需要在构建时访问它们(比如从您的单元测试代码)。

any argument provided to java in the form (note no spaces allowed):

在表格中提供给java的任何参数(注意不允许空格):

java <whatever> -Dprop.name=value

is available at runtime like this:

在运行时可用如下:

String propValue = System.getProperty("prop.name");

a slight complication here, specific to maven and unit tests, is that the maven surefire plugin (which is the plugin that runs unit tests) and also the maven failsafe plugin (which is the closely-related plugin that runs system tests) fork off a new JVM to run your unit tests in. however, according to their documentation:

这里有一个小问题,专门针对maven和单元测试,即maven surefire插件(即运行单元测试的插件)和maven failsafe插件(即运行系统测试的紧密相关插件)分离出一个新的JVM来运行单元测试。但是,根据他们的文件:

System property variables from the main maven process are passed to the forked process as well

主maven进程中的系统属性变量也被传递给分叉进程

so the above solution should work. if it doesnt you can either configure the plugin not to fork off the unit tests:

所以上面的解应该是成立的。如果它没有,你可以配置插件不要分开单元测试:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <forkCount>0</forkCount>
    </configuration>
</plugin>

or alternatively pass thise parameters to the forked process yourself:

或将参数传递给分叉过程:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <systemPropertyVariables>
            <my.schema>${my.schema}</my.schema>
        </systemPropertyVariables>
    </configuration>
</plugin>

and then they should be accessible in test code via System.getProperty()

然后通过System.getProperty()在测试代码中访问它们