我正在开发一个将在Java EE应用程序中使用的框架,因此可能会部署在EAR文件的\lib
目录中。
该框架将使用CDI以编程方式查找和注入位于使用该框架的Java EE应用程序中的bean。我遇到的问题是,当我的框架调用来自Provider.get()
的{{1}}方法来获取bean的实例时,Weld会抛出javax.enterprise.Provider<T>
。
要检查这不是与CDI相关的问题,我还尝试使用UnsatisfiedResolutionException
来获取该类的实例,但会抛出MyClass myClass = Class.forName(clazz).newInstance();
。
用于测试目的的EAR文件的结构如下:
ClassNotFoundException
我的测试应用程序的EAR包含一个包含MyTestApp.ear
+\lib\MyFramework.jar <----Contains the framework invoking the Provider.get() method
+MyTestApp.jar <----Contains the bean I want to inject
的application.xml文件。
我相信这个问题正在发生,因为我想要注入的bean存在于一个单独的类加载器中。即<library-directory>lib</library-directory>
与\lib\MyFramework.jar
位于不同的类加载器中。我发现这SO question似乎暗示了这种情况。鉴于我正在开发一个框架,我不相信问题的答案是满足我需求的可行解决方案。
我很想知道创建CDI便携式扩展是否允许我获取我想要使用的bean的实例,但是在这方面没有足够的经验。使用MyTestApp.jar
我可以看到存在于EAR文件中@Observes ProcessAnnotatedType<T>
目录之外的bean,包括我想以编程方式注入的bean。
我的问题是:
我是否因为\lib
和\lib\MyFramework.jar
位于不同的类加载器中而导致出现此问题?
我有什么办法可以使用CDI在部署到EAR文件的MyTestApp.jar
目录时允许我的框架进行\lib
方法调用以避免Weld抛出{{ 1}}
我能在CDI之外做些什么来达到同样的效果吗?
更新
我现在尝试将Provider.get()
移动到EAR文件的根目录,并在UnsatisfiedResolutionException
文件中包含jar模块,但由于CDI不满意,容器无法启动应用程序依赖性异常。当MyFramework.jar
位于application.xml
目录中时,可以注入异常中引用的bean,并且该bean与我的问题中引用的bean不同。
答案 0 :(得分:0)
1:是的
2:实际上我不知道
3:是的,您必须了解耳朵类加载器层次结构,ear lib目录中的jar是在耳朵级别加载的,因此在所有子类加载器中都可用(在耳朵中每个组件有一个子类加载器)。
这意味着从MyTestApp.jar ear子类加载器可以看到MyFramework.jar,但反之为false。
请参阅In java EE, which jars should I put in the library dir?
你可以:
答案 1 :(得分:0)
在我看来,拥有你的&#34;框架可能是一个糟糕的架构决策。取决于您的应用程序实现。也许应该是您的应用程序实现了一些框架级接口来实现您的目标。如果你拥有它,或者希望它能够工作,那么建议你的应用程序,任何真正的应用程序,通过为框架提供实现,可以影响你耳朵里所有其他应用程序的运行。这对我来说似乎是一个坏主意。如果你能够完成这项工作,并且你的耳朵中有一个应用程序提供了这个实现,CDI可能仍会因为模糊的依赖性而失败。
您可能可以使用某些特定于容器的依赖关系配置。例如,WildFly允许您配置模块到模块的依赖关系。我想,在WildFly中,有可能让一只耳朵依赖战争。
虽然以上可能有用,但在考虑之后,我认为这也是一个坏主意。你应该认真看看你真正想做的事情。我想如果你更加努力地看看你想要做什么,你会发现你的意志可能能够消除或抽象一些依赖关系,并仍然提供框架的实现,但不是来自耳中的应用程序。 / p>