Maven: inheritance of artifacts built by assembly plugin - maven

I am building our Web-application using Maven Assembly plug-in. This is motivated by a requirement to extract some data out of special plug-ins. The fragment of assembly descriptor demonstrates this:
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
<useProjectArtifact>false</useProjectArtifact>
<includes>
<include>org.myproject.module:*:jar</include>
</includes>
<unpackOptions>
<includes>
<include>images/**</include>
<include>install/**</include>
<include>mappings/**</include>
</includes>
</unpackOptions>
<outputDirectory>./WEB-INF/myproject-modules/${artifact.name}</outputDirectory>
</dependencySet>
All plug-ins with groupId=org.myproject.module have this special treatment and extraction of module-specific folders.
Now, I have a requirement to build another WAR with exactly the same approach, but different set of modules. Is there any way to nicely extend my original POM, and simply add dependencies, without need to have a copy of my assembly descriptor(s) (stored in src/main/assembly)?
Simply extending pom fails with missing assembly descriptor, which is physically found in parent:
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.3</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
</build>

There is an example of how to share assembly descriptors between projects in the assembly plugin docs. That should work if you're not using assembly components; I've seen references to classpath issues when using components with this method.

Related

How to copy file from Parent POM into Maven Project

I want to have a Parent Maven project that has two files.
src/license/LICENSE.txt
src/license/NOTICE.txt
When I build my main Project, that references it as a Parent POM, I want those files to be included in the produced JAR.
I know I can use...
<build>
<resources>
<resource>
<targetPath>META-INF</targetPath>
<directory>src/license</directory>
<includes>
<include>NOTICE.txt</include>
<include>LICENSE.txt</include>
</includes>
</resource>
</resources>
</build>
But this will only work when the files are located in main Project, not when they are in the Parent project.
I found a solution to this.
First, create a new repo to hold the items you want to be copied in.
The POM of this should contain this (GAV details are com.jeff:base-pom-license)...
<build>
<plugins>
<plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>**/*.txt</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
Then in your Base pom add this...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.5</version>
<configuration>
<resourceBundles>
<resourceBundle>com.jeff:base-pom-license:${project.version}</resourceBundle>
</resourceBundles>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
</plugin>
This will cause the files you have in the new maven repo to be included in all the places that extend the base pom.

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.

maven-ejb-plugin: include generated sources

I have an EJB-maven-Project that has some generated classes (generated by JAXB).
They are generated into: target/generated-sources/jaxb/
Now, with maven-ejb-plugin I want them (i.e. their compilated classes) to be included into the client-jar, something like that:
<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<!-- Tell Maven we are using EJB 3.1 -->
<ejbVersion>3.1</ejbVersion>
<generateClient>true</generateClient>
<clientIncludes>
<clientInclude>com/bla/ch/authorization/client/**</clientInclude>
<clientInclude>target/generated-sources/jaxb/**</clientInclude>
</clientIncludes>
</configuration>
</plugin>
This does not work, the generated classes are not part of the ejb-client-jar. (Though they are in the ejb-jar).
How can I do this correctly?
Include sources in your jar is probably not a good solution.
You may add generated sources in you resources locations, and then use source-plugin, to generate the so called artifact-sources.jar
<resources>
<resource>
<directory>${basedir}/target/generated-sources</directory>
<filtering>true</filtering>
</resource>
</resources>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This is a better way than producing a jar with source code.

How to use <includes> / <excludes> in maven-remote-resources-plugin

I am trying to use the maven-remote-resources-plugin as per this example to selectively share common resources between multiple maven modules and I'm having a lot of difficulty getting the selective import of the resources to work.
I am trying to use <includes> and <excludes> elements as per below. I haven't seen these mentioned in doco for the plugin anywhere but eclipse provides them as valid options in the command completion and I don't get any errors when I run the pom. So far I haven't been able to get <includes> or <excludes> to have any effect at all on the imported resources
The relevant sections of my pom are;
Shared resources
<build>
<plugins>
<plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>bundle</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>**/*</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.3</version>
</dependency>
</dependencies>
Resource consumer
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.3</version>
<configuration>
<resourceBunldes>
<resourceBundle>myApp:myApp_sharedresources:${project.version}</resourceBundle>
</resourceBundles>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<includes>
<include>theOnlyResourceIWant.properties</include>
</includes>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<phase>generate-resources</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>myApp</groupId>
<artifactId>myApp_sharedresources</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
I've tried many combinations of <includes> and <excludes> but all so far have had no impact.
So, are
<includes></includes>
and
<excludes></excludes>
valid elements for a maven-remote-resources-plugin configuration, and how do I use them?
I can reasonably seperate the resources out into seperate maven modules, but that could create a large number of single file maven modules and add a lot of extra xml so I'd like to avoid it if possible.
I'd really rather not start pawing through the plugin source code, but that is the next step.
I use a temp directory for the shared resources I'm importing and filter that.
Remote resource plugin configuration below. This copies all the shared resources into a temp directory in your project. Setting attached to false means they are not included in your final project artifact, which gives you the opportunity to select the ones you want to include using Maven's normal resource processing.
<plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<configuration>
<resourceBundles>
<resourceBundle>myApp:myApp_sharedresources:${project.version}</resourceBundle>
</resourceBundles>
<attached>false</attached>
<outputDirectory>${project.build.directory}/shared-resources</outputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<phase>generate-resources</phase>
</execution>
</executions>
</plugin>
Resource definition. When the maven-resource-plugin runs (it is bound to the lifecycle by default for jars/wars/ears), it will use the shared resource directory as well as the normal src/main/resources dir. You need to define both. (You may also enable resource filtering if you want.)
<resources>
<resource>
<directory>${project.build.directory}/shared-resources</directory>
<includes>
<include>theOnlyResourceIWant.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
I recommend making the shared directory be a subdirectory of ${project.build.directory}, so the clean lifecycle works without changes.
To enable the filter delimiters for the format '#{expr}' (Ruby-style), add the following to your plugin configuration:
<plugin>
<artifactId>maven-remote-resources-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>process-remote-resources</id>
<goals>
<goal>process</goal>
</goals>
<configuration>
<filterDelimiters>
<filterDelimiter>#{*}</filterDelimiter>
</filterDelimiters>
[...]
</configuration>
</execution>
</executions>
</plugin>
Check this link for reference

Maven 3: Generate Javadoc for defined artifacts

I want to generate javadocs only for certain artifacts of my project from within a dedicated docs-project.
That means that I would like to have an independent project called "docs" for example. In the docs/pom.xml I would like to define the artifacts that should be included in the generated javadocs.
So far I learned that I have to generate a separate sources.jar for the projects I want to include. But I can't figure out how to go on from there.
For now I can only imagine two approaches:
Get the artifacts (sources.jar) I want to include, unpack them and somehow point the Javadoc plugin to the source directory.
Define the artifacts I am interested as dependency and use the "dependencySourceInclude" option of the javadoc-plugin. But I am not sure if this is usage as intended.
Any suggestions how to solve this problem?
I have found a solution my self. It is a bit of a hack but it does work for me. I chose to go with my first idea:
Get the artifacts (sources.jar) I want to include, unpack them and somehow point the javadoc plugin to the source directory.
This solution has four differents parts which I'll explain in more detail later:
Generate sources.jars in all artifacts I want to include
Unpack those sources.jars
Generate Javadoc by pointing the javadoc-plugin to the unpacked sources
Package the generated apidocs in a zip file
Now in more detail:
1. Generate sources.jars in all artifacts I want to include
To generate sources.jars you have to use the maven-sources-plugin as follows:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>bundle-sources</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
You have to do this in every project/module/artifact you want to include in your apidocs.
2. Unpack those sources.jars
In you pom.xml you use to generate the javadocs you have to add the following plugins to unpack the sources.jar files.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-artifact-sources</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId><!-- your artifact here --></artifactId>
<version>${project.version}</version>
<classifier>sources</classifier>
<overWrite>true</overWrite>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/unpack_sources</outputDirectory>
</configuration>
</execution>
<!-- add more unpack-executions here -->
</executions>
</plugin>
You can add as many unpack-execution-blocks as you like.
3. Generate Javadoc by pointing the javadoc-plugin to the unpacked sources
Now the tricky part. Letting the javadoc-plugin know where to look for the source files. The imported definition is the <sourcepath> definition. In this section we define the folder where we have unpacked the sources in step 2.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.7</version>
<configuration>
<sourcepath>${project.build.directory}/unpack_sources</sourcepath>
</configuration>
<executions>
<execution>
<goals>
<goal>javadoc</goal>
</goals>
<phase>process-resources</phase>
</execution>
</executions>
</plugin>
When you call mvn clean install at this point you will end up with a site folder inside your target folder. In this site folder you'll find your apidocs. But to make this build all shiny and stuff we want to assemble the apidocs into a zip archive.
4. Package the generated apidocs in a zip file
To assemble the docs you have to use the maven-assembly-plugin and a extra assembly-file.
First the plugin-defintion inside your pom:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>docs-assembly</id>
<phase>package</phase>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>src/main/assembly/assemble.xml</descriptor>
</descriptors>
</configuration>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
assemble.xml:
<?xml version="1.0" encoding="UTF-8"?>
<assembly>
<id>${project.build.finalName}</id>
<formats>
<format>zip</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>target/site/apidocs</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>

Resources