ClassNotFoundException: com.fasterxml.jackson.core.util.JacksonFeature in Spring boot, upgrading from Elasticsearch HLRC to Java API Client - spring-boot

I wanted to swap out the deprecated High Level Rest Client with the new Java API Client from Elasticsearch. Problem is, I'm not sure if my dependencies are configured correctly! I'm running into this error:
java.lang.NoClassDefFoundError: com/fasterxml/jackson/core/util/JacksonFeature
Caused by: java.lang.ClassNotFoundException: com.fasterxml.jackson.core.util.JacksonFeature
Elasticsearch just got upgraded to 7.17.3 and Spring Boot is 2.2.8 right now, it will be upgraded later but I'm not sure if that's the problem? Here are my dependencies in the pom:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webmvc-core</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-security</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>7.17.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2</version>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.1.0</version>
</dependency>
</dependencies>
I followed the documentation from Elasticsearch here so I tried it with the 2.12.3 version of jackson-databind as well but the error persists. Any idea on what should be changed? Thanks!
Edit: just in case it helps, here's also my client which is where the dependency is needed (I assume)
#Configuration
public class ElasticsearchClient{
RestClient restClient = RestClient.builder(new HttpHost("localhost", 9200)).build();
ElasticsearchTransport transport = new RestClientTransport(restClient, new JacksonJsonpMapper());
public ElasticsearchClient client = new ElasticsearchClient(transport);
}
(I had to put the public in front of client because it sits under another package and won't let me call on it unless it's there)
more info after playing around: turns out there is a parent and it would load an older jackson-databind, so I did the following
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-schema-registry-client</artifactId>
<exclusions>
<exclusion>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
still doesn't work so I'm 200% out of ideas now

Add jackson-core solved my problem.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.3</version>
</dependency>

Related

Error starting Spring Cloud Stream with Kinesis

I'm trying to start a new sample project using for process Kinesis Stream but I'm getting the following error:
Exception in thread "-kinesis-consumer-1" java.lang.NoSuchFieldError: logger
at org.springframework.integration.aws.inbound.kinesis.KinesisMessageDrivenChannelAdapter.access$5400(KinesisMessageDrivenChannelAdapter.java:100)
at org.springframework.integration.aws.inbound.kinesis.KinesisMessageDrivenChannelAdapter$ShardConsumer.lambda$execute$0(KinesisMessageDrivenChannelAdapter.java:941)
And those are my pom dependencies:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-kinesis</artifactId>
<version>LATEST</version>
</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>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-kinesis</artifactId>
<version>1.11.632</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream</artifactId>
<scope>test</scope>
<classifier>test-binder</classifier>
<type>test-jar</type>
</dependency>
</dependencies>
The sample code of Spring Cloud with Kinesis is outdated, so I tried use newest dependencies.
Anyway, someone can help?
You probably try to use the latest Spring Boot 2.4.x which brings for us Spring Integration 5.4 already. And this one is not compatible with the latest Spring Integration AWS, which is still based on the Spring Integration 5.3.x.
Let's see if you still can stick with Spring Boot 2.3.x!

SpringBoot Keycloak NoSuchMethodError: javax.ws.rs.core.UriBuilder.resolveTemplates

I probably have an issue with my POM in my SpringBoot App.
Currently I am trying to access my Keycloak Server with the
"admin-client-keycloak"
But on the call:
Response response = getInstance().realm(REALM).users().create(user);
I get Error:
java.lang.NoSuchMethodError: javax.ws.rs.core.UriBuilder.resolveTemplates(Ljava/util/Map;)Ljavax/ws/rs/core/UriBuilder;
at org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget.resolveTemplates(ClientWebTarget.java:178) ~[resteasy-client-3.5.1.Final.jar:3.5.1.Final]
at org.jboss.resteasy.client.jaxrs.internal.proxy.SubResourceInvoker.invoke(SubResourceInvoker.java:65) ~[resteasy-client-3.5.1.Final.jar:3.5.1.Final]
at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:76) ~[resteasy-client-3.5.1.Final.jar:3.5.1.Final]
at com.sun.proxy.$Proxy198.realm(Unknown Source) ~[na:na]
at org.keycloak.admin.client.Keycloak.realm(Keycloak.java:118) ~[keycloak-admin-client-3.4.3.Final.jar:3.4.3.Final]
To be honest: I am not a Maven expert and stitched it together from several web soultions and I expect that some parts are still outdated or something.
the POM dependecys:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
<scope>runtime</scope>
</dependency>
<!-- Keycloak -->
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>3.4.3.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.5.1.Final</version>
</dependency>
<!-- JUnit -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.keycloak.bom</groupId>
<artifactId>keycloak-adapter-bom</artifactId>
<version>3.4.3.Final</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
The Error occurs from the 'keycloak-admin-client' module.
Now the main question is:
Whats the problem? Or is it realy a bug inside the version of 'keycloak-admin-client'?
I guess not which leads my to a second question:
How can I found out what I need to change in a situation like this?
Thanks in advance for all suggestions. I primary want to learn how to solve such issues by my own in future.
Kind regards
Gregor
EDIT:
Well I am a step further but the issue is still there.
The POM I show you here is a POM of library which is used in other projects.
These Project have a 'spring-Boot-starter' which are using the 'jersey' version:1.54.
So the problem seems clear.
I added the 'jersey 2.0.2' dependency in the final project POM
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
But the issue still exists.
How can I force maven use the 2.0.2 version and override the 1.5.?
Only adding the dependecy doesnt seems to help.
Some of the other dependencies are using a different version of the lib jsr311-api. In my case it was the eureka client. I just added an exclude with this dependency in the pom and it worked
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<exclusions>
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</exclusion>
</exclusions>
</dependency>
Please make sure UriBuilder class exist on your project. And make sure only one UriBuilder class (version) exist in your project. (It can be multiple on your project with different versions.) Different versions can be overlapped.
keycloak-admin-client version should same with your keycloak server version.
add additional dependency to pom (versions must be added, for keycloak 3.0.0.Final => resteasy dependecies 3.5.0.Final works for me. Dependencies must be complied.)
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-multipart-provider</artifactId>
</dependency>
Note: This is my suggestion, if you are develop multi-layer app. You can divide your project to layers. You can divide your spring boot starter app and keycloak access layer. And use this new project as dependecy.
edit,
see Failed adding user by keycloak-admin-client to Keycloak due to "unknown resource"
i hope these can helps.

Is it possible to configure the spring boot server explicitly?

I've a Spring Boot application where one of the dependencies is using spring and a embedded jetty to start an ad-hoc web server. This causes my spring boot app to start in a jetty instead of a tomcat.
My spring-boot-starter-web:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
</exclusion>
</exclusions>
</dependency>
The dependencies pom:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
Is there a possibility to configure the server to use by spring boot explicitly instead of being inferred by the dependency tree?
EDIT
I investigated the issue a little bit further and created a repo to reproduce the issue: github.com/svettwer/spring-server-test
org.eclipse.jetty.websocket:javax-websocket-server-impl causes spring to start with jetty without any other config required.
EDIT 2
The issue is not present anymore in Spring Boot 2.x
EDIT 3
I'll deleted the repo mentioned earlier, but here is the dependency setup that caused the issue:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>1.5.7.RELEASE</version>
<scope>test</scope>
</dependency>
<!-- Comment that in to start spring with jetty-->
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<version>9.4.8.v20171121</version>
</dependency>
</dependencies>
Normally, if you have the spring-boot-starter-tomcat on your classpath (through spring-boot-starter-web), it should always select Tomcat since it has priority over other servlet containers. Even if you have the following dependencies, Spring boot will start with Tomcat:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
You can programmatically override the chosen servlet container by registering your own ServletWebServerFactory, for example:
#Bean
public ServletWebServerFactory factory() {
return new TomcatServletWebServerFactory();
}
You can choose the predefined TomcatServletWebServerFactory, JettyServletWebServerFactory or the UndertowServletWebServerFactory.
This guide may help you: https://docs.spring.io/spring-boot/docs/current/reference/html/howto-embedded-web-servers.html
If you run an mvn dependency:tree and search for jetty you might find that you need to exclude it, e.g:
spring-boot-starter-jetty
excluded like in the example:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- Exclude the Tomcat dependency -->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Use Jetty instead -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
which is favouring jetty over tomcat - but you get the idea hopefully...
Hope this helps.

Integrate Keycloak Admin Client 3.1.0.Final with Spring Boot 1.5.1

I'm trying to integrate KeyCloak Admin Client with Spring Boot
But there is an exception is thrown when I was trying to create a new account:
Caused by: javax.ws.rs.ProcessingException: RESTEASY003145: Unable to find a MessageBodyReader of content-type application/json and type class org.keycloak.representations.AccessTokenResponse
So I tried to explicitly register Jackson Provider for KeyCloak like this:
KeycloakBuilder
.builder()
.serverUrl(SERVER_URL)
.realm(REALM)
.username(USERNAME)
.password(PASSWORD)
.clientId(CLIENT_ID)
.resteasyClient(new ResteasyClientBuilder()
.providerFactory(factory.register(ResteasyJackson2Provider.class))
.connectionPoolSize(10)
.build())
.build();
But I'm unable to import ResteasyJackson2Provider.class
pom.xml
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-spring-security-adapter</artifactId>
<version>3.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>3.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.1.3.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.1.3.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.1.3.Final</version>
</dependency>
Btw, if I use resteasy-jackson-provider, I got this exception:
javax.ws.rs.client.ResponseProcessingException: javax.ws.rs.ProcessingException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "access_token" (Class org.keycloak.representations.AccessTokenResponse), not marked as ignorable
at [Source: org.jboss.resteasy.client.jaxrs.internal.ClientResponse$InputStreamWrapper#7cc842b0; line: 1, column: 18] (through reference chain: org.keycloak.representations.AccessTokenResponse["access_token"])
After a while, I figured out the solution to this problem:
Firstly, I tested it out with the standalone project (empty maven project), the problem still occurs because of resteasy-jackson-provider. It should be resteasy-jackson2-provider (note that its resteasy-jackson2-provider)
For now, I was known that the problem somehow comes from Spring Boot, RESTeasy. And finally, I come up with this working pom.xml:
<dependency>
<groupId>org.keycloak</groupId>
<artifactId>keycloak-admin-client</artifactId>
<version>3.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.1.3.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<version>3.1.3.Final</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.8.8</version>
</dependency>
One more thing to note is, you should use the admin-cli client in your Keycloak, because by default, it has Direct Access Grants Enabled on
Btw, this is the Java configuration:
KeycloakBuilder
.builder()
.serverUrl("localhost:8080/auth")
.realm("master")
.username("YOUR_USERNAME")
.password("YOUR_PASSWORD")
.clientId("admin-cli")
.build();
Working example: https://github.com/phuongtailtranminh/Keycloak-Admin-Client-Spring-Boot-Demo

Hystrix Dashboard not available with Jersey endpoint

I have a Spring Boot application with a public endpoint implemented with Jersey/JAX-RS annotations.
Hystrix Dashboard is enabled with #EnableHystrixDashboard, HystrixMetricsStreamServlet is registered under "/hystrix.stream" (as in the examples out there).
When accessing .../hystrix.stream the metrics data is available for the HystrixCommands but the starter dashboard page "/hystrix" is empty giving HTTP 404 status code.
Any idea why it is not accessible with Jersey?
If the same is implemented with Spring WebMVC (not Jersey) the dashboard page is available.
My pom.xml
excludes spring-webmvc and depends on jersey
depends on hystrix, event-stream, dashboard, actuator
-
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>${hystrix.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>${hystrix.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<version>1.0.2.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.6.6</version>
</dependency>

Resources