1 Reply Latest reply on Apr 17, 2015 8:41 AM by mkouba

    Is it possible to use a CDI portable extension to lookup and inject beans that exist in a different classloader?

    paul.holding

      I am working on a framework which will be used in Java EE applications and therefore is likely to be deployed in the \lib directory of an EAR file.

      The framework will use CDI to programmatically lookup and inject beans that have been annotated with a custom annotation which are located in the Java EE application that is using the framework. The problem I've got is when the Provider.get() method from javax.enterprise.Provider<T> is called by my framework to get an instance of the bean, Weld throws a UnsatisfiedResolutionException.

      The structure of EAR file I'm using for testing purposes is as follows:

      MyTestApp.ear

      +\lib\MyFramework.jar <----Contains the framework invoking the Provider.get() method

      +MyTestApp.jar        <----Contains the bean I want to inject

      My test application's EAR contains an application.xml file which includes <library-directory>lib</library-directory>.

      I believe this problem is occurring because the bean I want to inject exists in a separate classloader. i.e. \lib\MyFramework.jar is in a different classloader to MyTestApp.jar. I have seen a workaround that suggest moving MyFramework.jar to the root of the EAR file so that it is in the same classpath as MyTestApp.jar but I would like to explore whether there other options available.

      I'm intrigued to find out whether using a CDI portable extension in my framework would allow me to get an instance of the beans that have been annotated with the custom annotation, even though these beans exist in a different classloader. I have created an extension that uses @Observes @WithAnnotations({ MyCustomAnnotation.class }) ProcessAnnotatedType<T> pat and I can see the beans in a different classloader that have been annotated with the custom annotation. My assumption is that if an extension running in CDI container can see the beans during the ProcessAnnotatedType lifecycle phase then it should be able to lookup and inject them, but despite many hours of searching I can't see how to do it.

      Is what I'm trying to do possible or is the only option to ensure MyFramework.jar is in the root of the EAR file rather than the \lib directory of the EAR file?

      If its relevant I am using GlassFish 4 which is running Weld 2.0.0 SP1 and GlassFish 4.1 which is running Weld 2.2.10 SP1.

      Kind Regards

      Paul