Building a dependencies jar with Maven - maven

Currently our maven build includes all the dependencies in the jar, using jar-with-dependencies.
We want to split this into two separate jars, one with the project application code and files, and one with the dependencies.
How is this done?
Thanks

This is done using the maven Assembly plugin
http://maven.apache.org/plugins/maven-assembly-plugin/

Use the maven-shade-plugin instead with following configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<configuration>
<finalName>${project.artifactId}-${project.version}-libs</finalName>
<artifactSet>
<excludes>
<exclude>${project.groupId}:${project.artifactId}</exclude>
</excludes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
The trick is to define a specific final name. This avoids the replacement of the default jar, which is packaged by the maven-jar-plugin. The default name is ${project.artifactId}-${project.version}. So simply add a suffix like libs. Then exclude the artifact itself, because the classes should not be packaged twice.
The build will result in two jar files:
${project.artifactId}-${project.version}.jar, containing the classes and files of the project
${project.artifactId}-${project.version}-libs.jar, containing the content of all the dependencies

Related

how to generate additional jar which having correct and complete manifest file for Bamboo deployment?

Basically, I want to generate a jar file named <project.name>.jar in addition to default jar file(which in my case is something like <project.name> + <project.version>.jar). NOTICE : This <project.name>.jar is all the same to default jar but the name.
And this additional jar should have a manifest file like below which is the manifest file of default generated jar
anifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: XXX
Start-Class: com.XXXX.XXX.Application
Spring-Boot-Version: 1.3.1.RELEASE
Created-By: Apache Maven
Build-Jdk: 1.8.0_74
Main-Class: org.springframework.boot.loader.JarLauncher
I am adding additional block in my as follows
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
....
<execution>
<id>copy-jar</id>
<phase>package</phase>
<goals><goal>jar</goal></goals>
<configuration>
<finalName>${project.name}</finalName>
</configuration>
</execution>
<execution>
</plugin>
But in my case, the manifest file generated in my addition jar don't have following impart fields:
Start-Class
Main-Class
...
So it couldn't be deployed.
I know the requirement sounds weird, but the question is clear, how to make maven generate a jar which having a correct and complete manifest file for deployment?
//The complete plugin part
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals><goal>test-jar</goal></goals>
</execution>
<execution>
<id>copy-jar</id>
<phase>package</phase>
<goals><goal>jar</goal></goals>
<configuration>
<finalName>${project.artifactId}</finalName>
</configuration>
</execution>
<execution>
<id>dto-jar</id>
<goals><goal>jar</goal></goals>
<phase>package</phase>
<configuration>
<finalName>${project.artifactId}-dto</finalName>
<includes>
<include>**/dto/*</include>
<include>**/dto</include>
<include>**/exceptions/*</include>
<include>**/exceptions</include>
<include>**/utils/*</include>
<include>**/utils</include>
</includes>
</configuration>
</execution>
</executions>
</plugin>
Concerning your maven-jar-plugin section:
You are having three executions: one for the test-jar goal, two for the jar goal
one of them re-using the default execution id (default-jar) to specify the finalName entry, but not specifying any manifest configuration. According to this configuration, your manifest file should also be empty then, not coherent with the description provided by your question then.
the additional jar goal execution has a further configuration with customizated option, nothing wrong here, except that you except to have a properly filled manifest file as part of it, while (again) there is no configuration for it.
A possible explanation would be that your pom also provides a pluginManagement section, with further configuration for the maven-jar-plugin, or a parent pom at its top which would then specify a further configuration for the same.
To double check this, you could run
mvn help:effective-pom -Doutput=eff-pom.xml
And check the content of the generated eff-pom.xml file. That would be the single source of truth for your case.
Looking at your manifest entry:
Spring-Boot-Version: 1.3.1.RELEASE
Main-Class: org.springframework.boot.loader.JarLauncher
It makes quite clear that you are working on a Spring Boot project, normally having a Spring Boot parent pom which already configures the required manifest file. However, it makes use of a fat-jar (jar with dependencies or uber jar), not built via the maven-jar-plugin but via the maven-assembly-plugin.
As an example:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/jar-with-dependencies.xml</descriptor>
</descriptors>
<archive>
<manifest>
<mainClass>org.springframework.boot.loader.JarLauncher</mainClass>
</manifest>
<manifestEntries>
<Start-Class>org.springframework.boot.load.it.jar.EmbeddedJarStarter</Start-Class>
</manifestEntries>
</archive>
</configuration>
<executions>
<execution>
<id>jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Hence you should not look at the Jar Plugin solution, but rather add a further Assembly Plugin execution for the same.
Just quick share of some other aspects of this problem. actually pom file should never be in charge of deployment business(even though It could, but very likely bring into more issues in the future). This part should be fully managed by bamboo deploy script. That is what I eventually did.

What's the proper way to generate a manifest with DS and maven-bundle-plugin?

I am using today maven-bundle-plugin to generate the manifest of my projects. Due to others constraints, my modules use the "jar" packaging (i can't use the "bundle" packaging), and currently, my pom look like this :
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<executions>
<execution>
<id>bundle-manifest</id>
<phase>process-classes</phase>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
...
</instructions>
</configuration>
</execution>
</executions>
</plugin>
I'd like now to generate a 'Service-Component' header and the DS xml descriptor from my annotated components, but adding "<_dsannotations>*</_dsannotations>" is not working :
Service-Component header is correctly generated, but the xml are not present in the jar
If i rebuild my maven project without a clean goal, then the 'Service-Component' header have duplicates references : After digging in the code, the plugin use the old generated manifest from target/classes/META-INF/MANIFEST.MF and merge it with the new generated one. The 'Service-Component' is then concatened
So, how should i configure my pom for this to work ? For now, i use the 'unpackBundle' option (in order to have the xml in my bundle) and an empty src/main/resource/MANIFEST.MF (in order to bypass the merge of the old manifest) : it looks ugly :-)
Moreover, the 'bnd-maven-plugin' work as intended, but the integration with maven are maybe too light (or not documented?), as 'global configuration' in a parent pom, generation of the Bundle-SymbolicName or Bundle-Name, etc.
Thanks!
There is a newer plugin for maven that is closer to both bnd and maven. This plugin does not take over the jar target and properly follows the maven phases.
Take a look at http://njbartlett.name/2015/03/27/announcing-bnd-maven-plugin.html

Maven exclude only certain files when deploying

Is there a way to exclude files only when calling mvn deploy but have the files included when I call mvn install?
EDIT:
When I run the jar locally I want the logback.xml in src/main/resources but when I deploy it so it's a library the logback.xml should not be included.
It is not the "Maven Way" to have an artifact with different content depending on where it's stored. Maven expects artifact-1.0.jar to be exactly the same in the remote repository and any local repositories.
You could have the project create a classified jar alongside the real jar. The classified jar would include the logback.xml.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<!-- default-jar is the ID assigned to the jar:jar execution included automatically by
Maven. -->
<execution>
<id>default-jar</id>
<configuration>
<!-- not exactly sure of the exact syntax for excludes in the jar plugin -->
<excludes>
<exclude>logback.xml</exclude>
</excludes>
</configuration>
</execution>
<execution>
<id>jar-with-logging</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classifier>logging</classifier> <!-- or whatever -->
</configuration>
</execution>
</executions>
This will create two artifacts, artifact-1.0.jar and artifact-1.0-logging.jar. Both artifacts will end up in both repositories. If you don't want the logging version to be attached (Maven terminology for published to repos), investigate using the maven-assembly-plugin which can create packages in various formats without attaching them.
You could also move the logback.xml into a separate project, package it separately, and add it to the classpath only when you run the jar from the local script.

build dependency on shared JavaScript file

Context:
We use a third-party maven plugin to compile lesscss into css
(lesscss-maven-plugin)
We cannot modify or update this plugin.
We cannot switch to another plugin, use grunt, or any other build
tool.
The plugin allows us to specify a JS file as a workaround to
upgrading the plugin itself.
Currently we have to have a copy of the
file included with each and every project
Question:
How can the JS file be packaged and a build/compile time dependency defined in the POM so that the file can be shared across projects easily?
Is it possible to use a URL for the file path instead of the {project.basedir}?
Example POM Snippet:
<plugin>
<groupId>org.lesscss</groupId>
<artifactId>lesscss-maven-plugin</artifactId>
<version>1.3.0</version>
<configuration>
<sourceDirectory>${project.basedir}/src/main/resources/less</sourceDirectory>
<outputDirectory>${project.basedir}/src/main/webapp/css</outputDirectory>
<compress>true</compress>
<includes>
<include>example.less</include>
</includes>
<lessJs>${project.basedir}/src/main/webapp/lib/less-1.7.0.min.js</lessJs>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>

How to compile resources folder with Maven command

I'm using mvn compile to compile my Maven webapp. This project has a resources folder instead of the java folder created for a .jar project. My problem is that mvn finds no sources, and I haven't find a way in the maven docs to proceed this way. Is there a way, either by mvn command options or by pom.xml modification to make mav aware of the resources folder and compile it?
I know changing the name from resources to java makes the deal, but that's a spureous way to proceed.
To include additional source directories in your project you can use the Build Helper Maven Plugin
So for example the following configuration will add the src/main/resources folder of your project as a source folder.
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/src/main/resource</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Look at your .classpath file. That should have what folders including src and test are added. You can then add additional resources. I would normally use the IDE to look at the build path and add/exclude resources.

Resources