Open glassfishrobot opened 7 years ago
@mjremijan Commented I have an update to this. Also using GlassFish Server Open Source Edition 5.0 (build 23). I tried deploying 2 application to GlassFish Server Open Source Edition 5.0 (build 23), each of which has their own IdentityStore. 1st application deploys and runs ok. 2nd application deploys but when I try to run the application I get the same LinkageError as described above. So, this basically means I can only have 1 application deployed that uses a custom IdentityStore :(
@mjremijan Commented A bit more info on this. I just tried with Payara Server 5.0.0.174-SNAPSHOT #badassfish (build 36) and got the same results as GlassFish.
@arjantijms Commented Hmmm, I'm sure going to take a look at this.
If you want, in the meantime you could do a quick check on say WildFly 10 with Soteria bundled in the war (if you're using a maven project just don't make the dependency provided).
@mjremijan Commented
I have an additional update on this. I was playing around with them IdentityStore
implementation. If found that if my validate
method looks like this:
public CredentialValidationResult validate(TestCredential credential) { ... }
Then I get the Linkage errors as described above. However, if I change the method to look like this:
@Override public CredentialValidationResult validate(Credential credential) { ... }
Then the problem with the linkage error goes away. Unfortunately, with the latter, a typecast is needed to get to the concrete Credential
object.
So to get things working after redeployment, the 2nd method signature is needed. Not sure if this is a bug or not, i'll let you guys decide.
The former method signature is used in the Soteria "test/app-custom/src/main/java/org/glassfish/soteria/test/TestIdentityStore.java" as:
public CredentialValidationResult validate(UsernamePasswordCredential usernamePasswordCredential) { ... }
I was basing my code off this example. So maybe this example needs to be updated?
@arjantijms Commented
By using the @Override public CredentialValidationResult validate(Credential credential) { ... }
version you override the convenience method that does this type case essentially for you.
It's this default method:
default CredentialValidationResult validate(Credential credential) {
try {
return CredentialValidationResult.class.cast(
MethodHandles.lookup()
.bind(this, "validate", methodType(CredentialValidationResult.class, credential.getClass()))
.invoke(credential));
} catch (NoSuchMethodException e) {
return NOT_VALIDATED_RESULT;
} catch (Throwable e) {
throw new IllegalStateException(e);
}
}
As you can see it uses some MethodHandle magic to find the right method.
@mjremijan Commented
After changing my code to use the exact method signature @Override public CredentialValidationResult validate(Credential credential) { ... }
it's working fine in both "GlassFish Server Open Source Edition 5.0 (build 23)" and "Payara Server 5.0.0.174-SNAPSHOT #badassfish (build 36)".
@mjremijan if I understand it correctly, this was a fault in your code that was already solved. Can we close this issue?
Im running into the same issue using wildfly 16 docker image, shipping soteria 1.0. It happens only on subsequent deployment in my case: If I start the image, then make a first deployment of my ear using cargo, it works fine. If I redeploy the same ear using cargo without recreating the container, I run into this issue. So far only involving a single of the few identity stores present in the archive. The identity store overload seems correct:
public CredentialValidationResult validate(AuthTokenCredential authTokenCredential) {
}
With AuthTokenCredential
a simple pojo class extending Credential.
The stack:
2019-04-04 06:35:36,227 ERROR [io.undertow.request] (default task-1) UT005023: Exception handling request to /Gestemps-ws/front/user/me/token: java.lang.IllegalStateException: java.lang.IllegalAccessException: no such method: be.valuya.gestemps.auth.identitystore.GestempsUserTokenIdentityStore.validate(AuthTokenCredential)CredentialValidationResult/invokeSpecial
at javax.security.enterprise.api@1.0//javax.security.enterprise.identitystore.IdentityStore.validate(IdentityStore.java:113)
at deployment.Gestemps-ear.ear.Gestemps-ejb-2019.04.02-SNAPSHOT.jar//be.valuya.gestemps.auth.identitystore.GestempsUserTokenIdentityStore$Proxy$_$$_WeldClientProxy.validate(Unknown Source)
at org.glassfish.soteria@1.0//org.glassfish.soteria.cdi.DefaultIdentityStoreHandler.validate(DefaultIdentityStoreHandler.java:97)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
...
Caused by: java.lang.IllegalAccessException: no such method: be.valuya.gestemps.auth.identitystore.GestempsUserTokenIdentityStore.validate(AuthTokenCredential)CredentialValidationResult/invokeSpecial
at java.base/java.lang.invoke.MemberName.makeAccessException(MemberName.java:959)
at java.base/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1101)
at java.base/java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:2030)
at java.base/java.lang.invoke.MethodHandles$Lookup.bind(MethodHandles.java:1694)
at javax.security.enterprise.api@1.0//javax.security.enterprise.identitystore.IdentityStore.validate(IdentityStore.java:108)
... 70 more
Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "be.valuya.gestemps.auth.identitystore.GestempsUserTokenIdentityStore.validate(Lbe/valuya/gestemps/auth/identitystore/AuthTokenCredential;)Ljavax/security/enterprise/identitystore/CredentialValidationResult;" the class loader 'javax.security.enterprise.api@1.0' @32c333bf (instance of org.jboss.modules.ModuleClassLoader, child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) of the current class, javax/security/enterprise/identitystore/IdentityStore, and the class loader 'deployment.Gestemps-ear.ear.Gestemps-ejb-2019.04.02-SNAPSHOT.jar' @54c15c15 (instance of org.jboss.modules.ModuleClassLoader, child of 'app' jdk.internal.loader.ClassLoaders$AppClassLoader) for the method's defining class, be/valuya/gestemps/auth/identitystore/GestempsUserTokenIdentityStore, have different Class objects for the type be/valuya/gestemps/auth/identitystore/AuthTokenCredential used in the signature
at java.base/java.lang.invoke.MethodHandleNatives.resolve(Native Method)
at java.base/java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1070)
at java.base/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1098)
... 73 more
I will be testing previous wildfly and report
Reverting to previous wildfly version did not change anything. Overriding the IdentityStore#validate method (taking Credential
as argument) rather that implementing one handling an application-typed credential fixed the issue, like for the original poster. So, in a custom identity store deployed in an ejb part of an ear on a wildfly 16 server, implementing:
public CredentialValidationResult validate(MyApplicationCredential credential) {/** **/}
does NOT work as documented in javax.security.enterprise.identitystore.IdentityStore. Starting from the second deployment of the ear archive, without restarting the application server, it produces a linkage error as pasted above. This happen as soon as the identity store is looked upon.@Override public CredentialValidationResult validate(Credential credential) {/** **/}
DOES work as intendedI've encountered this with WildFly 16 too.
I believe application-typed implementations should work as it's documented in javax.security.enterprise.identitystore.IdentityStore.
Would be interesting to see how Open Liberty behaves here, since they use another implementation of EE Security.
I've run into an interesting problem....
I am using the version of Soteria built into "GlassFish Server Open Source Edition 5.0 (build 23)". What I'm working on is basically following the Soteria "app-custom" test application to create my own
IdentityStore
andCredential
. My code can be found at "https://github.com/mjremijan/thoth-security-api/tree/master/11-security-api-get-cdi-bean/src/main/java/org/thoth/jeesa/security"The issue I found is on 1st deploy to GlassFish I can access my application and it works fine. But if I Redeploy the application, the Redeploy works fine but when I access the application I get a 500 Internal Server Error. I put a try-catch block in my HttpAuthenticationMechanism implementation and was able to capture the following stack trace (see below) in the #validateRequest() method when the IdentityStoreHandler#validate() method is called.
Again, on 1st deploy there are no problems. This only happens on a Redeploy of the application. The work-around is to stop the GlassFish domain and start it again. When I restart the domain, the application starts working again and I don't get this linkage error. Not very good for development to have to restart the domain every time the application needs to be redeployed :(
I have only tried this on "GlassFish Server Open Source Edition 5.0 (build 23)". I've not tried it on any other "EE8" server.
java.lang.IllegalStateException: java.lang.IllegalAccessException: no such method: org.thoth.jeesa.security.identitystore.TestIdentityStore.validate(TestCredential)CredentialValidationResult/invokeSpecial at javax.security.enterprise.identitystore.IdentityStore.validate(IdentityStore.java:113) at org.glassfish.soteria.cdi.DefaultIdentityStoreHandler.validate(DefaultIdentityStoreHandler.java:97) at sun.reflect.GeneratedMethodAccessor290.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at org.jboss.weld.bean.proxy.AbstractBeanInstance.invoke(AbstractBeanInstance.java:38) at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:100) at org.jboss.weldx.security.enterprise.identitystore.IdentityStoreHandler$1763020431$Proxy$_$$_WeldClientProxy.validate(Unknown Source) at org.thoth.jeesa.security.authentication.mechanism.TestHttpAuthenticationMechanism.validateRequest(TestHttpAuthenticationMechanism.java:67) at org.thoth.jeesa.security.authentication.mechanism.TestHttpAuthenticationMechanism$Proxy$_$$_WeldClientProxy.validateRequest(Unknown Source) at org.glassfish.soteria.mechanisms.jaspic.HttpBridgeServerAuthModule.validateRequest(HttpBridgeServerAuthModule.java:114) at org.glassfish.soteria.mechanisms.jaspic.DefaultServerAuthContext.validateRequest(DefaultServerAuthContext.java:76) at com.sun.web.security.RealmAdapter.validate(RealmAdapter.java:1675) at com.sun.web.security.RealmAdapter.invokeAuthenticateDelegate(RealmAdapter.java:1533) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:577) at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:620) at org.apache.catalina.core.StandardPipeline.doChainInvoke(StandardPipeline.java:596) at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:155) at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:371) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:238) at com.sun.enterprise.v3.services.impl.ContainerMapper$HttpHandlerCallable.call(ContainerMapper.java:463) at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:168) at org.glassfish.grizzly.http.server.HttpHandler.runService(HttpHandler.java:206) at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:180) at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:242) at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:284) at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:201) at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:133) at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77) at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:539) at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:112) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:117) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:56) at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:137) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:593) at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:573) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.IllegalAccessException: no such method: org.thoth.jeesa.security.identitystore.TestIdentityStore.validate(TestCredential)CredentialValidationResult/invokeSpecial at java.lang.invoke.MemberName.makeAccessException(MemberName.java:869) at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:990) at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:1382) at java.lang.invoke.MethodHandles$Lookup.bind(MethodHandles.java:1146) at javax.security.enterprise.identitystore.IdentityStore.validate(IdentityStore.java:108) ... 39 more Caused by: java.lang.LinkageError: loader constraint violation: when resolving method "org.thoth.jeesa.security.identitystore.TestIdentityStore.validate(Lorg/thoth/jeesa/security/credential/TestCredential;)Ljavax/security/enterprise/identitystore/CredentialValidationResult;" the class loader (instance of org/apache/felix/framework/BundleWiringImpl$BundleClassLoaderJava5) of the current class, javax/security/enterprise/identitystore/IdentityStore, and the class loader (instance of org/glassfish/web/loader/WebappClassLoader) for the method's defining class, org/thoth/jeesa/security/identitystore/TestIdentityStore, have different Class objects for the type org/thoth/jeesa/security/credential/TestCredential used in the signature at java.lang.invoke.MethodHandleNatives.resolve(Native Method) at java.lang.invoke.MemberName$Factory.resolve(MemberName.java:962) at java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:987) ... 42 more