users@jersey.java.net

[Jersey] Re: Erratic missing "CdiInjecteeSkippingClassAnalyzer" Exceptions

From: Joachim Kanbach <jo.ka_at_gmx.de>
Date: Tue, 22 Sep 2015 11:11:17 +0200
Hi Jakub,
 
thank your for your reply.
 
I have enabled CDI support in this module, in fact my beans.xml even declares a CDI interceptor. In those cases when the deployment and server startup code triggered by that singleton EJB run fine, CDI injection (in other beans) works without any problems thereafter.
 
I can confirm that the exception only occurs quite rarely; unfortunately the consequences when it does occur are quite bad because the singleton EJB is not available anymore then. I was thinking to catch the EJBException explicitly around this call so at least the bean will still be available. I could also add some logging in the catch clause to analyze the current server state wrt. CDI initialization etc. What would be useful information for you and how could I get hold of it? I'm still trying hard to reproduce it on my development system without success.
 
Since there's no immediate explanation, here are some more details of my design: that startup/singleton EJB actually spawns a different thread by registering a java.nio.file.WatchService in an @Asynchronous method, which is then triggered by a file on the file system present at server startup (I know using java.nio.file is not covered by the Java EE specification, but this is required/convenient for our environment and didn't cause any other problems yet). So it's one of the GlassFish EJB thread pool threads where the exception happens:
 
[2015-09-17T20:38:15.041+0200] [glassfish 4.1] [WARNING] [] [javax.enterprise.ejb.container] [tid: _ThreadID=114 _ThreadName=__ejb-thread-pool1] [timeMillis: 1442515095041] [levelValue: 900] [[
javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
 
Another thing that might be of importance is that I use @ExcludeDefaultInterceptors on both the singleton and the called stateless EJB.
 
And finally, what I find confusing is that I don't even use CDI injection in any of those classes involved in the issue. The stateless EJB is injected with @EJB into the singleton, and both the singleton and the stateless EJB only have other @EJB, @PersistenceContext and @Resource (javax.annotation.Resource) annotations.
 
 
Regards,
Joachim
 
Gesendet: Dienstag, 22. September 2015 um 09:58 Uhr
Von: "Jakub Podlesak" <jakub.podlesak@oracle.com>
An: users@jersey.java.net
Betreff: [Jersey] Re: Erratic missing "CdiInjecteeSkippingClassAnalyzer" Exceptions
Hi Joachim,
 
We bumped into a similar issue already in a different container.
 
The problem happens if you disable CDI support. Then EJB integration breaks.
I do not understand why you can see the issue only occasionally. Could you please double check?
 
Then to enable CDI, it should be sufficient to insert an empty beans.xml file into your application: <beans/>
 
Could you please try the above suggested workaround, and eventually file a bug with a simple
reproducer application attached? (https://java.net/jira/browse/JERSEY)
 
Thanks,
 
~Jakub
 
On 22 Sep 2015, at 09:05, Joachim Kanbach <jo.ka@gmx.de> wrote:
 
I hope this is the right mailing list to ask since my problem is apparently in the Jersey-GlassFish integration layer (jersey-gf-cdi.jar/jersey-gf-ejb.jar).
 
I have a setup where a @Singleton @Startup EJB makes calls to another @Stateless EJB. Due to the program layout, it's possible that those calls are triggered right at the server startup through the @PostConstruct method (the whole architecture is a little more complex, I can give the deails if required, but I first need guidance where to look for clues at all).
 
On our build system, the nightly build and deploy occasionally fails with a stack trace like this:
 
javax.ejb.EJBException: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
        at com.sun.ejb.containers.StatelessSessionContainer._getContext(StatelessSessionContainer.java:435)
        at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2579)
        at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1971)
        at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:210)
        at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:88)
        at com.sun.proxy.$Proxy224.deleteKeyMetaMappingByDbid(Unknown Source)
        at com.mycompany.cfg.__EJB31_Generated__ConfigurationService__Intf____Bean__.deleteKeyMetaMappingByDbid(Unknown Source)
        [...]
Caused by: javax.ejb.EJBException: javax.ejb.CreateException: Could not create stateless EJB
        [...]
Caused by: javax.ejb.CreateException: Could not create stateless EJB
        [...]
Caused by: A MultiException has 1 exceptions.  They are:
1. java.lang.IllegalStateException: Could not find an implementation of ClassAnalyzer with name CdiInjecteeSkippingClassAnalyzer
        at org.jvnet.hk2.internal.Collector.throwIfErrors(Collector.java:88)
        at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:928)
        at org.jvnet.hk2.internal.ServiceLocatorImpl.inject(ServiceLocatorImpl.java:902)
        at org.glassfish.jersey.gf.ejb.internal.EjbComponentInterceptor.inject(EjbComponentInterceptor.java:71)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        [...]
Caused by: java.lang.IllegalStateException: Could not find an implementation of ClassAnalyzer with name CdiInjecteeSkippingClassAnalyzer
        at org.jvnet.hk2.internal.ServiceLocatorImpl.getAnalyzer(ServiceLocatorImpl.java:2249)
        at org.jvnet.hk2.internal.Utilities.getClassAnalyzer(Utilities.java:172)
        at org.jvnet.hk2.internal.Utilities.justInject(Utilities.java:927)
        ... 102 more
 
"ConfigurationService" is the @Stateless EJB on which deleteKeyMetaMappingByDbid() should be called
 
This happens quite rarely, not more than once a week or so. I didn't manage to recreate the situation outside of the build period. It could be that the system is under very high load during that time. But I couldn't find a pattern that separates the successful deployments, where the exact same sequence of method calls and EJB creations happens, from the ones failing with this stack trace.
 
I've looked at the source code a little and realized that "CdiInjecteeSkippingClassAnalyzer" must be the HK2 internal name used for org.glassfish.jersey.gf.cdi.internal.InjecteeSkippingAnalyzer. But if you search for this on the web, you get only a very few hits, none of which is helpful.
 
So my question is how an error like this could be possible at all? I was wondering if the cause might be that HK2 may not have finished initializing properly before the @Stateless EJB is to be injected and used (cf. my remark regarding system load)?