Spring boot using test jars in Intellij - java

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

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.

Dynamically add a new maven dependency?

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

Customised maven deployable (war with some dependencies removed)

I have a multi module web app building with maven. We build the war as per normal and deploy and run on developer machines and local test servers using tomcat.
Then we want to deploy the application to the cloud. To do this we create a special version of tomcat which has all the libraries preloaded and a special version of the war which only has our code. Point here is tomcat is preloaded on the cloud server, the war is uploaded each time it is changed. Currently we are having to manually remove the dependencies from the built war.
What is the best way for maven to do this? Should I build a custom packaging type or maybe run some post build plugin to remove these wars? Or something else? I think the best way to activate this custom build is via a profile. I did try and remove these dependencies by setting them to scope = provided in the new profile but the transitive dependencies still made it into the war.
If you want to exclude all dependencies, you can use the war plugin's packagingExcludes to do so:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.2</version>
<configuration>
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
...
</configuration>
</plugin>
Specify this plugin inside a profile to only perform it for production.
You can achieve using profile in maven. As you said it is not working, I can think of you configure something wrong. Try something like:
<profiles>
<profile>
<id>dev</id>
<activation>
<!-- active by default, turn off when on prod -->
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<!-- include this in dev, not in prod -->
<dependency>
<groupId>com.company</groupId>
<artifactId>xyz</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
Then in command line, mvn package -P !dev to deactivate dev profile so that not include the jars.
Make sure com.company:xzy is not included in <project><dependencies></dependencies></project>.

Maven Dependency error in Eclipse

I have a war artefact and I need use some of their classes from a jar.
I can't move the classes to another project, then I deploy the classes and resources included in my webapp as an "attached" artifact using the following configuration:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.1.1</version>
<configuration>
<attachClasses>true</attachClasses>
</configuration>
</plugin>
This will result in two artifacts being deployed: mywebapp-1.0-SNAPSHOT.war and mywebapp-1.0-SNAPSHOT-classes.jar.
To use those classes I Referencing the artifact as follows:
<dependency>
<groupId>mygroup</groupId>
<artifactId>mywebapp</artifactId>
<version>${project.version}</version>
<classifier>classes</classifier>
</dependency>
When I compiled from Jenkins everything works correctly, but when I run the tests locally from Eclipse can not find the reference classes. (java.lang.NoClassDefFoundError)
I think it might be a bug in the maven eclipse plugin, someone has any idea that can be happening?
Workaround is described on http://wiki.eclipse.org/M2E-WTP_FAQ:
A workaround exists though, we need to change the dependency whether the project is built in Eclipse or not. In your dependent project, you can configure the following :
<dependencies>
...
<dependency>
<groupId>com.company</groupId>
<artifactId>mywebapp</artifactId>
<version>1.0.0-SNAPSHOT</version>
<classifier>${webClassifier}</classifier>
</dependency>
...
</dependencies>
...
<properties>
...
<webClassifier>classes</webClassifier>
</properties>
...
<profiles>
<profile>
<id>m2e</id>
<activation>
<property>
<name>m2e.version</name>
</property>
</activation>
<properties>
<webClassifier></webClassifier>
</properties>
</profile>
</profiles>
The m2e profile is automatically activated when the project is built with m2e, ignored in other circumstances. In that case only, the dependent project will use an empty classifier to reference the web project, which will be added to the classpath as expected.
My simple answer is the following link to the bug tracking system of Eclipse:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=365419
See the answers inside.
Yes it's a problem with Eclipse itself..
The solution within Eclipse just add the project manually within your workspace to the appropriate project where you need the classes out of your war project.

Categories

Resources