maven jar option, creating a additional jar during build - maven

when trying to create a maven build, i need resouces soures jar, javadoc jar, and compiled classes jar, which is easily achieved through existing plugins.
But i do have XSD's under src/main/resources/xsd folder, which i prefer to be created in a diffent jar during the build process, is it possible?
thanks for the help in advance

You can add additional artefacts to your maven build using either a custom plugin or as an assembly. An assembly allows you to define any group of resources into a new artefact. This new artefact will be an 'attachement' to your existing one in the same way sources jars can be attached.
When creating an assembly you need to define a descriptor and put it somewhere like src/main/assembly/xsd.xml
The descriptor will look something like:
<assembly>
<id>xsd</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>src/main/resources/xsd</directory>
<includes>
<include>*.xsd</include>
</includes>
</fileSet>
</fileSets>
</assembly>
The second part is the assembly plugin configuration which will look something like:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/xsd.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-xsd-zip</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
This configuration should give you an artefact with the name: <artifactid>-<version>-<assemblyid>.zip

Well, MAVEN natively does not supports multiple artifacts from a single pom.xml. But you can create another empty project with only a pom to create another jar
codebase
|- pom.xml
|- src
|- xsdJar
|- pom.xml
|- [other stuff]
Now, in xsdJar\pom.xml,
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<includes>
<include>../src/main/resources/xsd/*</include>
</includes>
</configuration>
</plugin>
...
</plugins>
</build>
...
</project>
Also, call the above mentioned module in your main pom.xml
<modules>
<module>xsdJar</module>
</modules>

Related

Maven war packaging, include classes ignores excluded resources

I have the following pom
<project>
....
<packaging>war</packaging>
....
<build>
<plugins>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>config/**/*</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<archiveClasses>true</archiveClasses>
<warSourceExcludes>WEB-INF/sass/**</warSourceExcludes>
<attachClasses>true</attachClasses>
<webResources>
<resource>
<directory>src/main/resources/config</directory>
<excludes>
<exclude>**/*</exclude>
</excludes>
</resource>
</webResources>
</configuration>
</plugin>
...
</project>
As you can see, I package a WAR while my .class files are not in my WEB-INF/classes folder - they are packaged into a JAR instead.
Now, I am desperately trying to exclude some resources from my JAR - but it does not work. When I run mvn jar:jar - the resources are excluded, however when I run mvn package the resources are there.
Please help.
It seems that #user944849 is right - indeed, the war plugin does not use the jar plugin in order to achieve the JAR packaging.
However, his answer gave me a wrong result still as it will simply create 2 jars - one will be with the resources and the other without. The WAR will still use the wrong one.
The correct answer is to use the new maven resources tag.
The one that corresponds to my configuration looks as follows
<build>
....
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>config/**/*</exclude>
</excludes>
<filtering>false</filtering>
</resource>
</resources>
....
</build>
You do not have the jar:jar goal bound to a lifecycle phase. When you run jar:jar from the command line, the exclusions happen fine; when you run mvn clean package I suspect jar:jar is not executing. Try binding the goal to a phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals><goal>jar</goal></goals>
<phase>prepare-package</phase>
<configuration>
<excludes>
<exclude>config/**/*</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
FYI, the archiveClasses feature of the war:war plugin goal does something similar to what I think you're trying to achieve without requiring a separate plugin config.

Maven: inheritance of artifacts built by assembly plugin

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.

maven create zip with jar and some more files

I do not understand maven. Better use ant, but... I've managed to create jar (with, or without dependencies), I've managed to copy bat runner script close to jar but now i want to create zip with this jar and this bat. So i use assembly plugin and get BUUUM!!!! CADAAAM! In my configuration it happens so, that it executes parallel to jar packaging. I wrote assembly file:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>jg</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>${project.build.directory}/classes</directory>
<outputDirectory>/123</outputDirectory>
<excludes>
<exclude>assembly/**</exclude>
<exclude>runners/**</exclude>
</excludes>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>
Then, I bound maven-assembly-plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<inherited>false</inherited>
<configuration>
<archive>
<manifest>
<mainClass>by.dev.madhead.lzwj.Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
<descriptors>
<descriptor>src/main/resources/assembly/assembly.xml</descriptor>
<!-- <descriptorRef>jar-with-dependencies</descriptorRef> -->
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
Now I get this in ./target:
runner.bat
jar_without_dependencies.jar (it is from maven-jar-plugin, right?)
jar_without_dependencies.jar
And the third angers me. It contains:
And the 123 directory contains:
As you see, I get jar with unpacked dependencies, EXCLUDED DIRS!!!!, and with dir 123, which is actually what I want (Oh! assembly plugin did that!!!).
I want to get jar with dependencies and correct manifest with classpath. As an option i want jar with unpacked dependencies (I know about <unpack>false</unpack> in assembly, but cannot get it work). I want to change /123 to / and get NORMAL JAR WITHOUT EXCLUDED FILES!!! I want two separate tasks to build jar and zip (is it done with profiles in maven??) As in ant, i would wrote something like this:
<target name="jar_with_deps" depends-on="compile">
<jar>
here i copy classes (excluding some dirs with runner script), and build manifest
</jar>
<copy>
copy bat file from src/main/resources/runner/runner.bat
</copy>
</target>
<target name="zip" depends-on="jar_with_deps">
<zip>
Get jar from previous target, get runner.bat. Put them in zip
</zip>
</target>
Excuse me, if I am too expressive, but I am really angry with this implicit behavior. I am really stuck with this.
Just in case it helps anyone else, I found that this was pretty easy to do, at least for my basic needs. I was already using the Maven Shade plugin to build a jar with all dependencies included:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<configuration></configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
So when I ran mvn package, it would produce target/MyApp-version.jar, whereas I wanted a MyApp-version.zip containing MyApp-version.jar along with some other files (a README, etc.). So, I add the Assembly plugin:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.5.5</version>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
The above block refers to assembly.xml, which configures the way the plugin works:
<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>release</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>target</directory>
<includes>
<include>MyApp-${app.version}.jar</include>
</includes>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
<files>
<file>
<source>CHANGES.md</source>
<fileMode>0644</fileMode>
</file>
<file>
<source>LICENSE</source>
<fileMode>0644</fileMode>
</file>
<file>
<source>README</source>
<fileMode>0644</fileMode>
</file>
</files>
</assembly>
(${app.version} is defined in the pom.xml <properties> element.)
That's it, now mvn package produces both the jar and the zip.
You have to options to achieve your goal:
option: Create two assembly descriptors, one for jar w/ deps and one for zip. Zip takes the the newly created jar.
option: Create two more modules in your project: first modules shades all deps into one jar (or attach a shaded jar along with your main jar, save another module), have the second module depend on it and suck in that jar in your assembly. Your done.
Depending on the size and structure of your project, I would go for the safe way: option 2. This one is guaranteed to have the correct build and dep order. Option 1 violates the maven way somewhat.
I've made two profiles in pom.xml:
<profiles>
<profile>
<id>jar-with-dependencies</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<archive>
<manifest>
<mainClass>by.dev.madhead.lzwj.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>distro</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/distro.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
Now i am able to create simple jar (mvn clean package), jar with dependencies (mvn clean package -Pjar-with-dependencies). I also can call mvn package -Pdistro to create zip. But i need to call maven with -Pjar-with-dependencies before it manually. Except this, everything is ok.

How can I make the test jar include dependencies in Maven?

I have a project with src/main/java and src/test/java structure, and I managed to use maven-jar-plugin to build a jar of the test branch. However, I want to package the test jar so that all the dependencies are resolved. Is there a way I can tell maven-jar-plugin to include the dependencies??
Thanks!
Frank
I had a similar problem with integration tests I need to run on Hadoop. Our integration tests are located in the test folder of a separate integration test module, so what is required is a test-jar-with-dependencies to make our life easier.
I'm using the assembly plugin as mentioned by Michael-O. My assembly descriptor is located in src/main/assembly/test-jar-with-dependencies.xml and is a modification of the standard jar-with-dependencies descriptor that's part of the plugin:
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
<id>test-jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<!-- we're creating the test-jar as an attachement -->
<useProjectAttachments>true</useProjectAttachments>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
</assembly>
This assembly relies on the test-jar being created as part of the module build. So I added the following to the module's pom.xml:
<!-- create a complete jar for testing in other environments -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/main/assembly/test-jar-with-dependencies.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
You can do this: Create a jar assembly with the assembly plugin, have the dependencies unpacked, pack a new test jar and attach it to the reactor. You're done.
The descriptor for the packaging could look like this.
In a similar situation I ended up moving my test code to a separate jar and made it depend on the original one. You can use an aggregator project to ensure that tests are run when you build the main jar.
<dependency>
<groupId>me.wener.xxx</groupId>
<artifactId>xxx-core</artifactId>
<version>${xxx.version}</version>
<type>test-jar</type>
<!-- <scope>test</scope> -->
</dependency>
I use this to include the test jar.the important line is <type>test-jar</type>.I am not sure this is what you need.
3 years ago, but may help others.At least, it helped me. :-)
to include a test-jar dependency in your assembly specify the include filter of the assembly debendencySet as bellow:
...
<dependencySet>
<outputDirectory>/</outputDirectory>
<includes>
<include>*:jar:*</include>
<include>*:test-jar:*</include>
</includes>
</dependencySet>
...
The following worked for Maven 3
POM.XML
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
<phase>test-compile</phase>
</execution>
</executions>
</plugin>
ASSEMBLY FILE
<dependencySet>
<outputDirectory>demo/test-lib</outputDirectory>
<includes>
<!--test only dependencies (like netty)-->
<include>io.netty:netty-all</include>
<!-- the actual test jar-->
<include>${project.groupId}:${project.artifactId}:test-jar</include>
</includes>
<useProjectAttachments>true</useProjectAttachments>
<scope>test</scope>
</dependencySet>

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