quarkus: Keycloak Admin Client does not work with Quarkus because it depends on RestEasy 3.x

Describe the bug A java.lang.InstantiationError is thrown when trying to create an instance of org.keycloak.admin.client.Keycloak programmatically.

Expected behavior The org.keycloak.admin.client.Keycloak instance is created with no exceptions or errors.

Actual behavior The following stack trace occurs:

20:47:19 ERROR [io.undertow.request.io] Exception handling request dba6821d-e797-4a15-8a77-c767e55943b2-1 to /api/v1/tests/accounts/create: java.lang.InstantiationError: org.jboss.resteasy.spi.ResteasyProviderFactory
	at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.getProviderFactory(ResteasyClientBuilder.java:382)
	at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.register(ResteasyClientBuilder.java:497)
	at org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder.register(ResteasyClientBuilder.java:38)
	at net.myapp.security.keycloak.KeycloakClientFactory.createKeycloakClient(KeycloakClientFactory.java:92)
	at net.myapp.security.keycloak.KeycloakAdminClient.init(KeycloakAdminClient.java:58)
	at net.myapp.security.keycloak.KeycloakAdminClient_Bean.create(KeycloakAdminClient_Bean.zig:80)
	at net.myapp.security.keycloak.KeycloakAdminClient_Bean.get(KeycloakAdminClient_Bean.zig:202)
	at net.myapp.security.keycloak.KeycloakAdminClient_Bean.get(KeycloakAdminClient_Bean.zig:61)
	at net.myapp.rest.services.test.TestRS_Bean.create(TestRS_Bean.zig:320)
	at net.myapp.rest.services.test.TestRS_Bean.create(TestRS_Bean.zig:179)
	at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:80)
	at io.quarkus.arc.impl.ComputingCache$CacheFunction.lambda$apply$0(ComputingCache.java:99)
	at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:26)
	at io.quarkus.arc.impl.ComputingCache.getValue(ComputingCache.java:41)
	at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:25)
	at net.myapp.rest.services.test.TestRS_Bean.get(TestRS_Bean.zig:163)
	at net.myapp.rest.services.test.TestRS_Bean.get(TestRS_Bean.zig:405)
	at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:355)
	at io.quarkus.arc.impl.ArcContainerImpl.beanInstanceHandle(ArcContainerImpl.java:367)
	at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:222)
	at io.quarkus.arc.impl.ArcContainerImpl$1.get(ArcContainerImpl.java:219)
	at io.quarkus.arc.runtime.ArcRecorder$2$1.create(ArcRecorder.java:79)
	at io.quarkus.resteasy.common.runtime.QuarkusConstructorInjector.construct(QuarkusConstructorInjector.java:56)
	at org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory.createResource(POJOResourceFactory.java:69)
	at org.jboss.resteasy.core.ResourceLocatorInvoker.createResource(ResourceLocatorInvoker.java:62)
	at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:112)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:477)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:252)
	at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:153)
	at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:363)
	at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:156)
	at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:238)
	at org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:249)
	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:60)
	at org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:55)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
	at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:74)
	at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:63)
	at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
	at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
	at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:133)
	at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
	at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:65)
	at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
	at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
	at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
	at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
	at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:270)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:59)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:116)
	at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:113)
	at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
	at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
	at io.quarkus.undertow.runtime.UndertowDeploymentRecorder$9$1$1.call(UndertowDeploymentRecorder.java:476)
	at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:250)
	at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:59)
	at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:82)
	at io.undertow.server.Connectors.executeRootHandler(Connectors.java:290)
	at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:669)
	at io.quarkus.runtime.CleanableExecutor$CleaningRunnable.run(CleanableExecutor.java:224)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2011)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1535)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1395)
	at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
	at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
	at java.base/java.lang.Thread.run(Thread.java:830)
	at org.jboss.threads.JBossThread.run(JBossThread.java:479)

To Reproduce I attempt to create a Keycloak client instance like this:

		Keycloak kc = KeycloakBuilder.builder() //
				.serverUrl(authServerURL) //
				.realm(realmName) //
				.grantType(OAuth2Constants.PASSWORD) //
				.clientId(clientID) //
				.clientSecret(clientSecret) //
				.username(adminUsername) //
				.password(adminPassword) //
				.build();

That is all that is needed to trigger the error.

Configuration Quarkus v1.1.0 Keycloak 8.0.1

Environment (please complete the following information): Quarkus v1.1.0 Keycloak 8.0.1

Additional context This is needed to create Keycloak user accounts programmatically. I am able to use quarkus-oidc for programmatic authorization, but making use of the Keycloak Admin Client library fails. I have successfully used this code in non-Quarkus projects deployed on Tomcat, Wildfly, etc.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 2
  • Comments: 18 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Update: quarkus-keycloak-admin-client extension is available starting from 1.4.0.CR1

@pedroigor I’m looking for administration capabilities (create users, set passwords, etc.) through Quarkus. Isn’t the Authz Java Client only for authn/authz functionality?

@michael-schnell Take a look at the sample code below to see how you can resolve the issue by using the ResteasyClientBuilderImplementation

    Keycloak kc = KeycloakBuilder.builder()
            .serverUrl(AUTH_SERVER_BASIC_URL)
            .realm(REALM)
            .username(USERNAME)
            .password(PASSWORD)
            .clientId(CLIENT_ID)
            .resteasyClient(new ResteasyClientBuilderImpl().connectionPoolSize(10).build())
            .build();

Seems as if the documentation in the “org.keycloak.admin.client.KeycloakBuilder” ist not correct:

/**
 * Provides a {@link Keycloak} client builder with the ability to customize the underlying
 * {@link ResteasyClient RESTEasy client} used to communicate with the Keycloak server.
 * <p>
 * <p>Example usage with a connection pool size of 20:</p>
 * <pre>
 *   Keycloak keycloak = KeycloakBuilder.builder()
 *     .serverUrl("https://sso.example.com/auth")
 *     .realm("realm")
 *     .username("user")
 *     .password("pass")
 *     .clientId("client")
 *     .clientSecret("secret")
 *     .resteasyClient(new ResteasyClientBuilder().connectionPoolSize(20).build())
 *     .build();
 * </pre>
*/

It has the error: “Cannot instantiate the type ResteasyClientBuilder”

@stianst well, the issue is related to Quarkus too as it’s the combination of the two that doesn’t work so it’s normal users are complaining here first.

What is a bit of a problem is that the issue was reported as a Keycloak issue in late November and if you’re saying you’re in feature freeze, that means that we don’t have any solution for the foreseeable future, and especially for Quarkus 1.3.

I can see 3 other similar issues in the Keycloak tracker so that’s definitely something that was requested on the Keycloak side. And we had several requests on the Quarkus side in our tracker, on Zulip and on SO.

I see you closed one because it would be a breaking change so I have absolutely no idea what your plans are regarding this issue and that’s concerning for the Quarkus + Keycloak adoption.

I don’t know what the solution is but we need to find some way to allow Quarkus and Keycloak to work well together.