Integrate Keycloak Admin Client 3.1.0.Final with Spring Boot 1.5.1 - spring-boot

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

Related

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

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>

Exception while instantiating RestTemplate

Am using Rest Template to consume web services in a Maven project and packaged the project to jar to add as a dependency to my other web application
but throwing Exception to console at instantiating the RestTemplate even though i put the code to catch the exception, its directly throwing the below Exception to console. can anyone know the reason?
try{
RestTemplate restTemplate = new RestTemplate(); //getting the Exception here
}
catch(Exception e){
e.printStackTrace(); // but its not coming here
}
the dependenices i have added in my pom.xml file :
<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.9.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<!-- JSON-Binding -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.3</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>1.1.0.1</version>
<scope>provided</scope>
</dependency>
the Exception at server side is :
Root cause of ServletException.
java.lang.NoSuchMethodError: com.fasterxml.jackson.databind.SerializationConfig.withDefaultPrettyPrinter(Lcom/fasterxml/jackson/core/PrettyPrinter;)Lcom/fasterxml/jackson/databind/SerializationConfig;
at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:86)
at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:67)
at com.fasterxml.jackson.dataformat.xml.XmlMapper.<init>(XmlMapper.java:63)
at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder$XmlObjectMapperInitializer.create(Jackson2ObjectMapperBuilder.java:807)
at org.springframework.http.converter.json.Jackson2ObjectMapperBuilder.build(Jackson2ObjectMapperBuilder.java:585)
Truncated. see log file for complete stacktrace
>
You might want to include the correct version jackson-databind jar file in classpath. The servlet container has not started to hit your code base.
Provide all the below dependencies in your pom.xml with same version:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
This should help.

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>

Issue with Hibernate Search and Spring Integration

I have been trying to integrate Spring with Hibernate Search but getting different exceptions with different versions.
In my pom.xml I have following dependencies
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.1.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>2.1.8.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-all</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.7.Final</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>2.1.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-tiles-plugin</artifactId>
<version>2.1.8.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.15</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.6</version>
</dependency>
<dependency>
<groupId>com.jgeppert.struts2.jquery</groupId>
<artifactId>struts2-jquery-plugin</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.jgeppert.struts2.jquery</groupId>
<artifactId>struts2-jquery-grid-plugin</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.jgeppert.struts2.jquery</groupId>
<artifactId>struts2-jquery-richtext-plugin</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.jgeppert.struts2.jquery</groupId>
<artifactId>struts2-jquery-tree-plugin</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>com.jgeppert.struts2.jquery</groupId>
<artifactId>struts2-jquery-mobile-plugin</artifactId>
<version>3.5.1</version>
</dependency>
I have also tried to get the actual version of hibernate (3.2.0 Final) from my tests so that I can easily compare the compatibility of hiberante search with my application's hiberante version.
String hibernateVersion = org.hibernate.annotations.common.Version.VERSION;
System.out.println("Hibernate Version: "+ hibernateVersion);
But whenever I just add these lines into my pom file
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search</artifactId>
<version>3.1.0.GA</version>
</dependency>
and try to deploy my application then it gives me an exception
ERROR org.springframework.web.context.ContextLoader.initWebApplicationContext:215 - Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource ....
....
....
Caused by: java.lang.NoSuchMethodError: org.hibernate.util.SoftLimitMRUCache.<init>(I)V
Mandatory:
Change all Struts2 jars from 2.1.8.1 to 2.3.16
Change struts2-jquery-plugin from 3.5.1 to 3.7.0 (or it won't work with 2.3.16, only with lower versions)
Suggested:
Upgrade Hibernate to 4.x
Upgrade Spring to 3.x
If possible, use Hibernate as JPA2 implementation, instead of using it as raw Hibernate (old way). Then you will discover that Spring is no longer needed (for persistence at least), especially if you are using JAVA EE 6.
P.S: you will need to upgrade also Apache Commons and other shared libraries according to the latest version, just use Maven Repository to get the proper version numbers.

Why does using spring 3.0 and struts yield: HTTP Status 404 - Servlet action is not available

Using Spring and Struts together gives no error
message in the console, but only a:
HTTP Status 404 - Servlet action is not available
in the Browser.
The logs give no clue whatsoever.
When Struts' action servlet fails to startup for whatever reason,
the resulting error can be as above.
In my case - struts using springs spring-struts integration -
the necessary spring jars (esp. spring-struts) were missing from the
class path of my web application.
The following maven dependencies worked:
<properties>
<spring.maven.artifact.version>
3.0.3.RELEASE
</spring.maven.artifact.version>
<spring.security.maven.artifact.version>
3.0.3.RELEASE
</spring.security.maven.artifact.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-struts</artifactId>
<version>${spring.maven.artifact.version}</version>
<exclusions>
<exclusion>
<groupId>struts</groupId>
<artifactId>struts</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring.security.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>com.springsource.org.apache.commons.codec</artifactId>
<version>1.4.0</version>
</dependency>
<!-- Struts 1.3 framework -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-core</artifactId>
<version>1.3.10</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-taglib</artifactId>
<version>1.3.10</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-el</artifactId>
<version>1.3.10</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-extras</artifactId>
<version>1.3.10</version>
</dependency>
<!-- be sure to include extra struts modules, as needed,
especially for used struts-plugins -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts-tiles</artifactId>
<version>1.3.10</version>
</dependency>
Note: if you don't use spring-security you can very likely drop the spring-security related dependencies, also the exclusion in spring-struts was necessary to include the latest struts version instead of 1.2.9

Resources