Well, I've found that even a user search requires an on-going
transaction... so committing the transaction must be the last thing you do
in a REST endpoint, or those read-only operations cannot be done. That
fixed my problem.
On Thu, Jun 15, 2017 at 1:17 PM Tomás García <tomas(a)intrahouse.com> wrote:
I've found a way to fix my problem... I just create a new session
and
start a transaction for every API request to that endpoint:
this.session = KeycloakApplication.createSessionFactory().create();
this.session.getTransactionManager().begin();
At the end of the endpoint I commit and close this generated session.
This looks so wrong... now the endpoint is way slower and the log is full
of those warning due to using internal SPIs. Any clue about a better
alternative or how to fix my original problem? If this things happen when
programming SPIs and developers don't have a guideline about how to use
Keycloak's transaction model, it will make developers life harder.
Thanks.
On Fri, Jun 9, 2017 at 10:25 AM Tomás García <tomas(a)intrahouse.com> wrote:
> Hi,
>
> I've developed an API service for Keycloak. It's a bit complex algorithm
> where the clientSession needs to be recovered later if something happens,
> so I put a note in the style of HMAC + Session ID as Keycloak does in other
> places and then next, when the algorithm needs to continue in the following
> request to the same endpoint, I recover the session. Inside the API
> service, I'm adding users so I have to commit the transaction just in case
> a ModelDuplicateException happens, as I've seen in other places of
> Keycloak's code.
>
> So I'm receiving this exception when I recover the client session from
> the note (note: a user was added and committed previously). I've tried to
> start a new transaction after committing, but yet I still get the same
> exception.
>
> Any help or ideas will be welcome. Thanks.
>
> 09:06:48,748 ERROR [io.undertow.request] (default task-5) UT005023:
> Exception handling request to /auth/realms/test/testApi/speciallogin
> : org.jboss.resteasy.spi.UnhandledException:
> java.lang.IllegalStateException: Cannot access delegate without a
> transaction
> at
>
org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76)
> at
> org.jboss.resteasy.core.ExceptionHandler.handleException(ExceptionHandler.java:212)
> at
>
org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:168)
> at
> org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:411)
> at
> org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:202)
> at
>
org.jboss.resteasy.plugins.server.servlet.ServletContainerDispatcher.service(ServletContainerDispatcher.java:221)
> at
>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:56)
> at
>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher.service(HttpServletDispatcher.java:51)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
> at
> io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
> at
>
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
> at
>
org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90)
> at
> io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
> at
>
io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
> at
> io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
> at
>
io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
> at
>
io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
> at
>
org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
> at
> io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
> at
>
io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
> 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.ja
> va:64)
> 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:4
> 3)
> at
> io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
> at
>
org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
> 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:284)
> at
>
io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
> at
>
io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
> at
>
io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
> at
> io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
> at
> io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
> at java.lang.Thread.run(Thread.java:748)
> Caused by: java.lang.IllegalStateException: Cannot access delegate
> without a transaction
> at
>
org.keycloak.models.cache.infinispan.UserCacheSession.getDelegate(UserCacheSession.java:97)
> at
>
org.keycloak.models.cache.infinispan.UserCacheSession.getUserById(UserCacheSession.java:182)
> at
>
org.keycloak.models.sessions.infinispan.ClientSessionAdapter.getAuthenticatedUser(ClientSessionAdapter.java:282)
> at
>
org.keycloak.authentication.AuthenticationProcessor.authenticateOnly(AuthenticationProcessor.java:794)
> at
> com.test.keycloak.api.services.specialLogin(TestAPIService.java:157)
> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> at
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> at
>
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.lang.reflect.Method.invoke(Method.java:498)
> at
> org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:139)
> at
>
org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:295)
> at
> org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:249)
> at
>
org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:138)
> at
>
org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:107)
> at
>
org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:133)
> at
>
org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:101)
> at
> org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:395)
> ... 37 more
>
>