Hi Joachim,
Please see inline…
> On 22 Sep 2015, at 11:11, Joachim Kanbach <jo.ka_at_gmx.de> wrote:
>
> 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.
Well, you can try to search your server log for something like:
WARNING: Could not load service class org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider
If you see such a log message before you get a failure, that would confirm how it happens.
>
> 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.
Since you do not use any CDI injection, there should be a workaround for you:
implemement a Jersey component provider impl (
https://jersey.java.net/apidocs/2.21/jersey/org/glassfish/jersey/server/spi/ComponentProvider.html <
https://jersey.java.net/apidocs/2.21/jersey/org/glassfish/jersey/server/spi/ComponentProvider.html>)
See
https://jersey.java.net/documentation/latest/user-guide.html#d0e16756 <
https://jersey.java.net/documentation/latest/user-guide.html#d0e16756> for an example.
The only important method that you need to implement is initialize:
@Override
public void initialize(final ServiceLocator locator) {
final ClassAnalyzer defaultClassAnalyzer =
locator.getService(ClassAnalyzer.class, ClassAnalyzer.DEFAULT_IMPLEMENTATION_NAME);
final DynamicConfiguration dc = Injections.getConfiguration(locator);
final ScopedBindingBuilder bindingBuilder =
Injections.newBinder(defaultClassAnalyzer);
bindingBuilder.analyzeWith(ClassAnalyzer.DEFAULT_IMPLEMENTATION_NAME)
.to(ClassAnalyzer.class)
.named(“CdiInjecteeSkippingClassAnalyzer");
Injections.addBinding(bindingBuilder, dc);
dc.commit();
}
your bind method should always return false.
You need to register your component provider in a META-INF/services registry and bundle it with your application.
I have not tested, but the above workaround should hopefully help.
~Jakub
>
>
> Regards,
> Joachim
>
> Gesendet: Dienstag, 22. September 2015 um 09:58 Uhr
> Von: "Jakub Podlesak" <jakub.podlesak_at_oracle.com>
> An: users_at_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 <https://java.net/jira/browse/JERSEY>)
>
> Thanks,
>
> ~Jakub
>
> On 22 Sep 2015, at 09:05, Joachim Kanbach <jo.ka_at_gmx.de <x-msg://21/jo.ka_at_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)?