My ear project has the following structure:
And my pom.xml goes like this:
<plugin>
<artifactId>maven-ear-plugin</artifactId>
<version>2.10</version>
<configuration>
<earSourceIncludes>META-INF/*</earSourceIncludes>
<packagingIncludes>META-INF/*,**/*.war</packagingIncludes>
<version>7</version>
<modules>
<webModule>
<groupId>com.ex</groupId>
<artifactId>one</artifactId>
</webModule>
</modules>
<generateApplicationXml>false</generateApplicationXml>
</configuration>
</plugin>
What I want is to include in my ear file the contents of the folder META-INF, in a similar folder in the root of the ear file called META-INF.
I've tried multiple combinations with earSourceIncludes and packagingIncludes with no success: My ear file has the linked application .war, which is good, and a META-INF folder which doesn't have what I need, but a pregenerated MANIFEST.MF file and a maven folder with the pom instead.
I wonder if I need the earSourceIncludes at all. To be honest, I don't know why it didn't work with just the packagingIncludes parameter.
You could use the maven-resource-plugin to include the content of META-INF folder to root META-INF folder. See below.
Let
Project base directory - ${project.basedir}
EAR root directory - ${project.rootdir}
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/${project.build.finalName}/META-INF</outputDirectory>
<resources>
<resource>
<directory>${project.basedir}/META-INF</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
I would like to generate a sources jar file for my project, so I have included the maven-source-plugin. However, I am also using the resource filtering plugin to set a version number in a property file for my project. When I generate a final jar file, the property file has been filtered and the version is set. However in the sources jar, is still has the unfiltered property. I would like for the sources plugin to also invoke the resource filtering. How can I do this?
Here is (part) of my pom.xml
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
</plugin>
<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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
and here is the property file that I want filtered in
version = ${project.version}
EDIT
For clarification, the root of my issue is that I have another project that is a GWT project built using this library. Part of the requirements of a GWT project is that the source code has to also be made available for anything that is going to be compiled to client side javascript. Therefore, this project contains both the compiled jar and the sources jar in the classpath.
So there are now two properties files with the same package path and name, one exists in the compiled jar and one in the sources jar.
When I attempt to read this file, it seems to pick the properties file out of the sources jar, which has not been filtered.
Normally, you'd use the maven-source-plugin for this. However, I see in its documentation that you cannot remove src/main/resources from its processing, while simultaneously adding target/classes to its processing cycle (which is what you would need to do in order to accomplish your task)
Therefore, I think your best bet is through a maven-assembly-plugin configuration.
I have a Maven project where I want to have two build artifacts:
The jar file containing the compiled Java source.
A folder containing a number of .properties file.
How can I setup my Maven project to do this? And then, once I've done this, how can I consume them up the dependency graph?
Add a copy-resources goal of the Maven Resources Plugin to your POM.
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-property-files</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/property-files</outputDirectory>
<resources>
<resource>
...
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>
I can't understand what you mean exactly by "consume them up the dependency graph".
According to maven-war-plugin FAQ,
If you can't move the classes to another project, you can deploy the classes and resources included in your webapp as an "attached" artifact, with a classifier, by using the following configuration:
<project>
...
<artifactId>mywebapp</artifactId>
<version>1.0-SNAPSHOT</version>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
This will result in two artifacts being deployed: mywebapp-1.0-SNAPSHOT.war and mywebapp-1.0-SNAPSHOT-classes.jar.
Is there any way possible that I could get mywebapp-1.0-SNAPSHOT.jar instead of mywebapp-1.0-SNAPSHOT-classes.jar?
Update: :
I want both war as well as jar to be generated. Though I am able to do this by applying profiles as mentioned in Changing packaging based on active profile in pom. But I am curious to know about above question.
Short answer: no, you can't.
By looking at the maven-war-plugin sources, in WarMojo.java (line 292), you can see that you cannot meet your requirement by simply modifying the maven-war-plugin configuration:
protected static File getTargetFile( File basedir, String finalName, String classifier, String type )
{
if ( classifier == null )
{
classifier = "";
}
else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
{
classifier = "-" + classifier;
}
return new File( basedir, finalName + classifier + "." + type );
}
Since the classesClassifier parameter is "classes" by default, you have no chance to modify this behavior: classifier will never be null.
Either you rename the file after its generation, or you modify the source code of the maven-war-plugin, and use it as a custom plugin.
As a final consideration, it is not advisable to have a null classesClassifier: it could be misleading. I do not know your project requirement though.
Hope it helps.
The closest approach to what you want to do is to use <classesClassifier>
as
<project>
...
<artifactId>mywebapp</artifactId>
<version>1.0-SNAPSHOT</version>
...
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<attachClasses>true</attachClasses>
<classesClassifier>someClassifier</classesClassifier>
</configuration>
</plugin>
</plugins>
</build>
...
</project>
but this approach will always put the classifier as your_jar-classifier.jar and if you create and empty or spaced tag, it will default to -classes
On the other hand, by using archiveClasses instead of attachClasses you will find the JAR just as you want it inside war's WEB-INF\lib (without the classifier), but no WEB-INF\classes will be generated.
Try to configure your webapp's pom.xml using the following <build> section, to see if it fits your needs :
...
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>create-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}.jar</file>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
This section asks Maven to explicitly create a jar, then it attaches the created jar to the build so that the install phase can copy the generated artifact into the local repository.
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<archiveClasses>true</archiveClasses>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-jar</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}/WEB-INF/lib/${project.build.finalName}.jar</file>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Combining some of the ideas mentioned above seems to work for me. The <archiveClasses> (as explained here) causes the required JAR to be generated within the WAR file and the attach-artifact goal extracts that file as an artifact.
Maven's general philosophy is that one POM generates one artifact. That would mean the cleanest, most "Maveny" way to get the Jar out of your project is to separate your Java code and the Webapp items into two modules grouped together by a parent project.
So a potential project hierarchy could be:
mywebapp-parent/ -> Contains all dependency info, project version
mywebapp/ -> Creates Jar
mywebapp-web/ -> Depends on mywebapp, Creates War
How do I get my project's runtime dependencies copied into the target/lib folder?
As it is right now, after mvn clean install the target folder contains only my project's jar, but none of the runtime dependencies.
This works for me:
<project>
...
<profiles>
<profile>
<id>qa</id>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
mvn install dependency:copy-dependencies
Works for me with dependencies directory created in target folder. Like it!
The best approach depends on what you want to do:
If you want to bundle your dependencies into a WAR or EAR file, then simply set the packaging type of your project to EAR or WAR. Maven will bundle the dependencies into the right location.
If you want to create a JAR file that includes your code along with all your dependencies, then use the assembly plugin with the jar-with-dependencies descriptor. Maven will generate a complete JAR file with all your classes plus the classes from any dependencies.
If you want to simply pull your dependencies into the target directory interactively, then use the dependency plugin to copy your files in.
If you want to pull in the dependencies for some other type of processing, then you will probably need to generate your own plugin. There are APIs to get the list of dependencies, and their location on disk. You will have to take it from there...
Take a look at the Maven dependency plugin, specifically, the dependency:copy-dependencies goal. Take a look at the example under the heading The dependency:copy-dependencies mojo. Set the outputDirectory configuration property to ${basedir}/target/lib (I believe, you'll have to test).
Hope this helps.
All you need is the following snippet inside pom.xml's build/plugins:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
The above will run in the package phase when you run
mvn clean package
And the dependencies will be copied to the outputDirectory specified in the snippet, i.e. lib in this case.
If you only want to do that occasionally, then no changes to pom.xml are required. Simply run the following:
mvn clean package dependency:copy-dependencies
To override the default location, which is ${project.build.directory}/dependencies, add a System property named outputDirectory, i.e.
-DoutputDirectory=${project.build.directory}/lib
If you want to do this on an occasional basis (and thus don't want to change your POM), try this command-line:
mvn dependency:copy-dependencies -DoutputDirectory=${project.build.directory}/lib
If you omit the last argument, the dependences are placed in target/dependencies.
A simple and elegant solution for the case where one needs to copy the dependencies to a target directory without using any other phases of maven (I found this very useful when working with Vaadin).
Complete pom example:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>process-sources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${targetdirectory}</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Then run mvn process-sources
The jar file dependencies can be found in /target/dependency
Try something like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>MainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy</id>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
supposing
you don't want to alter the pom.xml
you don't want test scoped (e.g. junit.jar) or provided dependencies (e.g. wlfullclient.jar)
here ist what worked for me:
mvn install dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/lib
If you want to deliver a bundle of your application jar, together with all its dependencies and some scripts to invoke the MainClass, look at the appassembler-maven-plugin.
The following configuration will generate scripts for Window and Linux to launch the application (with a generated path referencing all the dependency jars, download all dependencies (into a lib folder below target/appassembler). The assembly plugin can then be used to package the whole appassembler directory to a zip which is installed/deployed along with the jar to the repository.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>generate-jsw-scripts</id>
<phase>package</phase>
<goals>
<goal>generate-daemons</goal>
</goals>
<configuration>
<!--declare the JSW config -->
<daemons>
<daemon>
<id>myApp</id>
<mainClass>name.seller.rich.MyMainClass</mainClass>
<commandLineArguments>
<commandLineArgument>start</commandLineArgument>
</commandLineArguments>
<platforms>
<platform>jsw</platform>
</platforms>
</daemon>
</daemons>
<target>${project.build.directory}/appassembler</target>
</configuration>
</execution>
<execution>
<id>assemble-standalone</id>
<phase>integration-test</phase>
<goals>
<goal>assemble</goal>
</goals>
<configuration>
<programs>
<program>
<mainClass>name.seller.rich.MyMainClass</mainClass>
<!-- the name of the bat/sh files to be generated -->
<name>mymain</name>
</program>
</programs>
<platforms>
<platform>windows</platform>
<platform>unix</platform>
</platforms>
<repositoryLayout>flat</repositoryLayout>
<repositoryName>lib</repositoryName>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-4</version>
<executions>
<execution>
<phase>integration-test</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>src/main/assembly/archive.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
The assembly descriptor (in src/main/assembly) to package the direcotry as a zip would be:
<assembly>
<id>archive</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}/appassembler</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>
If you make your project a war or ear type maven will copy the dependencies.
It's a heavy solution for embedding heavy dependencies, but Maven's Assembly Plugin does the trick for me.
#Rich Seller's answer should work, although for simpler cases you should only need this excerpt from the usage guide:
<project>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
</plugins>
</build>
</project>
You can use the the Shade Plugin to create an uber jar in which you can bundle all your 3rd party dependencies.
Just to spell out what has already been said in brief. I wanted to create an executable JAR file that included my dependencies along with my code. This worked for me:
(1) In the pom, under <build><plugins>, I included:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<archive>
<manifest>
<mainClass>dk.certifikat.oces2.some.package.MyMainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
(2) Running mvn compile assembly:assembly produced the desired my-project-0.1-SNAPSHOT-jar-with-dependencies.jar in the project's target directory.
(3) I ran the JAR with java -jar my-project-0.1-SNAPSHOT-jar-with-dependencies.jar
If you're having problems related to dependencies not appearing in the WEB-INF/lib file when running on a Tomcat server in Eclipse, take a look at this:
ClassNotFoundException DispatcherServlet when launching Tomcat (Maven dependencies not copied to wtpwebapps)
You simply had to add the Maven Dependencies in Project Properties > Deployment Assembly.
You could place a settings.xml file in your project directory with a basic config like this:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>.m2/repository</localRepository>
<interactiveMode/>
<offline/>
<pluginGroups/>
<servers/>
<mirrors/>
<proxies/>
<profiles/>
<activeProfiles/>
</settings>
More information on these settings can be found in the official Maven docs.
Note that the path is resolved relative to the directory where the actual settings file resides in unless you enter an absolute path.
When you execute maven commands you can use the settings file as follows:
mvn -s settings.xml clean install
Side note: I use this in my GitLab CI/CD pipeline in order to being able to cache the maven repository for several jobs so that the dependencies don't need to be downloaded for every job execution. GitLab can only cache files or directories from your project directory and therefore I reference a directory wihtin my project directory.