I have Java Maven project in Eclipse. Sometimes I need to copy binary with all libraries and configuration files to live system. Is it right place to ask Maven about it?
Should I use package goal for this reason. Should I use any plugin? Where I should define remote system sftp logins and paths?
For building a .jar with all dependencies and a main-class attribute, you can use the maven plugin maven-assembly-plugin
You can use it like this in your pom-file:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>package.mainClass</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<goals>
<goal>single</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
</plugin>
Inside the <build> and plugins of course :)
See How to Create an Executable JAR with Maven with pros & cons for the different options:
Manual Configuration
Apache Maven Assembly Plugin
Apache Maven Shade Plugin
One Jar Maven Plugin
Spring Boot Maven Plugin
Web Application with Executable Tomcat
Use the Wagon Maven Plugin to copy/upload the so created "executable" JAR wherever you want.
Related
I have a Maven project with a number of sub modules. Some of these sub modules are packaged as jar that are deployed to a Nexus Maven repository.
The problem I have is that the packaged jar references the parent pom which is not necessarily deployed.
Is there a way for Maven to deploy the effective pom instead of the pom.xml?
You need to be perfectly aware of the consequences of what you want to do: the effective POM will also contain your current settings (content of settings.xml), thereby possibly publicly exposing whatever passwords you have hard-coded in there. A better solution would be just to deploy the parent POM.
However, if you really want to go down that path, you can have the following configuration:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<addMavenDescriptor>false</addMavenDescriptor>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-help-plugin</artifactId>
<version>2.1.1</version>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>effective-pom</goal>
</goals>
<configuration>
<output>${project.build.outputDirectory}/META-INF/maven/${project.groupId}/${project.artifactId}/pom.xml</output>
</configuration>
</execution>
</executions>
</plugin>
This tells the maven-jar-plugin not to add the Maven descriptor pom.xml and pom.properties to the jar. Instead, the pom.xml is generated by the maven-help-plugin and its effective-pom goal.
If you want the pom.properties file also, you will need to create it manually with the maven-antrun-plugin.
I've a simple program build in IntelliJ and using maven that uses the dependency io.netty. I've added to my POM file:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.0.Beta1</version>
</dependency>
In order to compile and get a jar file I usually do:
Clean
Compile
Package
However I noticed that the dependency is not added to the jar, neither existing in the target folder (Or in any of it's sub folders) or added to the resources folder like usually happens.
In order to have the io.netty library to be added to the jar I have tried:
Setting the scope to provided and to compile.
Re-importing the pom file.
Deleting io.netty folder in the .m2/repository/ folder.
I have several other libraries linked including:
mysql-connector-java
slf4j-simple
trove4j
Thanks for reading.
For some odd reason I had changed my maven configuration a while ago. While I had not added any new libraries, the old ones still had their classes laying around therefor still being added to the jar.
I solved this issue by changing the build in my pom to:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>com.domain.Program</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
Used as reference: http://mkyong.com/maven/create-a-fat-jar-file-maven-assembly-plugin/
Maven doesn't package all dependencies into a jar by default. You can use the assembly plugin to build a "jar with dependencies, as seen here:
How can I create an executable JAR with dependencies using Maven?
This question already has answers here:
Generate test-jar along with jar file in test package
(2 answers)
Closed 8 years ago.
I have maven project with main and test subfolders under folder src.
However, when I build maven jar, I dont see test files in jar file (I do see files that were there in src/main; I dont see test files from src/test)
[xx#localhost target]$ jar tvf cbm.jar | grep *Test*
[xx#localhost target]$
Here is my pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<!-- https://maven.apache.org/plugins/maven-assembly-plugin/examples/index.html -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>Main</mainClass>
</manifest>
</archive>
<finalName>afloat</finalName>
<appendAssemblyId>false</appendAssemblyId>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
EDIT
#azurefrog: I am having issues in production and need to run the test cases on production machine.
It is normal behavior. Maven crate jar from src (only production code).
If you want add test .class to jar you have to create your own maven plugin.
Check this
Guide for maven plugin development
Maven does not package test classes. What you would have to do is copy the maven project to the production machine and run mvn test from that machine.
The reason Maven behaves like this is that everything under src/test is not supposed to be used in production. It's test code, resources, etc. One common use of this is to put configuration files under src/test/resources such as Spring context files. If these files made it into the official jar file, it would be very bad in many, many cases.
That said, what you can do if you want to run test code is follow this process:
Build a maven project that uses this one as a dependency.
Write a some test code, either as JUnit with a standalone JUnit runner, or a simple class with a main method.
Use the Maven assembly plugin to generate a jar that has all dependencies in it. This GitHub project of mine uses the assembly plugin to build an uberjar for a groovy script.
I'm trying to create automated solution for building with maven. My vision is to have a Maven build, which creates JAR file from my project and then just copies all the dependencies as JARs to some sub-directory in "target" folder.
I do not want to use Shade or Assembly (so I do not want to extract the content of other JARs and include it in one "super-JAR", because the project is more complicated and it breaks when I'm including all the JARs in one file).
How can I do such build POM?
I don't see here any problem. Just create maven pom.xml with <packaging>jar</packaging>
By default it should not pack into your jar all dependent libraries.
<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>
Related with your latest comment, use this plugin to add the main class in the manifest:
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.test.YourMainClass</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
You can use the maven-assembly-plugin to create a .zip file from a selection of other files in your directory. I have used this method to create distribution zip files for a project. There are several examples available in the maven-assembly-plugin documentation.
I can deploy a jar by using the following in my pom.xml and running mvn deploy:
<distributionManagement>
<repository>
<id>releases</id>
<url>http://${host}:8081/nexus/content/repositories/releases</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<name>Internal Snapshots</name>
<url>http://${host}:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
And I can build an executable jar-with-dependencies using the following:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<id>create-executable-jar</id>
<phase>deploy</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass>my.company.app.Main</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
Problem is I don't know how to stitch these together to deploy the executable jar to my Maven repo. I don't really know if this is accomplished by a new plugin or by adding a goal or other step to the existing assembly plugin.
If you bind the assembly to the packaging phase, it will install in your repository both the "regular" jar and the with-dependencies jar when you do a build:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>my.company.app.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Then simply run mvn clean install deploy to upload both jars to your repository.
In order to build a (so-called) Über JAR and deploy it using maven, you could also use the shade plugin. The following code is taken from their website but I've made one or two projects using this feature.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jackofall</shadedClassifierName> <!-- Any name that makes sense -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
In this configuration you get the Über JAR as one deployment besides the normal JAR. The user of your JAR can then decide to pull the all-in-one package or the JAR with dependencies based on the classifier.
I'll usually use the shade plugin to build Über JARs (or modify the JAR in a way) and use the assembly plugin to build things like installation packages (containing the JAR and possibly other things). I am unsure what the intended goals of the single plugins are however.
The following worked. I'm going to leave this question open a bit because I'm not positive this is best practice, but working is something.
Problems I notice are that I made up the ID name and I don't know if this is usual practice and that I have to hard code the jar name; it isn't inferred from anything else.
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>deploy-executable</id>
<goals>
<goal>deploy-file</goal>
</goals>
<configuration>
<file>target/Monitoring-Client-1.0-SNAPSHOT-jar-with-dependencies.jar</file>
</configuration>
</execution>
</executions>
</plugin>
Essentially my difficulty doing this revealed the fact that my pom.xml was way off the rails already. Everything would have snapped into place on its own. I was formerly doing:
Save all the dependencies into a lib folder
Build a jar with a classpath slurping up that lib folder
Use the assembly plugin to make another deployable jar
I think there were several reasons this sort of made sense along the way, especially when my libraries were not well-factored from my applications.
However by deleting 1 and 2 all that is needed is the distributionManagement section and the deploy phase works automagically. So all in all this is an amazing case of literally adding functionality by deleting large swathes of code.
First you shouldn't do the creation of the ueber jar in the deploy phase it's better to do this in the package phase. Furthermore the created jar file is usually automatically attached to your artifact and will be transfered to the remote repository (in your case Nexus). You can check this if you simply try to do a mvn install and take a look at the output if the created jar is installed into the local repository.
To deploy the results into nexus you need to call mvn deploy.