Dynamically add a new maven dependency? - java

I need to add a new maven dependency to my maven project when project is built by the continuous integration server, but the dependency should not be there when developers are building the project locally.
Is there a way to dynamically add the dependency through a maven plugin so that continuous integration plan can run a maven command and add the dependency by itself?

Using profiles is the best way for this kind of case
Here is the example to customize the dependencies inclusion
<profiles>
<profile>
<id>profile-dev</id>
<dependencies>
<dependency>
depednency A
</dependency>
</dependencies>
</profile>
<profile>
<id>profile-prod</id>
<dependencies>
<dependency>
dependency B
</dependency>
</dependencies>
</profile>
<profiles>
To run the build at dev box mvn install -P profile-dev
To run the build at production mvn install -P profile-prod

Related

Multi module project to deliver two different wars

I am working on a multi module Spring MVC project in which one module has to deliver a war with all dependencies and other has to deliver a war with few dependencies excluded. Is this possible? If yes how can I achieve this? The project details are as below:
The structure is:
Parent pom:
<modules>
<web-war-with-all-dependencies>
<web-ear-without-dependencies> --> Only to pack the war into an ear.
</modules>
A shared library is created in Websphere and all dependencies are added there. So, < web-ear-without-dependencies > will be deployed there.
< web-war-with-all-dependencies > will be used to build a docker tomcat image and hosted in a diff environment.
My project has to support both environments. Hence the weird requirement.
Using Maven profiles and by adding some dependencies only in some profile or setting them with scope: provided:
https://www.baeldung.com/maven-profiles
Example:
<profiles>
<profile>
<id>dev</id>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>${testcontainers.version}</version>
</dependency>
</dependencies>
</profile>
<profile>
<id>prod</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<!-- my own library in my private repository which acts like a mock of testcontainers project. Don't ask :-) -->
<dependency>
<groupId>cz.jiripinkas</groupId>
<artifactId>fake-testcontainers</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</profile>
</profiles>
And then you build your project using:
mvn clean install -P dev
This will put inside WAR testcontainers libraries
or:
mvn clean install -P prod
This will put inside WAR fake-testcontainer library

IntelliJ resolve dependencies of profile

I have a Java project with multiple modules. In this project, one module has a dependency to another one, which is only needed for a specific profile and hence is defined like that:
<profile>
<id>myProfile</id>
<dependencies>
<dependency>
<groupId>MyGroupId</groupId>
<!-- ... -->
</dependency>
</dependencies>
<!-- ... -->
</profile>
This works fine when building manually with maven like that:
mvn clean install -P myProfile
When using the IntelliJ build however, the dependency doesn't get resolved.
I've tried the option to delegate IDE build/run actions to maven, adding a property for maven in Build, Execution, Deployment > Build Tools > Maven > Runner (namely -P -> myProfile), and much more which is most likely not of interest.
Is it possible to configure IntelliJ to resolve the dependencies for a specific profile?
To help Intellij Idea to understand about your maven profile and maven object mode, you set as default profile in maven so that by default it will be recognized and run by any IDE. I provide below the code snippet.
<profile>
<id>firstProfile</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
..... Other code goes
</profile>
So inside profile, use this <activeByDefault>true</activeByDefault>. It may solve the problem.

Spring boot using test jars in Intellij

Hello I have a spring boot application that runs fine from command line. However when I run it from the ide (intellij) it fails on every http request. The problem I'm having is that from the ide a test jar (scoped as test in maven) conflicts with the hk2 jar that I have in my app.
I can't exclude hk2 classes from the test jar as it is shaded.
Of course it also happens in my tests. So my question is how do I guarantee that spring boot loads only the production jars and not the test jars. I'm afraid that my Test might no be testing the correct binary.
Having integration tests that executes the compiled application is a solution however I would like to run it from the ide without recompiling the code every time.
The test jar is testcontainers postgres 1.1.5
Thanks
If you are willing to trust testcontainers' hk2 shaded classes, then you could define 2 maven profiles, one for production and one for test which I called hk2test. The production profile (activated by default) includes hk2, while hk2test includes testcontainers. They are mutually exclusive.
Define 2 maven profiles
<profiles>
<profile>
<id>production</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>unit test</id>
<activation>
<property>
<name>hk2test</name>
</property>
</activation>
<dependencies>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
</profiles>
Activate the test profile in Intellij
To use the profile from Intellj, go into the Maven Project view and select the hk2test profile.
Activate the test profile from the command line
$ mvn -Dhk2test test

Maven system scope for testing purposes

I wrote a little framework for testing microservices. Now I packed my contracts into a jar which will be used to test my framework, but i don't want to deploy them to our nexus. so my pom contains
<dependency>
<groupId>mycompany.testframework</groupId>
<artifactId>test.dummy-contract</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/test/resources/contract-dummy.jar</systemPath>
</dependency>
now if i want to use the framework in another project (using gradle) I get this error message:
Processing of C:\Users\dam\.gradle\caches\modules-2\files-2.1\mycompany.testframework\TestFramework\0.0.1-SNAPSHOT\5859a002118d47b4237425d25dfc79ea1d7eb829\TestFramework-0.0.1-SNAPSHOT.pom failed:
'dependencies.dependency.systemPath' for mycompany:test.dummy-contract:jar must specify an absolute path but is ${project.basedir}/src/test/resources/contract-dummy.jar in mycompany.testframework:TestFramework:0.0.1-SNAPSHOT
I need the dependency for my jenkins test and build but not for "delivery". any suggestions?
I resolved it by adding the dependency to a profile wich only will be used for the test-framework and on the jenkins
<profiles>
<profile>
<id>test-dummy</id>
<activation>
<file>
<exists>${project.basedir}/src/test/resources/contract-dummy.jar</exists>
</file>
</activation>
<dependencies>
<dependency>
<groupId>de.company.testframework</groupId>
<artifactId>test.dummy-contract</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/src/test/resources/contract-dummy.jar</systemPath>
<optional>true</optional>
</dependency>
</dependencies>
</profile>
</profiles>

Java - Adding jar dependency in pom.xml

I have never built my java applications by maven. But when i am trying to do that it's giving me error.
I have created JAR file from other java application just by exporting as JAR from that application.
Now i want to add this JAR in my maven application. I don't really how to do that.
this is how i have added in pom.xml. But i don't really know what should be it's artifact id.
Seriously what is artifact id?
<dependency>
<groupId>ProjectZen</groupId>
<artifactId>community</artifactId>
<scope>system</scope>
<version>1</version>
<systemPath>${basedir}\libs\ProjectZen.jar</systemPath>
</dependency>
I am getting below error
Missing artifact ProjectZen:community:jar:1
Thanks
Fahad Mullaji
If it is custom jar you need to do following things
Open cmd and type following command
mvn install:install-file -Dfile=path-to-your-artifact-jar \
-DgroupId=ProjectZen
-DartifactId=community
-Dversion=1
-Dpackaging=jar
-DgeneratePom=true
Now, the “ProjectZen” jar is copied to your Maven local repository.
In pom.xml
<dependency>
<groupId>ProjectZen</groupId>
<artifactId>community</artifactId>
<scope>system</scope>
<version>1</version>
<systemPath>${basedir}\libs\ProjectZen.jar</systemPath>
</dependency>
now the “ProjectZen” jar is able to retrieve from your Maven local repository.
change
<systemPath>${basedir}\libs\ProjectZen.jar</systemPath>
to
<systemPath>${basedir}/libs/ProjectZen.jar</systemPath>
or install it in local maven cache
you should give the format as below. and the slashes used in are incorrect I suppose. Check the dependency in this format.
...
<profiles>
<profile>
<id>default-tools.jar</id>
<activation>
<property>
<name>java.vendor</name>
<value>Sun Microsystems Inc.</value>
</property>
</activation>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.4.2</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</profile>
Reference
...

Categories

Resources