如何注入另一个类加载器中存在的CDI托管bean

时间:2015-04-12 23:30:32

标签: java java-ee classloader cdi weld

我正在开发一个将在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。

我的问题是:

  1. 我是否因为\lib\lib\MyFramework.jar位于不同的类加载器中而导致出现此问题?

  2. 我有什么办法可以使用CDI在部署到EAR文件的MyTestApp.jar目录时允许我的框架进行\lib方法调用以避免Weld抛出{{ 1}}

  3. 我能在CDI之外做些什么来达到同样的效果吗?


  4. 更新

    我现在尝试将Provider.get()移动到EAR文件的根目录,并在UnsatisfiedResolutionException文件中包含jar模块,但由于CDI不满意,容器无法启动应用程序依赖性异常。当MyFramework.jar位于application.xml目录中时,可以注入异常中引用的bean,并且该bean与我的问题中引用的bean不同。

2 个答案:

答案 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?

你可以:

  • 将MyTestApp.jar移动到ear lib目录(MyFramework.jar可以在lib目录和引用MyTestApp.jar中,也可以在ear根目录下)
  • 在耳根处移动MyFramework.jar并在其清单类路径中引用MyTestApp.jar

请参阅Deployment of multiple, depended CDI jars in one EAR

答案 1 :(得分:0)

在我看来,拥有你的&#34;框架可能是一个糟糕的架构决策。取决于您的应用程序实现。也许应该是您的应用程序实现了一些框架级接口来实现您的目标。如果你拥有它,或者希望它能够工作,那么建议你的应用程序,任何真正的应用程序,通过为框架提供实现,可以影响你耳朵里所有其他应用程序的运行。这对我来说似乎是一个坏主意。如果你能够完成这项工作,并且你的耳朵中有一个应用程序提供了这个实现,CDI可能仍会因为模糊的依赖性而失败。

您可能可以使用某些特定于容器的依赖关系配置。例如,WildFly允许您配置模块到模块的依赖关系。我想,在WildFly中,有可能让一只耳朵依赖战争。

虽然以上可能有用,但在考虑之后,我认为这也是一个坏主意。你应该认真看看你真正想做的事情。我想如果你更加努力地看看你想要做什么,你会发现你的意志可能能够消除或抽象一些依赖关系,并仍然提供框架的实现,但不是来自耳中的应用程序。 / p>