I want to extract all the properties from my pom.xml into a properties-file. These are the common properties like dependency-versions, plugin-versions and directories.
I'm using the properties-maven-plugin, but its not working as i want it to.
The essential part of my pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-1</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>${basedir}/pom.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
Now when i run "mvn properties:read-project-properties" i get the following error:
[INFO] One or more required plugin parameters are invalid/missing for 'properties:read-project-properties'
[0] Inside the definition for plugin 'properties-maven-plugin' specify the following:
<configuration>
...
<files>VALUE</files>
</configuration>.
The pom.properties-file is located in the same dir as the pom.xml.
What can i do to let the properties-maven-plugin read my properties-file?
EDIT
I filed an issue at http://jira.codehaus.org/browse/MOJO-1523.
It has been closed as "not a bug", the reason is:
It's by design. The project definition
has to be self-contained, otherwise it
is no longer complete if it is refered
from elsewhere as part of the
transitive deps.
Your configuration element is defined inside an execution and thus applies to this execution only.
So either call mvn initialize (or a phase posterior to initialize) to use the configuration of your current execution binding.
Or use a global configuration:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<configuration>
<files>
<file>etc/config/dev.properties</file>
</files>
</configuration>
...
</plugin>
And then call
mvn properties:read-project-properties
But that wouldn't make much sense in the particular case of this plugin (you want the properties to be available during the build) so this leaves you with the first solution.
Update: I did a test on my side and, indeed, with the following POM:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>Q2664362</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>etc/config/dev.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Running mvn test won't work: maven will try to download junit:jar:${junit.version} (i.e. it doesn't use the value of the property) and this will obviously fail.
$ mvn test
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building SO - Q2664362 - maven-properties-plugin demo
[INFO] task-segment: [test]
[INFO] ------------------------------------------------------------------------
[INFO] [properties:read-project-properties {execution: default}]
[INFO] [resources:resources {execution: default-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/pascal/Projects/stackoverflow/Q2664362/src/main/resources
Downloading: http://repo1.maven.org/maven2/junit/junit/${junit.version}/junit-${junit.version}.pom
[INFO] Unable to find resource 'junit:junit:pom:${junit.version}' in repository central (http://repo1.maven.org/maven2)
[INFO] [compiler:compile {execution: default-compile}]
[INFO] Nothing to compile - all classes are up to date
[INFO] [resources:testResources {execution: default-testResources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/pascal/Projects/stackoverflow/Q2664362/src/test/resources
Downloading: http://repo1.maven.org/maven2/junit/junit/${junit.version}/junit-${junit.version}.jar
[INFO] Unable to find resource 'junit:junit:jar:${junit.version}' in repository central (http://repo1.maven.org/maven2)
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Failed to resolve artifact.
...
The odd part is that the download of the dependency occurs after properties:read-project-properties. I'm not sure but this sounds like a bug, you should open an issue.
Try using validate phase instead of initialize for maven 3.x (link).
EDIT2
See here for a workaround using Ant Tasks, which makes this use case possible
I encounter your question, but i tried to add this resources here, it works well.
<build>
<resources>
<resource>
<directory>src/config</directory> //your config folder
<filtering>true</filtering>
</resource>
</resources>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>src/config/config.properties</file> //your config file
</files>
</configuration>
</execution>
</executions>
</plugin>
</build>
Hope you resolve this as above
Related
I am working on a maven based project. Project has multiple modules.
Here is the project structure
-- Project
--Module1
-- pom.xml
--Module2
-- pom.xml
--Module3-war
-- pom.xml
--parent module
--pom.xml
Parent module packaging type is "pom" and all the modules are defined in this.
I added the failsafe-pligin in parent module pom as shown below
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Now when I am running the "mvn verify" command, failsafe plugin is not getting executed.
My Integration test name "TestServiceIT.java" is in module1 in the structure.
When I added the same "failsafe" plugin in my war module then I see that failsafe plugin get executed after creating the WAR but it could not find the test class. See below
[INFO] Started Jetty Server
[INFO]
[INFO] --- maven-failsafe-plugin:2.15:integration-test (integration-test) # service-integration-test
---
[INFO] No tests to run.
[WARNING] File encoding has not been set, using platform encoding Cp1252, i.e. build is platform d
endent!
[INFO]
[INFO] --- jetty-maven-plugin:8.1.11.v20130520:stop (stop-jetty) # service-integration-test ---
[INFO]
[INFO] --- maven-failsafe-plugin:2.15:verify (verify) # service-integration-test ---
[INFO] No tests to run.
So, my questions are
When failsafe plugin is defined in main pom.xml then why it's not getting executed?
Why it's not able to find testcases defined in another module?
What is the best practice for writing the integration test in multi module maven project?
I think you have to add dependenciesToScan in failsafe plugin configuration.
ie:
<dependencies>
<dependency>
<groupId>org.arquillian.tck.container</groupId>
<artifactId>arquillian-tck-container</artifactId>
<version>1.0.0.Final-SNAPSHOT</version>
<classifier>tests</classifier>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.14-SNAPSHOT</version>
<configuration>
<dependenciesToScan>
<dependency>org.arquillian.tck.container:arquillian-tck-container</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
But I cannot test it because of this bug https://issues.apache.org/jira/browse/SUREFIRE-1024
I want to create a build info file into the specific location of the project's target folder (especially in target/abc_project/META-INF folder) through maven-2.
Following is what I am doing in the pom.xml
<build>
<finalName>abc_project</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<id>buid-info-generator</id>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>java</executable>
<arguments>
<argument>-jar</argument>
<argument>xyz.jar</argument>
<argument>target/abc_project/META-INF/info.txt</argument>
<argument>date</argument>
<argument>hg summary</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugins>
</build>
while giving the phase other than install, deploy, I get the following error -
[INFO] Exception in thread "main" java.io.FileNotFoundException: target\abc_project\META-INF\info.txt (The system cannot find the path specified)
[INFO] at java.io.FileOutputStream.open(Native Method)
[INFO] at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
[INFO] at java.io.FileOutputStream.<init>(FileOutputStream.java:131)
[INFO] at java.io.FileWriter.<init>(FileWriter.java:73)
[INFO] at com.nbec.svn.build.info.BuildInfoGenerator.main(BuildInfoGenerator.java:30)
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] Result of cmd.exe /X /C "java -jar xyz.jar target/abc_project/META-INF/info.txt "date "hg summary"" execution is: '1'.
But strangely, the same code is working for 1 project and not for other 2 projects. Is there any alternative to obtain the same.
Actually the error report indicates that the directory target\abc_project\META-INF probably does not exist. Without more information I can only speculate. Maybe the plugin which create the abc_project\META-INF directory is called after the exec-maven-plugin.
in my pom I've added the exec-maven-plugin to call a java class which will generate a file. This class requires some parameters to be passed to the main method, one of those is the location of an input file (outside the project). Until now I've been using a relative path for this which works fine:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.laco.projectmaster.util.LanguageGenerator</mainClass>
<arguments>
<argument>../PM-Config/dev/PMLanguage.xls</argument>
<argument>PM4.0</argument>
<argument>${project.build.outputDirectory}/com/laco/projectmaster/props/resources</argument>
<argument>ProjectMaster</argument>
<argument>Created during maven build (POM Version: ${pom.version})</argument>
</arguments>
</configuration>
</plugin>
Now I'm starting to use hudson to install/package and deploy the wars and I cannot longer use this relative path. Simple I thought, I just pass the location of the input file when invoking maven like:
mvn clean package -Dlangdir=C:/somedir
and then alter the pom like:
<argument>${langdir}/PMLanguage.xls</argument>
However, this parameter simply gets ignored here. The path the main class receives as argument becomes null/PMLanguage.xls . The parameter itself is available in maven, I tested with succes using an echo in the antrun plugin. The correct path was echoed.
Are the paremeters you pass to maven then not available by default no matter where you reference them in the pom?
thanks for any help,
Stijn
I can't reproduce the issue. I used the following test class:
package com.stackoverflow.q3421918;
public class Hello
{
public static void main( String[] args )
{
System.out.println( args[0] + " " + args[1] );
}
}
And the following pom.xml:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow.q3421918</groupId>
<artifactId>Q3421918</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- this was a test for a workaround -->
<properties>
<myprop>${langdir}</myprop>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.stackoverflow.q3421918.Hello</mainClass>
<arguments>
<argument>${myprop}</argument>
<argument>${langdir}</argument>
</arguments>
</configuration>
</plugin>
</plugins>
</build>
</project>
And here is the output I get:
$ mvn clean package -Dlangdir=C:/somedir
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Q3421918
[INFO] task-segment: [clean, package]
[INFO] ------------------------------------------------------------------------
...
[INFO] Preparing exec:java
[WARNING] Removing: java from forked lifecycle, to prevent recursive invocation.
[INFO] No goals needed for project - skipping
[INFO] [exec:java {execution: default}]
Hello c:/somedir c:/somedir
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
...
Tested with Maven 2.2.1.
I'm using a maven plugin for install4j in my project, located here. That plugin lets you pass variables to install4j using the <compilerVariables> section. Here's the relevant section of my pom:
<plugin>
<groupId>com.google.code.maven-install4j</groupId>
<artifactId>maven-install4j-plugin</artifactId>
<version>0.1.1</version>
<configuration>
<executable>${devenv.install4jc}</executable>
<configFile>${basedir}/newinstaller/ehd.install4j</configFile>
<releaseId>${project.version}</releaseId>
<attach>false</attach>
<skipOnMissingExecutable>false</skipOnMissingExecutable>
<compilerVariables>
<property>
<name>m2_home</name>
<value>${settings.localRepository}</value>
</property>
</compilerVariables>
</configuration>
</plugin>
The problem is that ${settings.localRepository} is not being substituted with the actual directory when I run the plugin. Here's the command line script that install4j is generating:
[INFO] Running the following command for install4j compile: /bin/sh -c /home/zach/install4j/bin/install4jc --release=9.1-SNAPSHOT --destination="/home/zach/projects/java/ehdtrunk/target/install4j" -D m2_home=${settings.localRepository} /home/zach/projects/java/ehdtrunk/newinstaller/ehd.install4j
Is this the fault of the plugin? If so, what needs to change to allow the substitution to happen?
The following POM just works for me (with Maven 2.2.1):
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>Q2828732</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
...
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>validate</phase>
<configuration>
<tasks>
<echo>${settings.localRepository}</echo>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
And running mvn process-ressources produces the following output:
$ mvn validate
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building Q2828732
[INFO] task-segment: [validate]
[INFO] ------------------------------------------------------------------------
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
[echo] /home/pascal/.m2/repository
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Thu May 13 19:28:38 CEST 2010
[INFO] Final Memory: 3M/54M
[INFO] ------------------------------------------------------------------------
Does the above work for you? Are you using M2Eclipse? Could it be related to MNGECLIPSE-299?
The plugin in question accepts a parameter which is a Properties instance. For whatever reason, expressions used to configure Properties instances are not automatically evaluated. I had to change the plugin to use a org.apache.maven.plugin.PluginParameterExpressionEvaluator to evaluate ${settings.localRepository}.
I have a maven dependency in my pom.xml as such:
<dependency>
<groupId>com.foo</groupId>
<artifactId>Bar</artifactId>
<version>1.2.3</version>
</dependency>
And I would like to use the system path to the binary as a property (so I can pass it to an external process that is kicked off by maven). I can do this in an awkward way:
<properties>
<my.lib>${settings.localRepository}/com/foo/Bar/1.2.3/Bar.jar</my.lib>
</properties>
But I would really like to use a more standard mechanism, such as:
<properties>
<my.lib>${com.foo:Bar:1.2.3}</my.lib>
</properties>
I something like that possible?
Here is a correct implementation, using the maven-dependency-plugin properties goal, which can be used anywhere in a pom:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>q2359872</artifactId>
<version>2.0-SNAPSHOT</version>
<name>q2359872</name>
<properties>
<!-- Must be listed in the dependencies section otherwise it will be null. -->
<my.lib>${org.jmockit:jmockit:jar}</my.lib>
</properties>
<dependencies>
<dependency>
<groupId>org.jmockit</groupId>
<artifactId>jmockit</artifactId>
<version>1.11</version>
</dependency>
</dependencies>
<build>
<defaultGoal>generate-sources</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<goals>
<goal>properties</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Example usage: -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
<phase>generate-sources</phase>
</execution>
</executions>
<configuration>
<executable>echo</executable>
<arguments>
<argument>path to jar=</argument>
<argument>${org.jmockit:jmockit:jar}</argument>
<argument>my.lib=</argument>
<argument>${my.lib}</argument>
</arguments>
</configuration>
</plugin>
<!-- end of Example usage -->
</plugins>
</build>
</project>
And the output is...
jpyeron#black /projects/wkspc/tmp/foo
$ /cygdrive/c/programs.x86_64/apache-software-foundation/apache-maven-3.1.1/bin/mvn
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building q2359872 2.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.3:properties (default) # q2359872 ---
[INFO]
[INFO] --- exec-maven-plugin:1.2:exec (default) # q2359872 ---
path to jar= C:\Documents and Settings\jpyeron\.m2\repository\org\jmockit\jmockit\1.11\jmockit-1.11.jar my.lib= C:\Documents and Settings\jpyeron\.m2\repository\org\jmockit\jmockit\1.11\jmockit-1.11.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.032s
[INFO] Finished at: Wed Sep 17 12:07:18 EDT 2014
[INFO] Final Memory: 10M/153M
[INFO] ------------------------------------------------------------------------
Assuming that the com.foo:Bar:jar:1.2.3 artifact is declared as dependency in your POM, the following property returns the path to the jar in the local repository:
${maven.dependency.com.foo.Bar.jar.path}
Update: Here is a simple POM demonstrating this:
<?xml version="1.0" encoding="UTF-8"?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.stackoverflow</groupId>
<artifactId>q2359872</artifactId>
<version>1.0-SNAPSHOT</version>
<name>q2359872</name>
<properties>
<my.lib>${maven.dependency.junit.junit.jar.path}</my.lib>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tasks>
<echo>${my.lib}</echo>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Running mvn process-resources produces the following output:
$ mvn process-resources
[INFO] Scanning for projects...
[INFO] ------------------------------------------------------------------------
[INFO] Building q2359872
[INFO] task-segment: [process-resources]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources {execution: default-resources}]
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory /home/pascal/Projects/stackoverflow/q2359872/src/main/resources
[INFO] [antrun:run {execution: default}]
[INFO] Executing tasks
[echo] /home/pascal/.m2/repository/junit/junit/3.8.1/junit-3.8.1.jar
[INFO] Executed tasks
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7 seconds
[INFO] Finished at: Tue Mar 02 14:41:32 CET 2010
[INFO] Final Memory: 7M/68M
[INFO] ------------------------------------------------------------------------
There is a plugin which might be what you are looking for... bitstrings.org (home).
If none of the upper work, you can always use gmaven to agressively dive into MavenProject object and get your artifact infos. In my case, I had the following artifact declared in a profile :
<!-- Neo4J connector. This dependency is scoped to be usable by maven-exec-plugin
which installs it in Glassfish -->
<dependency>
<groupId>com.netoprise</groupId>
<artifactId>neo4j-connector</artifactId>
<version>${neo4j.connector.version}</version>
<type>rar</type>
<!-- Set in test scope to avoid release issues -->
<scope>test</scope>
</dependency>
To get its path and put it in a maven property, I wrote the following gmaven script :
<!-- Small script used to build maven property for neo4j-connector path -->
<plugin>
<groupId>org.codehaus.gmaven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>get-neo4j-connector-rar-path</id>
<phase>validate</phase>
<goals>
<goal>execute</goal>
</goals>
<configuration>
<source>
<![CDATA[
println "initial value of neo4j.connector.rarPath is \""+project.properties['neo4j.connector.rarPath']+"\""
// Duplicate model in a Mavenproject, allowing me to get associated artifact
// So sad I can't get the embdder object
// More info here : http://maven.apache.org/ref/3.0.3/maven-core/apidocs/org/apache/maven/project/MavenProject.html
def mavenProject = new org.apache.maven.project.MavenProject(project)
// More infos on Artifact there : http://maven.apache.org/ref/3.0.3/maven-artifact/apidocs/org/apache/maven/artifact/Artifact.html
def neo4jConnector = mavenProject.getArtifacts().find { artifact -> artifact.getArtifactId()=='neo4j-connector' }
// Now resolve dependency to produce an artifact
// notice maven property interpolation doesn't do toString, so we have to do it ourselves
project.properties['neo4j.connector.rarPath'] = neo4jConnector.getFile().getAbsolutePath()
println "usable neoj4Connector can be found at "+project.properties['neo4j.connector.rarPath']
]]>
</source>
</configuration>
</execution>
</executions>
</plugin>
It's some kind of brute-force method, but it DO work far better than the previous solutions I've seen there.
You need to write a new maven plugin that sets a property value to the fully-resolved pathname of a dependency. The maven-dependency-plugin won't do that for you.
It will copy your dependency somewhere and then you can refer to it by that pathname.