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 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
.
To check this isn't an issue related to CDI I've also tried using MyClass myClass = Class.forName(clazz).newInstance();
to get an instance of the class but a ClassNotFoundException
is thrown.
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 found this SO question which seems to suggest this is the case. Given that I'm developing a framework I don't believe the answer in the question is a viable solution for my needs.
I'm intrigued to find out whether creating a CDI portable extension would allow me to get an instance of the bean I want to use, but don't have enough experience in this area. Using @Observes ProcessAnnotatedType<T>
I can see beans that exist outside of the \lib
directory in an EAR file, including the ones I want to programmatically inject.
My questions are:
Am I correct in assuming this problem is occurring because
\lib\MyFramework.jar
andMyTestApp.jar
are in separate classloaders?Is there anything I can do using CDI that will allow my framework when deployed in the
\lib
directory of an EAR file to make theProvider.get()
method call to avoid Weld throwing aUnsatisfiedResolutionException
?Is there anything I can do outside of CDI to achieve same result?
Update
I've now tried moving MyFramework.jar
to the root of the EAR file and also including the jar module in the application.xml
file but the container fails to start the application due to a CDI unsatisfied dependency exception. The bean referenced in the exception can be injected when MyFramework.jar
is located in the \lib
directory and is a different bean to the one referenced in my question.