Maven-release-plugin and builder-helper plugin - maven

I guess i am missing something.. I want to make a release of my project. I added maven-release-plugin to my pom. In addition, i have another source code dir aside from java(call it gen-src). When i make the first steps in the maven release (i.e prepare) everything is ok, but when i make perform it does not take the gen-src in account.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>src/main/gen_src</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
I suspect that it may be connected to the fact that the phase is generated-sources. Do i need to attach the add-source goal to another phase? If yes, how?
I also read in here - this is similar problem though i am not using flex..no answer.
Any idea?Thanks.

I had the same problem in the past and I think I know what's happening. The release:perform phase checkouts a copy of the tag to be released to 'target/checkout' folder and fork a maven process to build this checkout. As you have a problem only in the release:perform phase, it must be related to the fact that maven in running a fork process on the 'target/checkout' folder, not in the './' folder.
I ended up fixing this problem removing build helper, but I don't know if you could do the same, so if I were you I would try avoiding relative paths on configurations. You can configure the build-helper like that:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/main/gen_src</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Defining explicitly the ${basedir} could avoid this problem because ${basedir} will resolve to the fork path (your_workspace/project/target/checkout) instead of the current path (your_workspace/project). If this doesn't fix the problem, I believe we should file a bug against build-helper-maven-plugin because there should be no errors only in the perform phase.

The generated source classes won't make it into the binary jar — there you'll find only .class files resulting from compilation of both regular and generated sources. Maven release plug-in will, though, include the extra source directory into sources jar.
There is no need to execute "add-source" goal in any other phase; what you could find useful is letting the clean plug-in know that it should include the extra directory:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<filesets>
<fileset>
<directory>${basedir}/src/main/gen_src</directory>
<includes>
<include>**/*</include>
</includes>
</fileset>
</filesets>
</configuration>
</plugin>

Related

Running maven-shade and dockerfile-maven in different phases

My app uses maven-shade-plugin to pack things into single fatjar and then I would like to build a docker image using dockerfile-maven-plugin, my problem is that I can set the pom file properly so it would work.
What happens is that the docker plugin runs before the jar file was created...
I've tried to force the jar creation on prepare-package and the docker image build on package but it didn't work as expected...
any ideas?
EDIT: added pom snippet
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>dockerfile-maven-plugin</artifactId>
<version>${dockerfile-maven.version}</version>
<configuration>
<repository>test-docker-image</repository>
<tag>${docker.tag}</tag>
<buildArgs>
<JAR_FILE>${project.artifactId}-${project.version}-fat.jar</JAR_FILE>
<CONFIGURATION_FILE>configuration.json</CONFIGURATION_FILE>
</buildArgs>
</configuration>
<executions>
<execution>
<goals>
<goal>build</goal>
<!-- <goal>push</goal> -->
</goals>
<phase>install</phase>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${maven.shade.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>shade</goal>
</goals>
<phase>package</phase>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<Main-Class>io.vertx.core.Launcher</Main-Class>
<Main-Verticle>MyVerticle</Main-Verticle>
</manifestEntries>
</transformer>
</transformers>
<minimizeJar>false</minimizeJar>
<outputFile>${project.build.directory}/deploy/${project.artifactId}-${project.version}-fat.jar</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I had both of these same plugins listed in the same order you have (docker-maven-plugin before maven-shade-plugin) and was seeing the same issue. I discovered that Maven executes plugins in the same phase in the order that they are listed, so moving maven-shade-plugin to be first resolved the issue for me locally. (Older versions of Maven don't order plugins this way, so use the latest if possible.)
This doesn't explain why it is not working for you when you change them to use different phases, but I'd suggest at least trying it out that reordering. Also be sure that you are using the latest versions of related plugins, like maven-release-plugin.
I was still seeing the undesired behavior in my build environment after doing all of the above, due to the parent of my project containing an execution for docker-maven-plugin; the fact that I was customizing it and reordering it in my own project didn't help, although it is unclear why it worked locally. Maven build profiles can also have a similar impact on ordering. My solution there was to bind the docker-maven-plugin:build execution to the install phase.
The output of mvn help:effective-pom should let you see the exact listing of plugins, executions, and profiles so that you can see exactly what the ordering will be for your project. Note that profiles are executed bottom-to-top, which is the opposite of plugins!

How do I create an uber source jar with Maven?

Is there a well-known way to create an uber source jar? In other words, a jar of all the source code for a project and all its dependencies (or at least those that have a -sources.jar)?
I've looked into doing it with the maven-assembly-plugin, but using a dependencySet with includes of *.*.*.sources.* (or *.sources) doesn't work because those are not actually dependencies of the project, and I don't want to add them all.
You can use the maven-shade-plugin to create an uber jar. Just include the following within your <build> tag -
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>source-jar</id>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createSourcesJar>true</createSourcesJar>
<artifactSet>
<includes>
<include>...</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
To modify the configuration, you can use Resource Transformers within org.apache.maven.plugins.shade.resource package.
And to define the contents of the jar, you can further use includes and excludes within the filters.
I found some information on working with sources in the maven-dependency-plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>src-dependencies</id>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<classifier>sources</classifier>
<failOnMissingClassifierArtifact>false</failOnMissingClassifierArtifact>
<outputDirectory>${project.build.directory}/sources</outputDirectory>
<includeGroupIds>{your group prefix}</includeGroupIds>
<includes>**/*.java</includes>
<includeScope>runtime</includeScope>
</configuration>
</execution>
So if I do that, and then run a maven-assembly-plugin referencing the unpacked files, I can do it in two steps.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<execution>
<id>uber-source</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
<configuration>
<descriptors>
<descriptor>ubersource.xml</descriptor>
</descriptors>
<outputDirectory>${deploy.internal.directory}</outputDirectory>
<finalName>${project.artifactId}</finalName>
</configuration>
</execution>
</executions>
</plugin>
with a file set in the assembly descriptor ubsersource.xml:
<fileSet>
<directory>${project.build.directory}/sources</directory>
<outputDirectory>.</outputDirectory>
</fileSet>
And then I get my uber source jar...
There is perhaps a subtle distinction in the way the maven-assembly-plugin and maven-dependency-plugin treats sources. If you reference classifier sources in a dependencySet of an assembly descriptor, it looks for sources that are actual dependencies in your pom -- not that useful. However, in maven-dependency-plugin, referencing sources classifier means that sources of your dependencies. Hence why this solution works.
I also wrapped this up in my own plugin using mojo-executor to make it single step, and single declaration in my pom, but that's optional
This is a lot more pom code, but I like it better than the maven-shade-plugin because it does just what I want, and nothing more.

How to resolve dependency between files generated by maven plugin at compile time?

Ok, let me try to put my problem across as less confusing as I can.
I have a standard maven project with a few Maven plugins -
1) maven-antrun-plugin
2) Custom maven plugin, say, my-maven-plugin
3) jaxws-maven-plugin
Now here's the complicated part.
The 1st plugin generates a few .java files which I'm currently placing in "${project.build.directory}/java"
The 2nd plugin generates another set of .java files all of which I'm placing again under "${project.build.directory}/java". However, they're placed under different package structures.
Both of these plugins run during the "generate-sources" phase.
Now my 3rd plugin, jaxws-maven-plugin, tries to use the class files for the files generated by 1st and 2nd plugins, as the SEI to generate WSDLs. But the class files won't be created by maven at that point during the compilation and the plugin errors out with a "Class Not found" message.
So how do I go about trying to resolve this? Also, since I error out during the "generate-sources" phase, I don't see the .class files for any of the other source files from my project in the target/classes directory.
And oh, here's another twist. Some of my source files import these compile time generated source files in the code (You have no idea how badly I'm searching for this developer right now!!)
I have tried to describe my problem in the best possible way so please feel free to ask any other details or clarifications.
Run manually build-helper-maven-plugin and maven-compile-plugin before jaxws-maven-plugin:
<build>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
...
<executions>
<execution>
<phase>generate-sources</phase>
</execution>
...
</executions>
<plugin>
<plugin>
...
<artifactId>my-maven-plugin</artifactId>
...
<executions>
<execution>
<phase>generate-sources</phase>
</execution>
...
</executions>
<plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>some directory</source>
...
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compile-plugin</artifactId>
...
<executions>
<execution>
<phase>generate-sources</phase>
</execution>
<goals>
<goal>compile</goal>
</goals>
</executions>
<plugin>
<plugin>
<artifactId>jaxws-maven-pluginn</artifactId>
...
<plugin>
</plugins>
</build>
I haven't tested it but I think it should work.

Files got overwritten in maven project when building a war

I'm building a web application project using maven, and packaging is set to "war". I also use YUI compressor plugin to compress javascript codes in the webapp directory. I've set up the YUI compressor like this:
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.3.0</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
</execution>
</executions>
<configuration>
<excludes>
<exclude>**/ext-2.0/**/*.js</exclude>
<exclude>**/lang/*.js</exclude>
<exclude>**/javascripts/flot/*.js</exclude>
<exclude>**/javascripts/jqplot/*.js</exclude>
</excludes>
<nosuffix>true</nosuffix>
<force>true</force>
<jswarn>false</jswarn>
</configuration>
</plugin>
If I do: mvn process-resources, src/main/webapp will get copied over to target/webapp-1.0/ directory, and javacripts are compressed. However, when I run mvn install, all the compressed javascripts are overwritten, apparently the packaging process copies the content from main/webapp one time before building the war file.
How can I get around this?
As you noticed, the /src/main/webapp dir (aka warSourceDirectory) contents is not copied into the project dir for packaging until the war plugin executes during the package phase. When the war plugin completes the archive is already built; too late to modify those resources. If the .js files you want to compress were moved into another directory (outside of /src/main/webapp) then you could do something like the below.
To test, I created a ${basedir}/src/play directory with a couple of files in it. I used the resource plugin for the example; you'd replace that config with the YUI compressor plugin config you needed and simply add the <webResource> element to your war plugin config as shown below; more info in the war plugin examples. My war ended up with the additional files right where I wanted them.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>copy-resources</id>
<phase>process-resources</phase>
<goals><goal>copy-resources</goal></goals>
<configuration>
<outputDirectory>${project.build.directory}/tmpPlay</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/src/play</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<executions>
<execution>
<id>default-war</id>
<configuration>
<webResources>
<resource>
<directory>${project.build.directory}/tmpPlay</directory>
<targetPath>WEB-INF/yourLocationHere</targetPath>
<includes>
<include>**/*</include>
</includes>
</resource>
</webResources>
</configuration>
</execution>
</executions>
</plugin>
I think #user944849 answer is the correct answer, at least one of the correct answers. Another way of archiving this is to exclude the modified javascript directory from maven-war-plugin configuration, e.g.:
<plugin>
<artifactId> maven-war-plugin </artifactId>
<configuration>
<warSourceExcludes>**/external/ dojo/**/*.js </warSourceExcludes>
</configuration>
</plugin>
this will tell maven-war-plugin not to copy from the excluded directory, but since the modified javascript directory is already there, the war file still contains the javascript directory, BUT with the modified, in this case, compressed javascript codes.
in your execution directive, set the phase for applying your compression and copying to be install and that will hopefully do the trick. the code should be something like this:
<executions>
<execution>
....
<phase>install</phase>
....
</execution>
<executions>
Here is my solution, simply add an antrun plugin which updates the packaged war file using the processed outputs, which binds to the package phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>package</id>
<phase>package</phase>
<configuration>
<target>
<zip basedir="${project.build.directory}/${project.build.finalName}"
destfile="${project.build.directory}/${project.build.finalName}.war"
update="true">
</zip>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

delete the 'target' directory after build

i know this is probably frowned upon by maven lovers, but the whole 'target' directory is a waste of space in the context of our program and it's deployment. we have other build processes responsible for creating the actual deployment and i currently manually delete the target dir after every maven build, so that its contents don't interfere with my file searches etc...
is there a way to delete this dir automatically at the end of a maven build/install?
thanks, p.
Use the maven-clean-plugin as here http://maven.apache.org/plugins/maven-clean-plugin/examples/delete_additional_files.html
<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>install</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
You should simply add the clean goal to your maven goals at the end.
mvn install clean
The problem with the clean-plugin is that if you like to run the clean at the end of the build it depends which goal you called at the beginning. For example you called mvn package you need to have a phase post-package which does not exist or if you called mvn install you have to have phase post-install which does not exist either.
The easiest way is simply to add "clean" to the end of the normal build command. eg. mvn clean install clean.
if you want to just delete some directories in target folder, you have to create some construct like this.
this for instance deletes just all contents of folders:
target/unpack
gen-external-apklibs
excludeDefaultDirectories allows to not delete complete target folder.
i used it to clean up target folder before lint analysis.
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>Deleting all unnecessary files before lint analysis</id>
<phase>verify</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>target/unpack</directory>
<followSymlinks>false</followSymlinks>
<excludes>
<exclude>*</exclude>
</excludes>
</fileset>
<fileset>
<directory>gen-external-apklibs</directory>
<followSymlinks>false</followSymlinks>
<excludes>
<exclude>*</exclude>
</excludes>
</fileset>
</filesets>
<verbose>true</verbose>
</configuration>
</plugin>

Resources