Intellij is ignoring Maven settings [duplicate] - maven

I am trying to run tests in Intellij which used to work earlier in spring boot 2.2.x. I recently upgraded to spring boot 2.3.9. When I try to run the test from Run Configurations, it doesn't run the test and throws the error:
'failed to resolve junit platform launcher 1.6.3 intellij'.
However if I run the test in cli, it works fine.

It turns out that, junit5-platform-launcher dependency needs to be added in order for Junit5 tests to run in IntelliJ.
https://youtrack.jetbrains.com/issue/IDEA-231927?_ga=2.5997872.2063517257.1613993298-1098513328.1597974168
https://junit.org/junit5/docs/current/user-guide/#running-tests-ide-intellij-idea
Add this dependency explicitly in pom.xml, and it will solve the issue.
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>

I was facing same issue "failed to resolve junit platform launcher 1.8.1" intellij.
IntellJ version: 2021.3
I found answer here and it worked, no need to add any dependency to pom.
Go to settings >> HTTP Proxy >> choose auto-detect proxy settings

For IntelliJ Idea 2021.1, I fixed a similar problem with:
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
Maybe an even better fix is:
<dependencyManagement>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.junit/junit-bom -->
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.7.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Found the above solution on Jetbrains issue tracker

If you have no direct internet connection but a repository manager like artifactory, idea tries to resolve junit-platform-launcher from there. Make sure u have a mirror to maven central repository (virtual repository) configured and the artifactory url to this mirror is accessible WITHOUT authentication (in the settings for the repo "Force Authentication" should be unchecked).
Check also the idea proxy settings and if needed, configure an exception for the artifactory domain.

Check your proxy settings in IntelliJ Idea settings. I turned ON the proxy and it solved the problem.

Here's the official way to do this
Maven Surefire and Maven Failsafe can run JUnit 4 based tests
alongside Jupiter tests as long as you configure test scoped
dependencies on JUnit 4 and the JUnit Vintage TestEngine
implementation similar to the following.
<!-- ... -->
<build>
<plugins>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
<!-- ... -->
<dependencies>
<!-- ... -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.7.2</version>
<scope>test</scope>
</dependency>
<!-- ... -->
</dependencies>
<!-- ... -->

Related

How should I perform integration testing on a SpringBoot library, that isn't an application

First up, a disclaimer, I'm not entirely happy with the architecture of what I'm about to ask about!
We have a Spring based project that produces a library as a jar. That library includes all the usual controller/service/jpa (repositories) layers you might expect but no boot application to start it all up.
The idea being various projects within our organisation can import the jar and get instant addition of a common (HTTP) API.
Unit tests work ok.
*IT.java tests are another matter.
Run in isolation by the IDE from the test/java/ hierarchy they run ok and pass.
However when running via maven as part of the build they fail.
[ERROR] ControllerIT » IllegalState Unable to find a #SpringBootConfiguration...
We have a Boot configuration in the test hierarchy which the ITs must be using when run via the IDE, but when running the maven build it seems it can't be found to start up the application (understandably as it is in the test package tree).
The boot file we do have is intended to be no more than a test harness to run the lib, to run the ITs.
We have h2 in the Maven test scope, but it isn't wanted in the final library (that is up to the host application to provide a datasource/connection etc).
Requirement:
Start up the API library in an application for testing
Run the tests as part of Maven build
H2 should not end up in final jar
Symptoms when running mvn install
[ERROR] ControllerIT » IllegalState Unable to find a #SpringBootConfiguration...
Presumably need some config somewhere in pom? Already using package.Boot in the Springboot maven plugin config.
Maybe just need to figure out the magic config to point it at the src/test/... Boot.class rather than src/main/...Boot.class
Question(s):
Does spring have a 'correct' way to achieve what we want (I'd go with MicroServices, but not an option because ... reasons)?
How should we go about implementing ITs against a H2 driven SpringBoot application when we don't want to include the bootable class (or H2 lib) in product jar?
Should we be creating a separate Maven module just for the ITs (with a dependency on the library module)?
Abbreviated Maven pom:
<properties>
<version.spring-boot>2.1.13.RELEASE</version.spring-boot>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${version.spring-boot}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.28.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.28.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.0</version>
<type>pom</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- other dependencies excluded for brevity -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${version.spring-boot}</version>
<configuration>
<!-- file lives in test hierarchy -->
<mainClass>org.my.packages.test.Boot</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<skip>true</skip><!-- Skipping unit tests while trying to sort ITs -->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>3.0.0-M5</version>
<configuration>
<failIfNoTests>true</failIfNoTests>
</configuration>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</execution>
</plugin>
</plugins>
</build>
The Spring Boot config:
#SpringBootApplication()
public class Boot extends SpringBootServletInitializer
{
public static void main(String[] args)
{
SpringApplication.run(Boot.class, args);
}
}
IT configuration:
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ControllerIT
{
#Autowired
private TestRestTemplate restTemplate;
...
}
Number 2 lead me to looking into params of #SpringBootTest.
I ended up with ...
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = ITConfig.class)
Where ITConfig is:
#SpringBootApplication()
public class ITConfig extends SpringBootServletInitializer
{
public static void main(String[] args)
{
SpringApplication.run(org.lhasalimited.libraries.ITConfig.class, args);
}
}
That appears to be working. Thanks for the hint.
Let me propose one way of solving this issue, there are might be others:
#SpringBootTest annotation is intended to mimic the startup of the full fledged spring boot application.
It scans the packages up to the point where it finds #SpringBootConfiguration annotataion (this annotation is placed on #SpringBootApplication already) and this way it understands that the packages down to the package in which the main class is found should be scanned (to find all the beans).
Besides that, it does many other things that spring boot application does during the start: loading configurations (application.properties/yaml) obeying the conventions of spring boot application, loading auto-configurations (stuff inside spring.factories) and so forth.
Bottom line you'll have a full-fledged spring boot application (usually microservice) loaded inside the test.
So far so good, but you say that you don't really have a spring boot application. So I see three ways:
Introduce an artificial class with #SpringBootConfiguration in the src/test/java/whatever-package-close-to-root folder (note, its in 'test', not in src/main)
Use #SpringBootTest with a parameter of "Configuration". This will mean that SpringBootTest won't use all this scanning up-and-then-down process and instead you'll instruct it to use the concrete context configuration.
Do not use #SpringBootTest annotation at all, and prefer a "usual" #ContextConfiguration - yes, you won't have the power of spring boot but as I've said above you probably won't need it. In addition these tests will be way faster, especially if you'll provide many "#Configuration" classes and will load only "relevant" parts of the library during the tests.
For example, if you test the DAO, there is no point in loading web related stuff.

Spring boot 2.1.7 having tomcat-embed-core conflit

I am migrating existing Spring project into Spring boot.unable to run spring boot application its showing following error.
The error log says there is a conflict on tomcat-embed-core.
In eclipse Dependency hierarchy of porm.xml is given below
i exclude the maven architect ,and try to run the application its showing following error
porm.xml
<modelVersion>4.0.0</modelVersion>
<artifactId>MyService</artifactId>
<packaging>jar</packaging>
<properties>
<java.version>1.8</java.version>
<!-- 2.1.3.RELEASE -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<springframework.boot.version>2.1.7.RELEASE</springframework.boot.version>
</properties>
<name>MyService</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.sybase.jdbc3.jdbc</groupId>
<artifactId>jconn3</artifactId>
<version>${jconn3.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jdbc</artifactId>
<version>${tomcat.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
what was wrong in this porm.xml
Where is
${tomcat.version}
defined?
That version probably does not match the tomcat version that auto magically is included with spring boot items.
And thus the conflict.
Go here:
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web/2.1.7.RELEASE
And start following the COMPILE dependencies, and you'll find the versions that are auto included with 2.1.7.RELEASE. and you have to alter the other includes that are overwriting the springboot auto include tomcat versions.
Again, follow the COMPILED dependency trail.
So below is what you should find by crawling the COMPILED dependency trail (from immediately above in my answer)
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/2.1.7.RELEASE
And you'll find you need to set
tomcat.version to
9.0.22
By defining tomcat.version as 8.x, you are breaking it.
Another way to put it
You have to go ~way~ back to springboot 1.5.2.RELEASE or 1.5.3.RELEASE
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/1.5.2.RELEASE
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-tomcat/1.5.3.RELEASE
(Again, in the two above links, looked at the COMPILE dependencies)
To find a version of tomcat (that is auto included with springboot) that gets close to tomcat 8.5.x (where 8.5.x is the one you are attempting to use)
That's pretty old.
The principal you are missing is that springboot auto includes dependencies. And anything else you import has to play nice with everything springboot auto includes.
And your current value for tomcat.version is NOT playing nice with everything springboot 2.1.7.RELEASE is auto including.
And now that you've been through all of that. You'll find you'll make your life easier if you engage the springboot world more completely.
Alot of times, springboot will have a (sub)package that will bring in the thing you really desire.
spring-boot-starter-jdbc
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-jdbc/2.1.7.RELEASE
You would probably be better off bringing that package in, vs hand-picking ones. Aka, get rid of your "tomcat-jdbc" include and see if the spring-boot-starter-jdbc can give you what you want.
The curse/blessing of spring-boot is that it is its own universe. But if you engage, you probably want to play by its rules more often than not.
PS
It is pom.xml, not porm.xml
Try adding spring-boot-starter-tomcat as a dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
Remove tomcat-juli and tomcat-jdbc dependencies. If you need JDBC support, add the corresponding starter:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
If you use JSP views, you will probably need the following dependencies as well:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
Also, pay attention to your dependencies versions. Spring Boot's parent POM defines version management for many common artifacts so you don't need to set the <version></version> for these libraries. See https://docs.spring.io/spring-boot/docs/2.1.7.RELEASE/reference/htmlsingle/#appendix-dependency-versions

Using mvn aem-project-archetype in AEM 6.2 does not resolve the core bundle - javax.inject cannot be resolved

I'm trying to build a new project using mvn aem-project-archetype (https://github.com/Adobe-Marketing-Cloud/aem-project-archetype) and on deploy the core bundle shows status as "Installed" but cannot be Active showing the error
javax.inject, version=[0.0,1) -- Cannot be resolved
I tried to add the dependencies as suggested here (https://github.com/Adobe-Marketing-Cloud/aem-project-archetype/issues/59)
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-atinject_1.0_spec</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
and also tried all solutions as listed here (http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.html/forum__fikl-ive_just_updatedfro.html) but they did not resolve.
Appreciate any help here.
Add Import-Package tag for "javax.inject" with version "0.0.0,*" under "org.apache.felix" plugin tag like below:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<!-- <Embed-Dependency>
artifactId1,artifactId2;inline=true
</Embed-Dependency> -->
<!-- Import any version of javax.inject, to allow running on multiple versions of AEM -->
<Import-Package>javax.inject;version=0.0.0,*</Import-Package>
<Sling-Model-Packages>com.xyz.sample_test_impl.core</Sling-Model-Packages>
</instructions>
</configuration>
</plugin>
After some research here's some solutions for the above:
Comment "#Inject" in HelloWorldModel.java . This may not be ideal, but if you are not planning on using Sling Models, then this will work.
#Model(adaptables=Resource.class)
public class HelloWorldModel {
//#Inject
private SlingSettingsService settings;
//#Inject #Named("sling:resourceType") #Default(values="No resourceType")
protected String resourceType;
Use ACS's Lazybones AEM Template instead of Archetype 10 if you will be using AEM 6.1 or higher. This is the recommended template to use with AEM whihc is more sophisticated and up-to-date.
Try to sync your dependencies list with the following official sample project. In fact, it helped for me just after adding
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<scope>provided</scope>
</dependency>
to general pom.xml and
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
</dependency>
to its child ../core/pom.xml

spring boot app initialization failure

Adding the spring boot dependencies in pom.xml and running spring boot app causes following errors -
> xception in thread "main" java.lang.IllegalAccessError: tried to
> access method
> org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Ljava/lang/Class;Ljava/lang/ClassLoader;)Ljava/util/List;
> from class org.springframework.boot.SpringApplication at
> org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:392)
> at
> org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:384)
> at
> org.springframework.boot.SpringApplication.initialize(SpringApplication.java:260)
> at
> org.springframework.boot.SpringApplication.<init>(SpringApplication.java:236)
> at
> org.springframework.boot.SpringApplication.run(SpringApplication.java:1185)
> at
> org.springframework.boot.SpringApplication.run(SpringApplication.java:1174)
> at com.catalina.platform.batch.Application.main(Application.java:12)
See below the snap shot of my pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-ftp</artifactId>
<version>${spring.ftp.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
Usually IllegalAccessError problems are due to an incorrect version of Spring being pulled in by Maven. Spring Boot 1.3.6 needs Spring Framework 4.2.7.
The spring-boot-dependencies dependencyManagement import is normally enough to ensure the correct version is used and the limited section of the POM that you've posted looks correct.
I would suggest running mvn dependency:tree to check that the correct version is being pulled in. Also check that you're on the latest Maven release.
Failing that, a project that reproduces the issue would help a lot with tracking down the cause.
I too had the same problem when i created a Spring Simple Web Maven Project and added few other dependencies in my pom.xml to write a web service for spring boot application
Updating my dependencies so that the version mismatch is handled and then doing Run As-->Maven clean , Run As --> Maven Install followed by Maven--Update Project worked in my case

Using "provided" classpath in tomcat7-maven-plugin goals

I have some dependencies in my webapp that I've marked as provided because I expect them to be provided by an appserver (maybe a production environment provides these dependencies at the specified versions). How do I simulate that when I'm running tests or in development on my localhost using for example the tomcat7-maven-plugin goals like run?
I can't see any way to do it without manually copying jars around. I can see how to use the test classpath - is there something wrong with what I'm trying to do?
OK, I've found a way of getting this to work - it's reasonable but there's a duplication of dependency information and a magic profile... I feel that the tomcat7-maven-plugin should provide a means of making provided dependencies available in the container when running.
Add a profile that is activated when the tomcat plugin runs, and add the dependencies that have provided scope with compile scope to that profile, eg.
... in project pom ...
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>my-provided-artifact</artifactId>
<version>1.2.3</version>
<scope>provided</scope>
</dependency>
</dependencies>
...
<profiles>
<profile>
<!-- profile activated as cli param when tomcat7 plugin runs -->
<id>tomcat</id>
<dependencies>
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>my-provided-artifact</artifactId>
<version>1.2.3</version>
<scope>compile</scope>
</dependency>
</dependencies>
</profile>
</profiles>
I use, for example, this:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.0</version>
<configuration>
<path>/myApp</path>
</configuration>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3</version>
</dependency>
</dependencies>
</plugin>
and then also include the dependency again later with provided.

Resources