Arquillian no HTTPContext found when launching in embedded Weld EE container - maven

I'm using Maven and Eclipse to launch container tests. My maven config was setup using the archetype: jboss-javaee6-webapp-ear-blank-archetype
I can launch my Arquillian tests with no problem in JBoss AS7.
But when I try to launch using an embedded Weld EE container I get the following exception:
java.lang.IllegalArgumentException: No org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext found in org.jboss.arquillian.container.spi.client.protocol.metadata.ProtocolMetaData. Servlet protocol can not be used
What is causing the org.jboss.arquillian.container.spi.client.protocol.metadata.HTTPContext found error and how can I fix it?
I setup two different profiles in my pom, 1 for JBoss AS7 (works) and one for embedded Weld EE (not working):
<profile>
<id>arq-weld-ee-embedded</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jboss.spec</groupId>
<artifactId>jboss-javaee-6.0</artifactId>
<version>1.0.0.Final</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-weld-ee-embedded-1.1</artifactId>
<version>1.0.0.CR3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld</groupId>
<artifactId>weld-core</artifactId>
<version>1.1.5.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<!-- An optional Arquillian testing profile that executes tests in your
JBoss AS instance -->
<!-- This profile will start a new JBoss AS instance, and execute the
test, shutting it down when done -->
<!-- Run with: mvn clean test -Parq-jbossas-managed -->
<id>arq-jbossas-managed</id>
<dependencies>
<dependency>
<groupId>org.jboss.as</groupId>
<artifactId>jboss-as-arquillian-container-managed</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</profile>

In my arquillian.xml file I had the line:
<defaultProtocol type="Servlet 3.0" />
Upon some research I found out that the embedded Weld EE container does not support the Servlet 3.0 protocol
To fix this problem I removed the defaultProtocol from the config and setup the protocol on a per-container basis.

Related

Keycloak admin client not found in custom event listener

I'm developing a custom event listener for keycloak and I need the admin client (keycloak-admin-client) to use some methods. I've added the dependency in the pom file, and I'm generating the jar with: mvn clean install
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<keycloak.version>20.0.2</keycloak.version>
<maven-compiler-plugin.version>3.10.0</maven-compiler-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi</artifactId>
<version>${keycloak.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-server-spi-private</artifactId>
<version>${keycloak.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-services</artifactId>
<version>${keycloak.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>${keycloak.version}</version>
</dependency>
</dependencies>
The error I'm getting is:
2023-01-27 17:33:47,009 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-4) Uncaught server error: java.lang.NoClassDefFoundError: org/keycloak/admin/client/Keycloak
Also tried with <scope>provided</scope>. I have reviewed this post: KeyCloak custom REST Endpoint - Admin client classes not found which is exposing the same issue.
Edited: tried NoClassDefFoundError in a provider jar when using a class from org.keycloak.authentication.authenticators.broker.util without success.

How to properly configure Jakarta EE libraries in Maven pom.xml for Tomcat?

I have been trying in vain to implement tomcat 9's jakarta servlet as opposed to the previous javax.servlet implementation (as its my understanding that the jakarta package is the way forward). The issue is that when I point the browser at my servlet's url I get the following error(s)...
java.lang.ClassCastException: class cti.nm.web.Index cannot be cast to class javax.servlet.Servlet (cti.nm.web.Index is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader #48c76607; javax.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader #621be5d1)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:432)
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.base/java.lang.Thread.run(Thread.java:832)
The problem is obvious enough. Tomcat is trying to cast my jakarta.servlet.http.HttpServlet to a javax.servlet.Servlet which clearly won't work. What I can't figure is how to tell it what class the servlet is actually implementing.
The class itself is declared as ...
package cti.nm.web;
import jakarta.servlet.http.HttpServlet;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
public class Index extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
//print a bunch of stuff
}
}
My web.xml file is as follows ...
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<display-name>NMWeb</display-name>
<description>
NMWeb Description
</description>
<servlet>
<servlet-name>Index</servlet-name>
<servlet-class>cti.nm.web.Index</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Index</servlet-name>
<url-pattern>/NMWeb</url-pattern>
</servlet-mapping>
</web-app>
I had hoped that using the proper jakartaee xml schema in the deployment descriptor would cause the correct clases to be used but apparently not. The WAR seems to contain the proper jars ...
jakarta.jakartaee-api-9.0.0.jar
tomcat-el-api-10.0.0.jar
tomcat-servlet-api-10.0.0.jar
jakarta.servlet-api-5.0.0.jar
tomcat-jsp-api-10.0.0.jar
The pom is specified as ...
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cti.nm.NMWeb</groupId>
<artifactId>NMWeb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>[9.0.0,)</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>[5.0.0,)</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-jsp-api -->
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>[10.0.0,)</version>
</dependency>
</dependencies>
</project>
It's been days of searching the web for answers to this question and I can't seem to find any other instances of this exact scenario. I should mention that this is an eclipse generated probject that I have manually modified. Building with both maven and eclipse generates the same results when I deploy the war file.
You're basically physically including Tomcat 10.x specific libraries in WAR and then deploying the WAR to Tomcat 9.x. This is not the correct approach at all. Moreover, Tomcat 10.x was the first version to be Jakartified, not Tomcat 9.x.
Tomcat 9.x
For your Tomcat 9.x, which is based on Servlet 4.0, JSP 2.3, EL 3.0, WS 1.1 and JASIC 1.0, you should use javax.* imports and the entire <dependencies> section should minimally look like:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.security.enterprise</groupId>
<artifactId>javax.security.enterprise-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Tomcat 10.0.x
For Tomcat 10.0.x, which is based on Servlet 5.0, JSP 3.0, EL 4.0, WS 2.0 and JASIC 2.0, you should use jakarta.* imports and the entire <dependencies> section should minimally look like:
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.security.enterprise</groupId>
<artifactId>jakarta.security.enterprise-api</artifactId>
<version>2.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Tomcat 10.1.x
For Tomcat 10.1.x, which is based on Servlet 6.0, JSP 3.1, EL 5.0, WS 2.1 and JASIC 3.0, you should use jakarta.* imports and the entire <dependencies> section should minimally look like:
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp</groupId>
<artifactId>jakarta.servlet.jsp-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.el</groupId>
<artifactId>jakarta.el-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.websocket</groupId>
<artifactId>jakarta.websocket-api</artifactId>
<version>2.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.security.enterprise</groupId>
<artifactId>jakarta.security.enterprise-api</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
In any case
Please note that the <scope> is explicitly set to provided for them, which means that Maven should not include the physical JAR files in /WEB-INF/lib of the generated WAR file (because it's already provided by Tomcat itself!). Otherwise you only end up in runtime conflicts caused by duplicate classes in the runtime classpath.
Please also note that Tomcat is not a JEE server and thus importing either javax:javaee-api for Tomcat 9.x or jakarta.platform:jakarta.jakartaee-api for Tomcat 10.x is per definition wrong. Because it will allow you to compile your code against other JEE components such as JSF, JSTL, CDI, BV, EJB, JPA, JAX-RS, JSONB, etc etc while Tomcat actually doesn't offer them out the box. Tomcat only offers Servlet, JSP, EL, WS and JASIC out the box, so you should only declare them in pom.xml.
For example, JSTL needs to be installed separately as instructed in How to install JSTL? The absolute uri: http://java.sun.com/jstl/core cannot be resolved and JSF needs to be installed separately as instructed in How to properly install and configure JSF libraries via Maven? and CDI needs to be installed separately as instructed in How to install and use CDI on Tomcat?
If you're however very well aware of this limitation during developing code for Tomcat (i.e. make sure yourself that you don't accidentally use e.g. JSTL, CDI, BV, JPA, etc without actually installing them in Tomcat first), and merely want to minimize pom.xml boilerplate, then you can also get away with this minimalist dependencies configuration for Tomcat 9.x:
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>8.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
Or this for Tomcat 10.0.x:
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>9.0.0</version> <!-- Use 9.1.0 if you're already on Java 11 -->
<scope>provided</scope>
</dependency>
</dependencies>
Or this for Tomcat 10.1.x:
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
See also:
Tomcat versions
What exactly is Java EE?

Upgraded spring boot from 2.1.9 to 2.2.0 , now getting exception while starting

I upgraded spring boot from 2.1.9 to 2.2.0 now I am facing some exception while starting the application
java : openjdk11
spring-boot: v2.2.0.RELEASE
I tried by deleting the jar from this below location and did mvn clean install, still no luck.
.m2/repository/org/springframework/boot/spring-boot-actuator/2.2.0.RELEASE/spring-boot-actuator-2.2.0.RELEASE.jar
error :
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.cloud.client.discovery.health.DiscoveryCompositeHealthIndicator.<init>(DiscoveryCompositeHealthIndicator.java:41)
The following method did not exist:
org.springframework.boot.actuate.health.CompositeHealthIndicator.<init>(Lorg/springframework/boot/actuate/health/HealthAggregator;)V
The method's class, org.springframework.boot.actuate.health.CompositeHealthIndicator, is available from the following locations:
jar:file:/C:/Users/regosa/.m2/repository/org/springframework/boot/spring-boot-actuator/2.2.0.RELEASE/spring-boot-actuator-2.2.0.RELEASE.jar!/org/springframework/boot/actuate/health/CompositeHealthIndicator.class
It was loaded from the following location:
file:/C:/Users/regosa/.m2/repository/org/springframework/boot/spring-boot-actuator/2.2.0.RELEASE/spring-boot-actuator-2.2.0.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.boot.actuate.health.CompositeHealthIndicator
Pom.xml
<?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>com.xxxxx.business.workflow</groupId>
<artifactId>xxxxx-component-workflow-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>xxxxx-component-workflow-starter</name>
<description>xxxxx-component-workflow-starter</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<jaxb-runtime.version>2.4.0-b180830.0438</jaxb-runtime.version>
<spring-cloud.version>Greenwich.M1</spring-cloud.version>
<zeebe-version>0.20.1</zeebe-version>
<google-guava.version>27.0.1-jre</google-guava.version>
<xxxxx.version>1.0</xxxxx.version>
<swagger.version>2.9.2</swagger.version>
<jjwt.version>0.9.1</jjwt.version>
<json.version>20180813</json.version>
<slf4j-api.version>1.7.25</slf4j-api.version>
<mysql.version>8.0.11</mysql.version>
<mongo-java-driver.version>3.10.1</mongo-java-driver.version>
<commons-io.version>2.6</commons-io.version>
<commons-lang.version>2.6</commons-lang.version>
<commons-pool2.version>2.5.0</commons-pool2.version>
<redis.version>3.1.0</redis.version>
<velocity.version>1.7</velocity.version>
<velocity-tools.version>2.0</velocity-tools.version>
<logstash-logback-encoder.version>5.3</logstash-logback-encoder.version>
<httpclient.version>4.5.6</httpclient.version>
<jaxb-runtime.version>2.4.0-b180830.0438</jaxb-runtime.version>
<env>local</env>
</properties>
<dependencies>
<!-- Start: Spring Libraries -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</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-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
<!-- End: Spring Libraries -->
<!-- Adding JAXB Runtime since it is not shipped with JDK 9+ -->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>${jaxb-runtime.version}</version>
</dependency>
<!-- Start: xxxxx Libraries -->
<dependency>
<groupId>com.xxxxx</groupId>
<artifactId>xxxxx-entity</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<dependency>
<groupId>com.xxxxx</groupId>
<artifactId>xxxxx-redis</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<dependency>
<groupId>com.xxxxx</groupId>
<artifactId>xxxxx-mongo</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<dependency>
<groupId>com.xxxxx</groupId>
<artifactId>xxxxx-util</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<dependency>
<groupId>com.xxxxx.model</groupId>
<artifactId>xxxxx-model</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<dependency>
<groupId>com.xxxxx.service</groupId>
<artifactId>xxxxx-common-service</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<dependency>
<groupId>com.xxxxx.service</groupId>
<artifactId>xxxxx-common-messaging</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<dependency>
<groupId>com.xxxxx.service</groupId>
<artifactId>xxxxx-common-security</artifactId>
<version>${xxxxx.version}</version>
</dependency>
<!-- End: xxxxx Libraries -->
<!-- Adding Zeebe client as part of the Spring Startup -->
<dependency>
<groupId>io.zeebe</groupId>
<artifactId>zeebe-client-java</artifactId>
<version>${zeebe-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${google-guava.version}</version>
</dependency>
<!-- Logstash Log Encoder -->
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>${logstash-logback-encoder.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>${mongo-java-driver.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>${commons-lang.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${commons-pool2.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>${httpclient.version}</version>
</dependency>
<!-- Start: Swagger Libraries -->
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- End: Swagger Libraries -->
<!-- Start: Spring Boot and Security Test Libraries -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- End: Spring Boot and Security Test Libraries -->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>xxxxx-component-workflow-starter</finalName>
<filters>
<filter>${env}-build.properties</filter>
</filters>
<resources>
<resource>
<filtering>true</filtering>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<release>${java.version}</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Automatic-Module-Name>com.xxxxx.business.workflow.component.starter</Automatic-Module-Name>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>
New exception :
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.data.rest.core.support.UnwrappingRepositoryInvokerFactory.<init>(UnwrappingRepositoryInvokerFactory.java:57)
The following method did not exist:
org.springframework.plugin.core.PluginRegistry.of(Ljava/util/List;)Lorg/springframework/plugin/core/PluginRegistry;
The method's class, org.springframework.plugin.core.PluginRegistry, is available from the following locations:
jar:file:/C:/Users/regosa/.m2/repository/org/springframework/plugin/spring-plugin-core/1.2.0.RELEASE/spring-plugin-core-1.2.0.RELEASE.jar!/org/springframework/plugin/core/PluginRegistry.class
It was loaded from the following location:
file:/C:/Users/regosa/.m2/repository/org/springframework/plugin/spring-plugin-core/1.2.0.RELEASE/spring-plugin-core-1.2.0.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.plugin.core.PluginRegistry
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
springfox.documentation.spring.web.plugins.DocumentationPluginsManager.createContextBuilder(DocumentationPluginsManager.java:152)
The following method did not exist:
org.springframework.plugin.core.PluginRegistry.getPluginFor(Ljava/lang/Object;Lorg/springframework/plugin/core/Plugin;)Lorg/springframework/plugin/core/Plugin;
The method's class, org.springframework.plugin.core.PluginRegistry, is available from the following locations:
jar:file:/C:/Users/regosa/.m2/repository/org/springframework/plugin/spring-plugin-core/2.0.0.RELEASE/spring-plugin-core-2.0.0.RELEASE.jar!/org/springframework/plugin/core/PluginRegistry.class
It was loaded from the following location:
file:/C:/Users/regosa/.m2/repository/org/springframework/plugin/spring-plugin-core/2.0.0.RELEASE/spring-plugin-core-2.0.0.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.plugin.core.PluginRegistry
How to resolve this issue?
In short, issue is due to spring cloud and spring boot version incompatibility, spring boot 2.2.X requires Hoxton release train instead of Greenwich. See below for more info.
This issue is due to spring-cloud.version incompatibility. As per spring cloud documentation link(https://spring.io/projects/spring-cloud), below is the spring boot compatibility:
Release train Spring Boot compatibility
Release Train Boot Version
Hoxton 2.2.x
Greenwich 2.1.x
So if you are updating spring boot to 2.2.x then update to Hoxton release train for spring cloud as well i.e Hoxton.RC1(https://spring.io/blog/2019/10/25/spring-cloud-hoxton-rc1-released)
P.S: As per spring cloud Milestone page Hoxton.RELEASE in due on Nov 18, 2019 (https://github.com/spring-cloud/spring-cloud-release/milestones)
Actually springfox ist not compatible with Spring-Boot 2.2.0. It seems that springfox is dead at all.
Instead you can use: SpringDoc OpenApi
This seems to be a known issue: https://github.com/spring-cloud/spring-cloud-netflix/issues/3410
If you use Spring Cloud dependencies in your Spring Boot application make sure you have the correct Spring Cloud version on classpath! Only Spring Cloud's "Hoxton" (https://spring.io/blog/2019/08/19/spring-cloud-hoxton-m2-released) release train currently support Spring Boot 2.2.
Update your springfox-swagger version. I have upgraded springfox 2.9.2 running with boot 2.2.2
SpringFox needs version 1.2.0 version but Spring Boot 2.2.2 itself does not pull this in.So you somehow got spring-plugin-core-1.2.0.RELEASE in your classpath.Then it will work fine
As user10871691 and P3arl have already noted, the spring-plugin-core dependency is resolved with the wrong version 1.2.0.RELEASE. In order to force usage of the correct 2.0.0.RELEASE, you have to
EITHER exclude the wrong transitive dependency and specify the correct one,
OR pin (!) that dependency version in your pom.xml. This is done in the <dependenciesManagement> block, not in the <dependencies> block.
Example for Springfox 3.0.0 using version pinning in the <dependenciesManagement> block:
<spring-plugin-core.version>2.0.0.RELEASE</spring-plugin-core.version>
<springfox.version>3.0.0</springfox.version>
...
<dependencyManagement>
<dependencies>
<!-- Fix wrong resolved `spring-plugin-core` dependency version for springfox -->
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>${spring-plugin-core.version}</version>
</dependency>
<!-- API Documentation -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>${springfox.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- API Documentation -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
</dependency>
</dependencies>
<springBootVersion>2.2.4.RELEASE</springBootVersion>
Supported Cloud version. Hoxton.M2
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.M2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
...
</dependencies>
It's strange. The spring-plugin-core version should be 2.0.0, not 1.2.0. Let's upgrade it:
<!-- https://mvnrepository.com/artifact/org.springframework.plugin/spring-plugin-core -->
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
I was also facing the same issue and after adding the updated plugin-core dependency. It is resolved now.
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
If spring-plugin-core-1.2.0.RELEASE is not working in your project then another approach is that to use springfox-swagger with 3.0.0-SNAPSHOT version. For this version it has different repository.
Repository url : http://oss.jfrog.org/artifactory/oss-snapshot-local/
It will use #EnableSwagger2WebMvc annotation instead of #EnableSwagger2.
I upgraded to Springfox Swagger2 to 3.0.0 version and spring plugin code to 2.0.0.RELEASE version. It worked for me.
Spring Boot Version - 2.3.9.RELEASE
<dependency>
<groupId>org.springframework.plugin</groupId>
<artifactId>spring-plugin-core</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>

Spring Boot App module with custom parent - getting it to work

The goal: getting the Spring Boot app module which works perfectly with the spring-boot-starter-parent, to work with our own custom parent pom.
I am following this guide and am sorry to say I cannot get this to fully work.
https://www.surasint.com/spring-boot-with-no-parent-example/.
Concretely, with having the spring-boot-starter as parent pom everything works fine.
With our own parent pom, the Spring Boot app breaks.
I have a project setup with three modules and my own parent pom. This is needed for many reasons (the parent pom uses Maven profiles and sets important database variables depending on these profiles).
Parent pom (our custom).
Common – simple jar library.
Web – Spring Boot app with REST services and pure Java helpers (NOT any jsp or html). This used to inherit from spring-boot-starter parent – and now must inherit from our custom parent pom.
Worker – simple jar library with a worker thread.
I am using Spring Boot 1.5.9, Maven 3.3 and Java 8.
In theory I totally agree that it should work without having the spring-boot-starter-parent. However when making the Spring Boot module inheriting only from our parent pom and NOT from the spring-boot-starter-parent, the following (to me very weird) exceptions occur.
2018-02-07 16:06:46.822 ERROR 10008 --- [ main]
o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerAdapter' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter]: Factory method 'requestMappingHandlerAdapter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mvcValidator' defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.validation.Validator]: Factory method 'mvcValidator' threw exception; nested exception is java.lang.NoSuchMethodError: org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$EnableWebMvcConfiguration.getApplicationContext()Lorg/springframework/context/ApplicationContext;
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1173) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
The project is fully green in IntelliJ and compile is OK. It is only when starting the Spring Boot app that these errors occurs. As I interpret it the Spring boot app module is now lacking something which it had before. Any advice here would be most helpful!
Concretely, what do you need to import (in Maven dependency-tags) for the module to have access to exactly the same thing – and everything – that it had when it was inheriting from the spring-boot-starter-parent instead of your own custom parent? It would be super that instead of by pure intuition guessing your dependencies (which apparently fails in my situation) there is a reference dependency checklist that makes sure your module have access to exactly the same thing as if inheriting from the spring-boot-starter-parent directly.
So far I've by pure intuition added the following to the Spring boot module (called "web" above)
<!-- === [Spring Boot Starter] === -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Evidently something is missing which was present with the spring-boot-starter as parent. Moreover - and oddly enough - the rest of the possible spring-boot-starter dependencies seem totally irrelevant for the project (things like cloud-connectors, twitter-connectors, mongodb and related). I added all remotely relevant just to test but the errors below are still there. Any advice or help is most appreciated.
As a reference here is the parent pom:
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
no.statnett.fasit
fasit-hub-backend
1.0-SNAPSHOT
common
worker
web
pom
Fasit Hub Backend
<!-- parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.source.encoding>UTF-8</project.source.encoding>
<project.source.version>1.8</project.source.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.boot.version>1.5.9.RELEASE</spring.boot.version>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencyManagement>
<dependencies>
<!--
Import dependency management from Spring Boot
* This fixes the Spring boot parent issue [inherit dependencyManagement without forcing Spring Boot App]
* It does NOT include the plugin management
See https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-build-systems.html#using-boot-maven-without-a-parent
See http://www.logicbig.com/tutorials/spring-framework/spring-boot/starter-import/
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
<!-- === [Spring Boot JPA] ===-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.1</version>
</dependency>
<!-- === [Spring Boot Security] ===-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- === [Spring Boot Maven plugin needed for profile management] ===-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!-- === [Messaging] ===-->
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
</dependency>
-->
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.7.2.RELEASE</version>
</dependency>
<!-- ===[Messaging with AMQP over JMS with the Apache QPID client] === -->
<dependency>
<groupId>org.apache.qpid</groupId>
<artifactId>qpid-jms-client</artifactId>
<version>0.24.0</version>
</dependency>
<!-- === [Date and Time management] ===-->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.9.4</version>
</dependency>
<!-- === [XStream for converting classes to and from XML] === -->
<!-- NB!
XStream also needs Apache's commons-io
2017.10.15: The artifact org.apache.commons:commons-io:jar:1.3.2 has been relocated to commons-io:commons-io:jar:1.3.2
See https://mvnrepository.com/artifact/org.apache.commons/commons-io
See https://mvnrepository.com/artifact/commons-io/commons-io
-->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<!-- === [Spring MVC and WEB (javax.servlet, JSP/JSTL] === -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.5.RELEASE</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- === [Logging and Testing] === -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</dependencyManagement>
<profiles>
<profile>
<id>dev</id>
<properties>
<activatedProperties>dev</activatedProperties>
<datasourceURL>jdbc:oracle:thin:#h1-a-oradb10t:1521:fasitngft1</datasourceURL>
<datasourceUser>fasithub</datasourceUser>
<datasourcePassword>cH9nIiBzuS5Ho3q1bOP5</datasourcePassword>
<datasourceDriver>oracle.jdbc.OracleDriver</datasourceDriver>
<ecpServer>amqp://ec2-52-34-81-131.us-west-2.compute.amazonaws.com:5672</ecpServer>
<ecpServerSolnett>amqp://ec2-52-40-134-91.us-west-2.compute.amazonaws.com:5672</ecpServerSolnett>
<ecpServerVindnett>amqp://ec2-34-213-80-66.us-west-2.compute.amazonaws.com:5672</ecpServerVindnett>
<ecpEndpointSuffix></ecpEndpointSuffix>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<activatedProperties>test</activatedProperties>
<datasourceURL>jdbc:h2:file:~/test</datasourceURL>
<datasourceUser>sa</datasourceUser>
<datasourcePassword></datasourcePassword>
<datasourceDriver>org.h2.Driver</datasourceDriver>
<ecpServer>amqp://ec2-52-34-81-131.us-west-2.compute.amazonaws.com:5672</ecpServer>
<ecpServerSolnett>amqp://ec2-52-40-134-91.us-west-2.compute.amazonaws.com:5672</ecpServerSolnett>
<ecpServerVindnett>amqp://ec2-34-213-80-66.us-west-2.compute.amazonaws.com:5672</ecpServerVindnett>
<ecpEndpointSuffix></ecpEndpointSuffix>
</properties>
</profile>
<profile>
<id>staging</id>
<properties>
<activatedProperties>staging</activatedProperties>
<datasourceURL>jdbc:oracle:thin:#h1-a-oradb10t:1521:fasitngft1</datasourceURL>
<datasourceUser>fasithub</datasourceUser>
<datasourcePassword>cH9nIiBzuS5Ho3q1bOP5</datasourcePassword>
<datasourceDriver>oracle.jdbc.OracleDriver</datasourceDriver>
<ecpServer>amqp://h1-a-ecp4end:6672</ecpServer>
<ecpServerSolnett>amqp://ec2-52-40-134-91.us-west-2.compute.amazonaws.com:5672</ecpServerSolnett>
<ecpServerVindnett>amqp://ec2-34-213-80-66.us-west-2.compute.amazonaws.com:5672</ecpServerVindnett>
<ecpEndpointSuffix>FASIT-SERVICE</ecpEndpointSuffix>
</properties>
</profile>
</profiles>
And here is the spring boot app module pom (here is where current the trial-and-error occurrs):
<?xml version="1.0" encoding="UTF-8"?>
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
<!-- Alt.1: have our own parent: this is the way to go for a common jar module.
ISSUE: Spring Boot module fails to run - applicationContext fails to load!
Solution: explicitly define goal for spring-boot-maven-plugin (If you use Spring Boot as parent, you do not have to explicitly define this)
-->
<parent>
<groupId>no.statnett.fasit</groupId>
<artifactId>fasit-hub-backend</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<!-- Alt.2: have spring-boot-starter-parent as parent. This is useful for a Spring Boot app module.
ISSUE: profile management breaks - properties are not set on the Spring Boot module!
Solution: not possible without our own parent pom
-->
<!-- parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
<relativePath/>
</parent -->
<!-- Spring Boot starter properties overrule (default Java is only 1.6) -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<!-- spring.boot.version>1.5.6.RELEASE</spring.boot.version -->
</properties>
<groupId>no.statnett.fasit</groupId>
<artifactId>web</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!-- === [Dependency Management] === -->
<dependencies>
<dependency>
<groupId>no.statnett.fasit</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- === [Spring Boot Starter] === -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- Following three dependencies where not needed with spring-boot-starter-parent as parent:
spring-boot-starter-tomcat, spring-boot-starter-thymeleaf, spring-boot-starter-data-rest
STILL GET ISSUE:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate
[org.springframework.data.rest.core.config.RepositoryRestConfiguration]:
Factory method 'config' threw exception; nested exception is java.lang.NoClassDefFoundError:
org/springframework/data/rest/core/config/RepositoryCorsRegistry
-->
<!-- === [Spring Boot JPA] === -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<exclusions>
<exclusion>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- === [Oracle driver official, manually installed] ===-->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.3.0</version>
<type>pom</type>
</dependency>
<!-- === [Spring Boot Security] ===-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- === [Date and Time management] ===-->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.3</version>
</dependency>
<!-- === [XStream for converting classes to and from XML] === -->
<!-- NB! moved to the common module, they are not needed here in the web service module! -->
</dependencies>
<!-- === [Build management for the Spring Boot module] === -->
<build>
<plugins>
<!-- === [Spring Boot Maven plugin is used for profile management] ===-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- === [Apache Maven compiler plugin for building] ===-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
UPADTE 1:
if I add the following three dependencies to the spring app module pom:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
I instead get the following excetpion:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.rest.core.config.RepositoryRestConfiguration]: Factory method 'config' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/data/rest/core/config/RepositoryCorsRegistry
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 144 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/data/rest/core/config/RepositoryCorsRegistry
I am not sure how to interpret this. Does this mean we are on the right track and just need to add some additional depedency, OR where the dependencies added needlessly and perhaps causing unnessecary problems?
The missing class now is https://docs.spring.io/spring-data/rest/docs/current/api/org/springframework/data/rest/core/config/RepositoryCorsRegistry.html
I am not sure exactly what to add as dependency to get access to this class in the right way with Spring Boot. Naturally I am reluctant to add it through a normal spring framework dependency like https://mvnrepository.com/artifact/org.springframework/spring-web/5.0.3.RELEASE since that often causes version problems (Spring Boot includes the relevant springframeworkd and should be managed totally through Spring Boot as I understand it and been told many times).
UPDATE 2:
Perhaps against better judgement – and since I'm willing to test anything until things are working – I add the following libraries which have the currently missing class.
This is of course only done after carefully checking https://mvnrepository.com/artifact/org.springframework.boot/spring-boot/1.5.9.RELEASE for exactly which core org.springframework library are used by the Spring Boot version.
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
I now get a different exception:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter]: Factory method 'httpPutFormContentFilter' threw exception; nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.jackson.databind.ObjectMapper
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 26 common frames omitted
Caused by: java.lang.NoClassDefFoundError: Could not initialize class com.fasterxml.jackson.databind.ObjectMapper
at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.build(Jackson2ObjectMapperBuilder.java:588) ~[spring-web-4.3.13.RELEASE.jar:4.3.13.RELEASE]
Which leads me to add the following dependency (again after carefully checking the Spring Boot reference above to see what version of the specific library it uses):
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
However, sadly and oddly enough – the same exception is still there. This means we have hit a dead end since there are no more logical libraries to include from https://mvnrepository.com/artifact/org.springframework.boot/spring-boot/1.5.9.RELEASE.
And regardless, it is not best practice to include specific core springframework library versions when working with a Spring Boot app.
So let's take a step back and look at what we need.
The Spring Boot app module contains a set of REST services.
One set of the services are only GET requests, and produces application/xml
(for integration with systems of type alpha)
Another set of the
services produces and consumes application/json (for integration with
systems of type omega).
That's it. All core service and JPA logic is in the common library module which is needed by both the web Spring Boot app module, and the worker module.
Bottom line: what spring-boot dependencies do we need to import to get this to work? Again it works perfectly fine when having the spring-boot-starter-parent as pom parent – but that is not possible in the given situation. Suffice to say it would be super to finally get this working
Cheers!
Is there some reason that the Spring Boot Starter Parent cannot be the parent of your parent pom? I see that it is commented out in your custom parent.
This setup should work:
Custom Parent pom
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.16.RELEASE</version>
</parent>
<!-- All of your customizations follow -->
<dependencies>
<!-- Define common dependencies for all child modules-->
</dependencies>
<dependencyManagement>
<!-- Define optional module dependencies with preferred versions -->
<!-- This can help the module developers to not have to deal with dependency conflicts if you handle them here -->
</dependencyManagement>
<build>
<plugins>
<!-- Define common plugin configs for all child modules -->
</plugins>
<pluginManagement>
<plugins>
<!-- Define optional plugin configs for child modules -->
</plugins>
</pluginManagement>
</build>
App pom
<parent>
<groupId>no.statnett.fasit</groupId>
<artifactId>fasit-hub-backend</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
Honestly, that should be it. You've then created a custom parent pom that inherits everything correctly from the Spring Boot Starter Parent, and you can provide all of your own profiles and other customization that you want your App module(s) to inherit.
You should not have to go through all of the trouble of recreating the dependency tree of a Spring Boot Application, and as you've noted, doing so would basically be a hellscape of dependency management.
I have now finally managed to solve this issue by brute force trial-and-error testing.
Suffice to say there are a huge number of possible of combinations of dependencies to test. As a developer this is by far among the most tedious and time-wasting task you can perform.
I am not flagging this as an acceptable answer simply because I am not happy at all with it.
Suffice to say, it would really be super with a reference set for dependency inclusions so you get exactly what you get as with the spring-boot-starter-parent. Also it does not feel like best practice to include specific core org.springframework dependencies when you are working with Spring Boot. If you are not super disciplined and doublecheck the exact library versions used by your specific Spring Boot version you will run into problems.
Best practice - as I understand it and also been told many times - is that you only import pure Spring Boot dependencies, and Spring Boot manages the rest. Evidently that sadly and suprisingly enough is not the case. If anyone has proof of the contrary, I'm all ears.
In summary these are the dependencies that solved the spring boot app module containing REST services (with both application/json and application/xml and automatic object mapping).
<!-- === [Spring Boot Starter] === -->
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- NB!
spring-boot-starter-web also needs the following [Spring Boot app fails to start without them]
These dependencies where NOT needed with spring-boot-starter-parent as parent.
Without them you e.g. get the following on Spring Boot app start:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate
[org.springframework.data.rest.core.config.RepositoryRestConfiguration]:
Factory method 'config' threw exception; nested exception is java.lang.NoClassDefFoundError:
org/springframework/data/rest/core/config/RepositoryCorsRegistry
-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.10</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.3.6.Final</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.13.RELEASE</version>
</dependency>
<!-- Provided -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

How to test Spring in an application server container with Arquillian?

We are trying to run integration tests of Spring based code on an embedded tomcat container using TestNG framework.
We have tried to use the existing Arquillian Spring Extension without much success. Maybe some missing configuration. We have followed instructions from this post
Our pom includes the following dependencies:
<dependency>
<groupId>org.jboss.arquillian</groupId>
<artifactId>arquillian-bom</artifactId>
<version>1.0.2.Final</version>
<scope>test</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.testng</groupId>
<artifactId>arquillian-testng-container</artifactId>
<version>1.0.2.Final</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8</version>
<scope>test</scope>
</dependency>
<!-- Spring Extension -->
<dependency>
<groupId>org.jboss.arquillian.extension</groupId>
<artifactId>arquillian-service-container-spring</artifactId>
<version>1.0.0.Beta1</version>
<scope>test</scope>
</dependency>
<!-- testing END -->
We have also added a Tomcat embedded profile to our pom.
<profile>
<id>arquillian-tomcat-embedded-7</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-tomcat-embedded-7</artifactId>
<version>1.0.0.CR3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>7.0.30</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>7.0.30</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-juli</artifactId>
<version>7.0.30</version>
</dependency>
<dependency>
<groupId>org.eclipse.jdt.core.compiler</groupId>
<artifactId>ecj</artifactId>
<version>3.7</version>
<scope>test</scope>
</dependency>
<!-- Weld servlet for testing CDI injections -->
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet</artifactId>
<version>1.1.9.Final</version>
</dependency>
</dependencies>
</profile>
Our arquillian.xml looks like...
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<arquillian xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://jboss.org/schema/arquillian"
xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
<container qualifier="tomcat" default="true">
<configuration>
<property name="unpackArchive">true</property>
</configuration>
</container>
We also tried adding the following lines to our arquillian.xml
<extension qualifier="spring">
<property name="autoPackage">true</property>
<property name="springVersion">3.0.0.RELEASE</property>
<property name="cglibVersion">2.2</property>
<property name="includeSnowdrop">true</property>
<property name="snowdropVersion">2.0.3.Final</property>
<property name="customContextClass">org.jboss.spring.vfs.context.VFSClassPathXmlApplicationContext</property>
</extension>
We have created an empty test and check that the embedded Tomcat starts and the test is run.
The next step is to verify that the Arquillian Spring Extension is working properly, and to do so we are trying to inject a Spring bean into our test.
The problem is that the #SpringConfiguration annotation isn't available at all. So we guess we are missing some configuration. Any clues on how to proceed?
You're using the arquillian-service-container-spring artifact which is the Embedded Spring container. To use if with another Container you need to use the arquillian-service-deployer-spring-3 and arquillian-service-integration-spring-inject artifacts.
service-deployer adds auto adding Spring dependencies to the deployment while service-integration-spring-inject adds the #Inject/#Autowire support in the test case.
See https://github.com/arquillian/arquillian-showcase/blob/master/spring/spring-inject/pom.xml#L43
Multiple other examples can be found here:
https://github.com/arquillian/arquillian-showcase/tree/master/spring

Resources