I have a multimodule project such as:
top
|----sub1/
|----sub2/
|----packager/
sub1 and sub2 have multiple assemblies attached. Let's say sub1's assemblies creates target/dist/artifactA.jar and target/dist/artifactB.jar
If I create another assembly in packager, how can I pull in artifactA and artifactB from sub1, etc?
If I use this including groupId:artifactId:type:classifier as below, I get the error: "You must set at least one file".
Even if this did work, this isn't exactly what I want, anyway. I want the versions of the files in sub1/target/dist, which don't have version or artifactIds on them (as per sub1's assembly configuration).
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>my-distribution</id>
<formats>
<format>zip</format>
</formats>
<moduleSets>
<moduleSet>
<useAllReactorProjects>true</useAllReactorProjects>
<binaries>
<unpack>false</unpack>
<includes>
<include>com.example:sub1:jar:artifactA</include>
<include>com.example:sub1:jar:artifactB</include>
</includes>
</binaries>
</moduleSet>
</moduleSets>
edit: looks like <moduleset> works only if the sub modules are directly below the module doing the assembling. <dependencyset> is recommended in my case... but I still have the problem of rounding up attached jars that are not the primary jar.
Related
Something that has always made me wonder with maven-assembly-plugin is that the jar-with-dependencies example file on the apache website has a TODO comment about a jarjar format.
Is this just an artifact of code that keeps getting copied through indefinitely or is there some actual reason behind that TODO on the sample file?
The documentation states the following
Use jar-with-dependencies as the descriptorRef of your assembly-plugin
configuration in order to create a JAR which contains the binary
output of your project, along its the unpacked dependencies.
So jar-with-dependencies creates a single JAR will all the class files of your project and also all the unpacked class files of your dependencies.
I'm guessing, "jarjar" refers to something like the Spring Boot Maven plugin does: it also creates a single JAR file, but the dependencies are included in their original JAR files, not unpacked. In contrast to the assembly plugin approach, this requires a custom class loader.
However, you should probably ask this question on the Maven mailing list. I just did so and will update this answer if I get any new information.
Updates
In found out that this particular part of the web page (including the TODO) was added over 10 years ago. Apparently the TODO hasn't been changed since.
I suspect this is referring to a jarjar format, which repackages Java libraries and embeds them into your own distribution, to allow for no dependencies.
see: jarjar
In the context of the example file, which contains:
<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">
<!-- TODO: a jarjar format would be better -->
<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
</dependencySet>
</dependencySets>
</assembly>
I think the todo is to indicate that this is how this certain method is done, but that a jarjar would be better. That is, "here's how you do it, but you should do it this other way".
I want to pack two or more very similar distributions, the only difference is path to data set that will be inside those distributions.
Given this example for path: ${project.basedir}/src/config/dataset1
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>dataset1</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/src/config/dataset1/aaa</directory>
<outputDirectory>conf/aaa</outputDirectory>
</fileSet>
<fileSet>
<directory>${project.basedir}/src/config/dataset1/bbb</directory>
<outputDirectory>conf/bbb</outputDirectory>
</fileSet>
</fileSets>
<!-- MANY MORE FILESETS... -->
</assembly>
Now I want exactly the same assembly descriptor for different data set, for example: ${project.basedir}/src/config/dataset2
Off course I could create two assembly descriptors. But then again I would have to keep in mind to change multiple places when needed, or worse when adding another dataset or two.
Is there a way how solve this, like creating multiple executions and passing properties to it? Or something ever nicer?
EDIT:
This wish item would solve everything:
https://jira.codehaus.org/browse/MASSEMBLY-445
Yes, you could use properties for this.
Create properties (with default value) for parts that differs between executions in pom.xml. E.g.:
<properties>
<dataset.dir>config/dataset</dataset.dir>
</properties>
Use them in your assembly descriptor just like any other property (e.g ${project.basedir} )
For different executions you could:
use several build profiles (Maven profiles) where override property value;
or pass values directly as a mvn call argument (like mvn package -Dprop=val)
Also, if you want to use these properties in any other place, you could populate them via placeholders in any config by using other maven plugins (for instance, maven-resource-plugin).
I need to create a hadoop job jar file that uses mahout and a bunch of other libraries. I need ti be able to run the job without needing additional jar.files such that all referenced classes are packaged with the resultant jar file. How can this be done?
Configure your build file to copy all the referenced classes to the build directory. For example, in ant:
<path id="classpathunjar">
<fileset dir="${lib.dir}" includes="*.jar" excludes="sqljdbc4.jar"/>
</path>
<target name="compile" depends="clean">
...
<unjar dest="${build.dir}">
<path refid="classpathunjar" />
</unjar>
...
</target>
But it is better if you can manage without doing this. Use the libjars feature to load the jars into all nodes if you are doing this for running mapreduce jobs on a hadoop cluster
Hadoop has the ability to read jars-in-jar. Amend you Ant script to include all the dependency jars in a folder called lib, and add this lib folder to your output Jar. This is sometimes a better choice if you have number of larger jars as it decreases your jar build time.
See this article on a number of options you have when using 3rd party libs with hadoop
http://www.cloudera.com/blog/2011/01/how-to-include-third-party-libraries-in-your-map-reduce-job/
Jar is just a Zip container.
You can manually unzip and modify your Jar file with the classes needed, or you can make use of e.g., the jar-with-dependencies descriptor of the Maven build system.
In the generic sense, it is sometimes impossible, as JAR files have resources that must be in particular locations, and two conflicting but necessary resources might prevent the combination (Think META-INF/MANIFEST.MF)
However, in many cases it is very easy. Basically you unzip the JAR file to be added (it is a zip file format) and "add" the classes and what-not to the existing JAR file.
A better choice if you are making an executable JAR file is to add a ClassPath entry into your launching MANIFEST.MF and ship both JAR files in a directory structure compatible with your added ClassPath entry.
Note that the additional jars have to be put under a lib/ subdirectory (Yes, jars within a jar). I use the following maven assembly, which I found somewhere else.
<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>job</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>false</unpack>
<scope>runtime</scope>
<outputDirectory>lib</outputDirectory>
<excludes>
<exclude>org.apache.hadoop:hadoop-core</exclude>
<exclude>${artifact.groupId}:${artifact.artifactId}</exclude>
</excludes>
</dependencySet>
<dependencySet>
<unpack>false</unpack>
<scope>system</scope>
<outputDirectory>lib</outputDirectory>
<excludes>
<exclude>${artifact.groupId}:${artifact.artifactId}</exclude>
</excludes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${basedir}/target/classes</directory>
<outputDirectory>/</outputDirectory>
<excludes>
<exclude>*.jar</exclude>
</excludes>
</fileSet>
</fileSets>
</assembly>
Is there a tool which takes a Java File what describes a REST service as a parameter and generates a wadl file out of that.
I had the same problem: was using RESTeasy and wanted to find a way to generate the WADL automatically.
Did some research and came to the solution below.
1. Add this to your pom.xml:
<build>
<plugins>
<plugin>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>maven-wadl-plugin</artifactId>
<version>1.17</version>
<executions>
<execution>
<id>generate</id>
<goals>
<goal>generate</goal>
</goals>
<phase>${javadoc-phase}</phase>
</execution>
</executions>
<configuration>
<wadlFile>${project.build.outputDirectory}/application.wadl
</wadlFile>
<formatWadlFile>true</formatWadlFile>
<baseUri>http://example.com:8080/rest</baseUri>
<packagesResourceConfig>
<param>com.example.rs.resource</param>
</packagesResourceConfig>
<wadlGenerators>
<wadlGeneratorDescription>
<className>com.sun.jersey.server.wadl.generators.WadlGeneratorApplicationDoc
</className>
<properties>
<property>
<name>applicationDocsFile</name>
<value>${basedir}/src/main/doc/application-doc.xml</value>
</property>
</properties>
</wadlGeneratorDescription>
<wadlGeneratorDescription>
<className>com.sun.jersey.server.wadl.generators.WadlGeneratorGrammarsSupport
</className>
<properties>
<property>
<name>grammarsFile</name>
<value>${basedir}/src/main/doc/application-grammars.xml</value>
</property>
</properties>
</wadlGeneratorDescription>
</wadlGenerators>
</configuration>
</plugin>
</plugins>
</build>
Pay attention to the buildUri and packagesResourceConfig elements. You have to change them to reflect your project's configuration. You may also want to change the plugin's version (I used 1.17).
2. Create a /doc folder and add some files.
Create the src/main/doc/ folder and create the two files below.
File: application-doc.xml
Content:
<?xml version="1.0" encoding="UTF-8"?>
<applicationDocs targetNamespace="http://wadl.dev.java.net/2009/02">
<doc xml:lang="en" title="A message in the WADL">This is added to the start of the generated application.wadl</doc>
</applicationDocs>
File: application-grammars.xml
Content:
<?xml version="1.0" encoding="UTF-8" ?>
<grammars xmlns="http://wadl.dev.java.net/2009/02" />
3. Run the maven command.
Go to the project folder and run the following command:
$ mvn compile com.sun.jersey.contribs:maven-wadl-plugin:generate
The files \target\classes\application.wadl (the WADL itself) and \target\classes\xsd0.xsd (the schema of the resources - it's used by the application.wadl) should be generated.
Edit and use them as you wish.
PS.: Bear in mind that this is a very simple use of the maven-wadl-plugin. It can do a lot more. To know it better, please refer to the zip file mentioned in the other answer (by Pavel Bucek).
Yes, please see gerenate-wadl [1] sample from Jersey samples (look for maven-wadl-plugin).
[1] http://search.maven.org/remotecontent?filepath=com/sun/jersey/samples/generate-wadl/1.12/generate-wadl-1.12-project.zip
We are using ANT for our build process and don't have plans to change this in the near future.
Is it possible to use Maven to just fetch common Open Source jar files (e.g. Log4J, SWT, JFace) and put them in the right location of our project, so we don't have to store them in our version control — preferable without creating the typical Maven-cache in the home directory?
NO NO NO Everyone!
If you're using Ant, the best way to use Maven repositories to download jar dependencies is to use Ivy with Ant. That's exactly what Ivy is for.
Installing Ivy and getting to work with current Ant projects is simple to do. It works with Nexus and Artifactory if you use those as your local Maven repositories.
Take a look at Ivy. It is probably exactly what you want.
In variation of org.life.java's answer, I would not do mvn install.
Instead, in the pom.xml I would add the following bit:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Now you just need to do mvn generate-sources, which is a lot faster than the full mvn install, and all dependencies will be copied to the specified directory.
Oh btw, isn't that what Apache Ivy is about? Extending Ant to understand Maven's dependency management?
It's possible, you should use maven-ant-tasks.
In particular its dependencies ant task. With this setup no Maven install is required.
<?xml version="1.0" encoding="UTF-8"?>
<project
name="download-dependency"
basedir="."
default="download-dependency"
xmlns:artifact="antlib:org.apache.maven.artifact.ant"
>
<target name="download-dependency">
... define properties ...
<taskdef
resource="org/apache/maven/artifact/ant/antlib.xml"
uri="antlib:org.apache.maven.artifact.ant"
/>
<artifact:dependencies>
<localRepository path="${local-repo.dir}"/>
<remoteRepository id="central" url="${repository-uri}"/>
<dependency
groupId="${groupId}"
artifactId="${artifactId}"
version="${version}"
type="${type}"
classifier="${classifier}"
scope="runtime"
/>
</artifact:dependencies>
</target>
</project>
The only binary you should check into your project is maven-ant-tasks.jar.
Actually in our project I used Sonatype Nexus ( documentation ) Maven repository manager to centralize access to different repositories and even maintain some binaries unique to our environment. With Nexus' help I just fetch maven-ant-tasks.jar with ant's <get> task from a known URL. You don't have to use Nexus, but it greatly speeds up builds, because it caches binaries close to your developer's machines.
Ivy does just this,
when it bootstraps itself:
http://ant.apache.org/ivy/history/latest-milestone/samples/build.xml
<property name="ivy.install.version" value="2.0.0-beta1"/>
<property name="ivy.jar.dir" value="lib"/>
<property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>
<target name="resolve" unless="skip.download">
<mkdir dir="${ivy.jar.dir}"/>
<echo message="installing ivy..."/>
<get src="http://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar" dest="${ivy.jar.file}" usetimestamp="true"/>
</target>