Maven copy only specific dependencies - java

I'm developping an OSGI email client with Maven following component-based software engineering. I must make sure that the dependencies between all my components are resolved inside of the OSGI container, so I cannot copy the dependencies inside the generated JARs, otherwise there would be no point using OSGI. But there is one dependency I really have to copy inside of the JAR, it's javax.mail, because I cannot find any OSGI-compatible bundle that does emailing.
To do that, I have seen this page: https://maven.apache.org/plugins/maven-dependency-plugin/examples/copying-artifacts.html
So I edited my pom.xml:
<project>
...
<build>
<plugins>
<plugin> <!-- to edit the MANIFEST.MF, required for OSGI -->
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>4.2.1</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Class-Path>lib/</Class-Path>
... OSGI instructions ...
</instructions>
</configuration>
</plugin>
<plugin> <!-- to copy the dependencies -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.6.2</version>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
But the <artifactItems> tag doesn't seem to work. When I mvn install, it copies ALL the dependencies into a dependency/ folder and not a lib/ folder. How can I do to copy only the javax.mail JAR into a folder named lib/?
Thank you for your help.

The maven-bundle-plugin allows to embed dependencies:
https://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html
<Embed-Dependency>javax.mail|javax.mail-api</Embed-Dependency>

You mixed up the goals copy-dependencies and copy. Replace copy-dependencies by copy.
http://maven.apache.org/plugins/maven-dependency-plugin/copy-mojo.html

Related

Spring Boot Layered jar: Extract layers.xml to separate dependency

I'm starting to catch up on the capabilities of the repackage goal in spring-boot-maven-plugin.It looks promising, but I need to fine-tune it a little.
I can easily do that by creating a layers.xml file somewhere in my project, but the problem is that I don't only have 1 project, but rather half a dozen. All of the projects need the same kind of layering, but I don't really want to copy the same configuration for every project I want to use it on.
A nice-looking solution would be to extract that configuration file into a separate jar for example and have the plugin take the config file from there, but I see no way of doing it. Is there any other solution that doesn't involve me copying the configuration file to every project I have?
Unfortunately, even though the projects I have use the same parent, but are not in the same multi-module project.
I managed to work out a solution.
Before asking the question my spring-boot-mave-plugin config looked something like this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
<phase>package</phase>
<configuration>
<layers>
<enabled>true</enabled>
<configuration><!-- something like classpath:layers.xml --></configuration>
</layers>
<classifier>exec</classifier>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>artifact</groupId>
<artifactId>with-layers.xml</artifactId>
<version>...</version>
</dependency>
</dependencies>
</plugin>
The solution becomes one step more convoluted, by bringing in the maven-dependency-plugin, which downloads the before mentioned dependency and unpacks it in the build folder with this configuration:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<id>copy-shc-build-tools</id>
<goals>
<goal>unpack</goal>
</goals>
<phase>package</phase>
<configuration>
<artifactItems>
<artifactItem>
<groupId>artifact</groupId>
<artifactId>with-layers.xml</artifactId>
<version>...</version>
<type>jar</type>
<outputDirectory>${project.build.directory}</outputDirectory>
<includes>**/layers.xml</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
<configuration>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</plugin>
In turn, the line <configuration><!-- something like classpath:layers.xml --></configuration> becomes <configuration>${project.build.directory}/layers/layers.xml</configuration>.
The documentation for Spring Boot Maven Plugin states you can set the path to the layers.xml manually, so why not have all pom.xml point to the same location?
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.2.RELEASE</version>
<configuration>
<layers>
<enabled>true</enabled>
<configuration>${project.basedir}/../layers.xml</configuration>
</layers>
</configuration>
</plugin>
</plugins>
</build>
</project>
The /../ means one level higher from the project directory. So say you have a bunch of projects in one directory, put the layers.xml there and it'll work.
Another approach could be to reuse the Maven Plugin declaration by moving it to a so-called parent POM. This is a technique where the common/shared parts of the POM files of a series of projects is moved to a single POM file (the parent POM). Here's an example

How can I get class files from Maven dependency into the target\classes folder

Is there any sort of Maven plugin that allows me to copy the class files for a dependency into the target\classes folder for my project? Currently I have to manually open the jar file that has the dependencies extract the package that I need to copy over and then copy it into the target\class folder for my project.
I need a way to do those ideally within the pom.xml file but I haven't been able to find a solution that works. Any help would be appreciated, Thanks.
This sounds like a terrible idea. If you want to include unpacked dependencies into your project, use the maven assembly plugin or the maven shade plugin.
Use the maven-dependency-plugin. Here is an example of how you can extract the content of a dependency JAR:
<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.1.2</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
<includes>**/*.class,**/*.xml</includes>
<excludes>**/*test.class</excludes>
</artifactItem>
</artifactItems>
<includes>**/*.java</includes>
<excludes>**/*.properties</excludes>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>
below is the example to use of assembly pulgin and it works for me
below is the child pom plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<archive>
<manifest>
<mainClass>my parent package statup class</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
Parent pom plugin
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>

How to unjar, and edit source and jar it back using maven?

I have a situation where i need to Unpack a spring jar and replace a file in that package with my .class file and repackage it back as jar. I understood that this can be done in Maven. So i created a maven project and i added the .java(to be replace in the Spring jar) to it . Here is my Project structure.
here is my pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<name>repackage</name>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.4.6</version>
<packaging>pom</packaging>
<build>
<plugins>
<!-- Unpacking -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6.SEC03</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>target</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<!-- Packing -->
<!-- <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
<configuration>
<classesDirectory>target</classesDirectory>
<classifier>sample</classifier>
</configuration>
</execution>
</executions>
</plugin>-->
</plugins>
</build>
</project>
I am able to unpack the spring jar using maven dependency plugin and i figured out how to pack it back to a jar using maven-jar-plugin. The part i am struggling to understand 1) how convert my .java file into a .class file. As the packaging is pom type <packaging>pom</packaging> I am not able to compile the java file(JdkVersion.java). if successful in creating the class file 2) How to replace this .class file into unpacked spring jar as the file i need to replace is inside the sub directory of /springpackage
You don't have to. Spring is an open source project just clone its source code https://github.com/spring-projects/spring-framework?files=1 and update the code and create a package using simple mvn package command

Unpack Maven dependency into classes, keeping transitive dependencies

I am trying to unpack a maven dependency jar's contents into my classes folder, and at the same time include the transitive dependencies. I also don't want to unpack all of my project's dependencies. Only one would be good, even better if I could do this to a list of them. Found similar solutions but nothing addressing my exact issue.
Example Main Project Pom:
.
.
.
<dependencies>
<dependency>
<groupId>com.test.dep</groupId>
<artifact>first-dependency</artifact>
</dependency>
<dependency>
<groupId>com.test.dep</groupId>
<artifact>second-dependency</artifact>
</dependency>
</dependencies>
.
.
.
Example second-dependency Pom:
.
.
.
<dependencies>
<dependency>
<groupId>com.test.dep</groupId>
<artifact>third-dependency</artifact>
</dependency>
<dependency>
<groupId>com.test.dep</groupId>
<artifact>fourth-dependency</artifact>
</dependency>
</dependencies>
.
.
.
I want second-dependency to be unpacked into my classes folder nested under target and also want any of the artifacts (third-dependency, fourth-dependency) it depends on to still be included in my lib folder (not unpacked).
I tried the following (without including the the artifact in my dependencies):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.test.dep</groupId>
<artifactId>second-dependency</artifactId>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<includes>**/*</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
And this did include the contents of second-dependency in my classes folder, but did not include third-dependency or fourth-dependency in my main projects lib directory.
Any ideas?
Try to use following plugin configuration, based on the described parameters of dependency:unpack-dependencies, instead:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<includeArtifactIds>second-dependency</includeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
Im not sure about your use case.
But if you want to build jar, that sounds like a use case for the maven-shade-plugin. This plugin is able to package the classes and resources of the project itself as well as of a specified set of artifacts (dependencies) into one jar.
Just define the artifact itself ("${project.groupId}:${project.artifactId}") and the "second dependency" to be included.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<configuration>
<artifactSet>
<includes>
<include>${project.groupId}:${project.artifactId}</include>
<include>com.test.dep:second-dependency</include>
</includes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>

How to move (or copy) a war's jar to another war's folder?

I have maven prj with 2 modules: a JAR and a WAR that depends on the JAR.
after the MAVEN INSTALL I have into a WAR the classic WEB-INF/lib folder that contains all the jar dependencies(including the first module's JAR).
I need the first module's JAR is moved to another folder, for example WEB-INF/resources.
as I can?
I was able to move the jar but only within the TARGET, the WAR remains the same.
I used the following plugin:
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>copy-installed</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>1.0</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/.../WEB-INF/services</outputDirectory>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/.../WEB-INF/services</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
For now, I surrendered.
I could not move this JAR from WEB-INF/lib to WEB-INF/services of the EAR.
The workaround I used is to say MODULE1 to copy its JAR in the WEB-INF/services of MODULE2. Consequently, the JAR will be present in the WEB-INF/services of the sources folders, in the WEB-INF/services of the TARGET folders and in the end in the WEB-INF/services of the EAR.
i used:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.5</version>
<configuration>
<outputDirectory>..MOSULE1/src/main/webbapp/WEB-INF/services</outputDirectory>
</configuration>
</plugin>
</plugins>
into MODULE1 pom.
I had to give up to make module1 independent module2 ;(
i hope i will found a clean solution..
Maybe this will help:
<project.warSourceDirectory>${basedir}/src/main/webapp</project.warSourceDirectory>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>copy-installed</id>
<phase>install</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>groupId</groupId>
<artifactId>artifactId</artifactId>
<version>1.0</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.warSourceDirectory}/WEB-INF/services</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>

Categories