Maven: add dependecy also with a specific profile - java

I have 3 projects:
myLibProject: has 2 profiles, "profileOne" and "profileTwo": each profile compile a different jar.
myFirstProject: has the jar compiled by myLibProject with "profileOne" as dependecy
mySecondProject: has the jar compiled by myLibProject with "profileTwo" as dependecy.
It's possible to add myLibProject with a custom profile as depedency?
myLibProject fragment profile: (it's just a sample)
<profiles>
<profile>
<id>profileOne</id>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*prop*</exclude>
</excludes>
<finalName>jarFromProfileOne-${project.version}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>compimpl</id>
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/*.sql</exclude>
</excludes>
<finalName>jarFromProfileTwo-${project.version}</finalName>
</configuration>
</plugin>
</plugins>
</build>
</profile>
myFirstProject has as depency
<dependency>
<groupId>com.mywebsite</groupId>
<artifactId>myLibProject</artifactId>
<version>1.0.0</version>
<type>pom</type>
<with-profile>profileOne</with-profile>
</dependency>
mySecondProject has as depency
<dependency>
<groupId>com.mywebsite</groupId>
<artifactId>myLibProject</artifactId>
<version>1.0.0</version>
<type>pom</type>
<with-profile>profileTwo</with-profile>
</dependency>
how can I achieve this result? Of course i know "with-profile" does not exists as option.
I need 2 different jars because Documentum's requirment, I know Maven it's created to make a single jar... so I can't use envirnment vars or scope.
Maven 3.0.1

Related

Include JDBC driver for Postgres in the JAR fo my simple demo app driven by Maven [duplicate]

This question already has answers here:
How can I create an executable/runnable JAR with dependencies using Maven?
(33 answers)
Closed 3 years ago.
How to make Maven include the JDBC driver for Postgres inside my app's .jar file?
I added this dependency element to the <dependencies> element in my POM.
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.8</version>
</dependency>
The IntelliJ IDE shows the driver was successfully downloaded, as it is listed in the "External Libraries" item of my Project pane. And my code can use the JDBC classes such as PGSimpleDataSource.
When I build, if I look inside the resulting .jar file, there is no JDBC driver included.
My project is driven by Maven, using the maven-archetype-quickstart archetype. I did update all the version numbers within the POM to the latest. My only other change was to add the following to get the manifest file of the JAR to specify a main class.
<configuration>
<archive>
<manifest>
<mainClass>work.basil.example.App</mainClass>
</manifest>
</archive>
</configuration>
I thought that Maven by default would bundle all dependencies inside the resulting JAR file. That is the behavior I have seen in building Vaadin web apps. Is that not the case more generally? Or is the JDBC driver special and being omitted for some reason.
If it helps, here is the entire POM.
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>tryjdbc</artifactId>
<version>1.0-SNAPSHOT</version>
<name>tryjdbc</name>
<description>A simple tryjdbc.</description>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>13</maven.compiler.source>
<maven.compiler.target>13</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.6.0-M1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.8</version>
</dependency>
</dependencies>
<build>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.8.2</version>
</plugin>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifest>
<mainClass>work.basil.example.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</project>
The .war files, such as those you saw in building Vaadin web apps, do include dependencies by default.
In contrast, the .jar files built by Maven do not include any dependencies by default.
You can use a plugin such as maven-shade-plugin to create a shaded jar, which does include the dependencies:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<!-- put your configurations here -->
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Further examples can be found on the Apache Maven Shade Plugin project page.

Is it possible to exclude (or include) classes or resources on a per profile basis in Maven?

I have two maven profiles P1 and P2 and what I want to do is that depending on the profile I use to build my project, certain resources should be excluded.
For example
<profiles>
<profile>
<id>P1</id>
<properties>
<app.home>Path to project home</app.home>
<exclude>src/main/java/foo/*.*</exclude> <!-- need to exclude all files in src/main/java/foo in this profile -->
</properties>
</profile>
<profile>
<id>P2</id>
<properties>
<app.home>Path to project home</app.home>
<exclude>src/main/java/bar/*.*</exclude> <!-- need to exclude all files in src/main/java/bar in this profile-->
</properties>
</profile>
</profiles>
So, here what I want to do is to exclude all files in src/main/java/foo/ when I build using the P1 profile and exclude all files in src/main/java/bar when I build using the P2 profile.
Is this possible and if not is there any alternative?
You can add a build with the Maven Compiler Plugin to your profile and add a exclude in there
E.g.
<profile>
<id>P1</id>
<properties>
<app.home>Path to project home</app.home>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>**src/main/java/foo/*.*</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
See for additional information Maven: excluding java files in compilation
If you are using spring boot maven plugin, use should do it like this:
<profiles>
<profile>
<id>sample-profile</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>com/example/foo/ToSkip.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</profile>
</profiles>
This would do below. For more details, see: https://maven.apache.org/plugins/maven-resources-plugin/examples/include-exclude.html
<project>
...
<name>My Resources Plugin Practice Project</name>
...
<build>
...
<resources>
<resource>
<directory>src/my-resources</directory>
<excludes>
<exclude>**/*.bmp</exclude>
<exclude>**/*.jpg</exclude>
<exclude>**/*.jpeg</exclude>
<exclude>**/*.gif</exclude>
</excludes>
</resource>
...
</resources>
...
</build>
...
</project>

Maven classifier empty jars

Assume we have multimodule maven project:
parent
|-module-a-jar
|-module-b-jar
|-web-module-c-war
There is common classified specified for parent pom.xml:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<classifier>${my.project.classifier}</classifier>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<classifier>${my.project.classifier}</classifier>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Assume that I build project using
mvn clean package -Dmy.project.classifier=NIGHTLY
After building web-module-c-war contains empty folders instead of jar files:
web-module-c-war
|-WEB-INF
|-lib
|-module-a-jar
|-module-a-jar
Can you please advise how to fix this? Why this is happening?
If I remove classifier from maven-jar-plugin configuration it seems to be working fine.
Thanks
why not just make this?
pom web-module-c-war :
<groupId>xxxxx</groupId>
<artifactId>xxxx</artifactId>
<version>1.0.0-SNAPSHOT</version>
<classifier>${my.project.classifier}</classifier>
..
..
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module-a-jar</artifactId>
<version>${project.version}</version>
<classifier>${my.project.classifier}</classifier>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>module-b-jar</artifactId>
<version>${project.version}</version>
<classifier>${my.project.classifier}</classifier>
</dependency>

Maven Surefire: Running tests in specified dependencies

I have a project that includes multiple other jar artifacts as dependencies. I'm using the surefire plugin's dependenciesToScan property to run tests in the said artifacts as follows:
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<dependenciesToScan>
<dependency>com.example.tests:project-a</dependency>
<dependency>com.example.tests:project-b</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.example.tests</groupId>
<artifactId>project-a</artifactId>
</dependency>
<dependency>
<groupId>com.example.tests</groupId>
<artifactId>project-b</artifactId>
</dependency>
</dependencies>
Ideally, I would like to be able to do the following:
mvn test would run the tests in each dependency like normal
Another parameter would run only the tests for whichever artifact is specified and skip the tests for whatever dependency was not included
Is this possible at all or is there another way to approach this?
You can use profiles to have two distinct builds.
<profiles>
<profile>
<id>project-a</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<dependenciesToScan>
<dependency>com.example.tests:project-a</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>project-b</id>
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<dependenciesToScan>
<dependency>com.example.tests:project-b</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The use mvn clean test -P project-a or mvn clean test -P project-b
You could also set different properties in each profiles and have a centralized surefire config.
Or you could use a property:
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<dependenciesToScan>
<dependency>${someProperty}</dependency>
</dependenciesToScan>
</configuration>
</plugin>
</plugins>
</build>
The use mvn clean test -DsomeProperty=project-a

Maven: Development and Release versions for Libraries

I have a project consisting of 3 libraries - let's call them 1) BABY, 2) CHILD and 3) ADULT. Lib "CHILD" depends on "BABY" and "ADULT" depends on "CHILD".
What I want to do is produce:
a dev version that has all the (transitive) dependencies
a production version that creates a standalone JAR for each library (embedding the dependencies)
I have a profile dev and a profile release already, and I know how to use ProGuard to generate the JAR.
The question is how to tell Maven to keep all dependencies in dev and ignore them (optional/provided) in production?
To have different dependencies when you develop to deployment you could use maven profiles.
http://maven.apache.org/guides/introduction/introduction-to-profiles.html
So when developing you would use something like mvn -Pdev compile
When you say "standalone jar" it sounds like you mean a jar with all dependencies merged into it.
How can I create an executable JAR with dependencies using Maven?
or http://maven.apache.org/plugins/maven-assembly-plugin/
Here is what I used eventually:
The parent POM defines a profile release that configurates the proguard plugin (crates one big JAR) and the install plugin (places the release artifact in the repo).
The lib-baby POM simply calls the 2 plugins in the <build> section.
The lib-child POM additionally specifies a dev profile where the dependency to lib-baby is defined. Within the release profile this dependency has an optional tag and is included in the big JAR.
In the end when run by default, the libs com.company.dev:lib-baby and com.company.dev:lib-child are created (included their dependencies).
When run with -Prelease the libs com.company:lib-baby and com.company:lib-child are created (standalone libs [WITHOUT any dependencies]) - only side effect is that the default artifacts (.*dev) are overwritten :(
parent:
<project>
<groupId>com.company</groupId>
<artifactId>lib-parent</artifactId>
<packaging>pom</packaging>
<modules>
<module>lib-baby</module>
<module>lib-child</module>
<module>lib-adult</module>
</modules>
<profiles>
<profile>
<id>release</id>
<activation>
<property>
<name>release</name>
</property>
</activation>
<build>
<pluginManagement>
<plugins>
<!-- aggregate to one big jar -->
<plugin>
<groupId>com.pyx4me</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<executions>
...
</executions>
<configuration>
<injar>${project.build.finalName}.jar</injar>
<outjar>${project.build.finalName}-release.jar</outjar>
....
</configuration>
</plugin>
<!-- install release version of artifact separately (under com.company) -->
<plugin>
<inherited>true</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-release</id>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>
target/${project.build.finalName}-release.jar
</file>
<groupId>com.company</groupId>
...
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</profile>
</profiles>
</project>
lib-baby:
<project>
<groupId>com.company.dev</groupId>
<artifactId>lib-baby</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.company</groupId>
<artifactId>lib-parent</artifactId>
</parent>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<!-- produces 'lib-baby-release.jar -->
<plugin>
<groupId>com.pyx4me</groupId>
<artifactId>proguard-maven-plugin</artifactId>
</plugin>
<!-- installs 'lib-baby-release.jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-release</id>
<phase>install</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
lib-child:
<project>
<groupId>com.company.dev</groupId>
<artifactId>lib-child</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.company</groupId>
<artifactId>lib-parent</artifactId>
</parent>
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>com.company.dev</groupId>
<artifactId>lib-baby</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>release</id>
<dependencies>
<dependency>
<groupId>com.company.dev</groupId>
<artifactId>lib-baby</artifactId>
<version>1.0</version>
<!-- made optional because will be embedded in standalone jar -->
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!-- produces 'lib-child-release.jar -->
<plugin>
<groupId>com.pyx4me</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<configuration>
<assembly>
<inclusions>
<inclusion>
<groupId>com.company.dev</groupId>
<artifactId>lib-baby</artifactId>
</inclusion>
</inclusions>
</assembly>
</configuration>
</plugin>
<!-- installs 'lib-child-release.jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>install-release</id>
<phase>install</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

Categories

Resources