I want to deploy sources and javadocs with my snapshots. This means that I want to automize the following command:
mvn clean source:jar javadoc:jar deploy
Just to execute:
mvn clean deploy
I don't want to have javadoc/sources generation executed during the install phase (i.e. local builds).
I know that source/javadoc plugins can be synchronized with the execution of the release plugin but I can't figure out how to wire it to the snapshots releases.
<build>
<plugins>
<plugin>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<phase>deploy</phase>
<goals><goal>jar-no-fork</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>deploy</phase>
<goals><goal>jar</goal></goals>
</execution>
</executions>
</plugin>
<plugin>
<!-- explicitly define maven-deploy-plugin after other to force exec order -->
<artifactId>maven-deploy-plugin</artifactId>
<executions>
<execution>
<id>deploy</id>
<phase>deploy</phase>
<goals><goal>deploy</goal></goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
See Sonatype's OSS parent POM for a complete example.
The article referred to by Dan also mentions another approach that works without modifying poms AND won't go away anytime soon:
mvn clean javadoc:jar source:jar install
Which works fine with Maven 3+, along with...
mvn clean javadoc:jar source:jar deploy
Which I have tested from Jenkins deploying to Nexus.
This approach was nice because I only had to modify some Jenkins jobs and didn't need to mess with my poms.
Just to add an alternative that doesn't require you to muck with plugin configuration:
mvn -DperformRelease=true [goals]
Credit goes to mcbeelen from http://sea36.blogspot.com/2009/02/attaching-javadocs-and-sources-to-maven.html?showComment=1314177874102#c6853460758692768998
Related
I have an internal nexus that contains all the artifacts that we build.
Once an artifact is tested, I want to take the sane artifact and deploy it to Maven Central without rebuilding it.
I know that I might be able to do that using mvn deploy:deploy-file but it seems complicated.
Is there an easy way to do it?
Note: due to historical reasons,we don't use SNAPSHOT versions. All versions are in the style of artifact-name-X.Y.Z.jar were X.Y.Z is the version number. We have an internal tool that can be queried for sanity.
I've ended using an approach similar to what they have in here:
https://central.sonatype.org/pages/manual-staging-bundle-creation-and-deployment.html
So, if I had the following files:
ossrh-test-1.2.pom
ossrh-test-1.2.jar
ossrh-test-1.2-javadoc.jar
ossrh-test-1.2-sources.jar
I've invoked this command for the JAR:
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=ossrh -DpomFile=ossrh-test-1.2.pom -Dfile=ossrh-test-1.2.jar
And the following commands for the sources and JavaDocs:
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=ossrh -DpomFile=ossrh-test-1.2.pom -Dfile=ossrh-test-1.2-sources.jar -Dclassifier=sources
mvn gpg:sign-and-deploy-file -Durl=https://oss.sonatype.org/service/local/staging/deploy/maven2/ -DrepositoryId=ossrh -DpomFile=ossrh-test-1.2.pom -Dfile=ossrh-test-1.2-javadoc.jar -Dclassifier=javadoc
Last but not least, since I had to create fake sources and javadoc jars I've just taken a jar, unzipped it, put a readme file inside of it instead of the old content, updated the manifest and zipped it again. Then I've uploaded it as my fake sources/javadoc jars.
Let me assume you have not only x.y.z version of binaries, but also scm tag for this version.
If so, you can give a try to the following CI job:
<scm> checkout <YOUR TAG>
<scm> clean -d -x -f
mvn maven-dependency-plugin:get -Pcustom-deployment -DexecutionId=resolve-sane-binaries
mvn maven-deploy-plugin:deploy -Pcustom-deployment -DexecutionId=deploy-sane-binaries
with profile in your pom.xml:
<profiles>
<profile>
<id>custom-deployment</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>resolve-sane-binaries</id>
<goals>
<goal>get</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
<outputDirectory>${project.build.directory}</outputDirectory>
<destFileName>${project.build.finalName}</destFileName>
</artifactItem>
...
</artifactItems>
...
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<executions>
<execution>
<id>deploy-sane-binaries</id>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
...
</configuration>
</execution>
<executions>
<plugin>
</plugins>
It's just an idea, not a code I've really tested. But hope it'll help.
An existing maven pom project <packaging>pom</packaging> which currently collects and packages resources needs to be extended to validate some of the resources.
In the same project I created a java-source directory src/main/java and in there I created a small java class to validate some of the resources. In addition I configured the maven-compiler and exec-maven plugin in the pom.
The java class runs fine in the IDE but it fails when I do mvn clean install it fails because it cant find the compiled class file. This is because the compile/test-compile phase is not available for pom-packaged projects.
My questions are:
Can I modify the compiler plugin to execute (compile) in a different phase than the default compile-phase. (I tried with adding an execution tag but no success)
Why is the exec-maven plugin executed because this was defined in test phase, which according to the docs is not part of the pom-package.
Are there other possibilities to run this validation task in the pom?
Modifying the packaging from pom to jar is a political sub-optimal solution.
Yes, you can configure maven-compiler-plugin to run the compilation in the package phase of the pom packaging.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<mainClass>com.example.validate.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Our maven pom.xml specifies to add an additional source and test-source folder if a certain profile (here "java8") is activated. The corresponding part of the pom looks like the following
<profile>
<id>java8</id>
....
<build>
<plugins>
....
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals><goal>add-test-source</goal></goals>
<configuration>
<sources>
<source>src/test/java8</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
According to http://mojo.codehaus.org/build-helper-maven-plugin/usage.html this appears to be the correct specification.
Running mvm install -P java8 I see that the additional tests are performed as expected.
However, running mvm eclipse:eclipse -P java8 the additional test source folder does not appear in eclipse .classpath.
Question: How do I have to configure maven to add the test source folder to the eclipse configuration? Is the above behavior a bug or a misconfiguration?
Having spent some time experimenting with this, I can give a partial answer to my own question (hopefully saving some time of other developers):
If one uses
<phase>generate-sources</phase>
<goals><goal>add-test-source</goal></goals>
instead of
<phase>generate-test-sources</phase>
<goals><goal>add-test-source</goal></goals>
then the test source folder is added to the eclipse .classpath (and it is added as a test folder). I.e. I am executing "add-test-source" in a different phase now.
In other words the profile looks like this:
<profile>
<id>java8</id>
....
<build>
<plugins>
....
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-sources</phase>
<goals><goal>add-test-source</goal></goals>
<configuration>
<sources>
<source>src/test/java8</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
This looks like a "workaround". It still contradicts the specification on http://mojo.codehaus.org/build-helper-maven-plugin/usage.html
rather than using eclipse:eclipse, you can use the http://www.eclipse.org/m2e/ plugin to open maven pom.xml projects.
Once you install that plugin in maven you will be able to take advantage of the m2e maven plugin, which can map any maven phase into the eclipse build life cycle.
in our example you will need to add something like this to your pom.xml:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<versionRange>[1.0,)</versionRange>
<goals>
<goal>add-test-source</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Important
this will only work if you install the m2e plugin and use it to open maven projects.
The way I see it, the plugin is working as expected.
When you run mvn install -P java8, you are invoking the phase install. In effect, maven executes all the phase prior to install, including generate-test-sources phase and test phase... before it really executes install. Because your plugin's goal is bound to generate-test-sources phase, that's why in this case you see your tests added in the class-path and run.
When you run mvn eclipse:eclipse -P java8, however, you are invoking a plugin's goal (in particular, eclipse goal of eclipse plugin), not a build life-cycle (phase). According to the eclipse plugin's documentation, only the generate-resources phase will be invoked. Be noted that generate-resources doesn't not "include" generate-test-sources (see more here), so in this case, your build-helper plugin does not get called.
If I guess correctly, you're trying to run your test in Eclipse with the profile java8 enabled. In that case, one way to do it (without having to work around) is right click on your project, click Maven, in the Active Maven Profile input box type in java8 ->OK. Now right click in your project and choose Run As -> JUnit Test (or whatever test framework you're using). Make sure you use the latest Eclipse version (Kepler 4.3.1 as of now) as it has a built-in m2e plugin which has improved a lot from the original m2e.
I'm experiencing the same issue as you Christian Fries and I came to the same conclusion as you about binding the add-test-source goal to the generate-sources phase instead of the generate-test-sources phase.
The problem is that when we run mvn eclipse:eclipse, we are actually directly calling a plugin so only that plugin will run. The reason the generate-sources phase is executed is explained in the plugin's doco (http://maven.apache.org/plugins/maven-eclipse-plugin/eclipse-mojo.html):
Invokes the execution of the lifecycle phase generate-resources prior to executing itself.
What we want is to be able to tell the plugin to execute the generate-test-sources phase before itself and then run. Note that maven will run all the phases up to and including the one you specify (http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) so we don't need to say run generate-sources AND generate-test-sources because simply specifying the latter is enough. Anyway, we can test this situation by running (the order matters):
mvn generate-test-sources eclipse:eclipse
...and for me, this did exactly as we expected. You can see from the output that the build-helper-maven-plugin is run to add the test sources and THEN the maven-eclipse-plugin runs and picks it up.
Now we have a new problem because AFAIK you can only bind a plugin to a phase (so it runs when the phase is run) and not the other way around.
The (sort of) solution is to bind the build-helper-maven-plugin and the maven-eclipse-plugin (in that order, so define the plugins in your POM in that order) to the generate-test-sources phase and then instead of running mvn eclipse:eclipse, run:
mvn generate-test-sources
So we have a POM that looks like:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<directory>src/test/java8</directory>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<phase>generate-test-sources</phase>
<goals>
<goal>eclipse</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
I know it's not perfect because people will still run mvn eclipse:eclipse and cry when it doesn't work. Also, the maven-eclipse-plugin will run as part of anything that runs the generate-test-sources phase (i.e. mvn clean install) which isn't so bad if it doesn't steamroll custom settings people have but if it is a problem you could move this stuff into a profile, bind it to a different phase that doesn't run as part of a build (like clean) or create a new lifecycle phase.
Java - jaxb - maven plugin
I have maven based web application, in pom i have following plugin which should generate jaxb .xsd to java classes.
When i execute clean, compile, package xsd classes do not gets generate. When i execute mvn jaxb2:generate manually it does generate xsd classes in generate-source folder but does not pack in war.
How can i make it generate xsd classes without manually executing "mvn jaxb2:generate" and make it part of the war ? thanks i Advance.
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaDirectory>src/main/wsdl</schemaDirectory>
</configuration>
</plugin>
It will not generate the XSD classes when you run mvn clean compile package, as generate-sources is not part of the packaging goal.
The default bindings for WAR packaging would be
process-resources
compile
process-test-resources
test-compile
test
package
install
deploy
You can wrap it around a profile, and run the mvn build with that profile
The other reason being to use profile is you can use this profile only whenever you need to generate the java classes, othertimes you can just run the regular build.
The format is
<profiles>
<profile>
<id>generateFromSchemas</id>
<plugin>
......
</plugin>
</profile>
<profiles>
mvn -P generateFromSchemas
I slightly updated my plugin as following
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.8.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<generatePackage>com.equilibriums.samplespringws</generatePackage>
<schemaDirectory>src/main/wsdl</schemaDirectory>
</configuration>
</plugin>
and following is the maven command
mvn jaxb2:generate compile package
and it worked awesome.
I have a project with 2 profiles, because UAT and PROD use different versions of the same jar.
I have noticed that if i don't explicitly call mvn clean ... the deployed EAR will have BOTH UAT and PROD jars.
Is there a way in the POM to specify that Maven should always clean before any building?
Use the maven-clean-plugin with the initialize phase as given here
http://maven.apache.org/plugins/maven-clean-plugin/usage.html
<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>initialize</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
Sure. Visit the Maven clean plugin usage page, they provide an example how to run the plugin automatically during build.
Please read up on the maven lifecycle
especially the package lifecycle.
The maven clean plugin you use will probably allow you to define a clean goal at a particular pahse.
You can also execute for example mvn clean install -P profile