使用@producer错误注入远程ejb glassfish 4 WELD-000044无法从null获取实例

时间:2014-02-13 11:23:08

标签: java java-ee glassfish ejb weld

好吧,我在使用Glassfish 4.0 build 89的生产者(开发环境是NetBeans 7.0)将远程无状态EJB注入另一个无状态EJB时遇到了一些问题。
为此,我将使用简化命名但是我的开发结构大致相同,即:

  • ProjectA(企业应用程序 - 客户使用的应用程序)
    • 项目A-EJB
    • 项目A-战争
    • LIB /项目B-ejbClient.jar
    • LIB /项目B-jpa.jar

  • ProjectB(企业应用 - 幕后)
    • ProjectB-ejb(包含远程ejb impl)

  • ProjectB-ejbClient(Java类库)
    • 包含远程接口,生产者,限定符和META-INF / beans.xml

  • ProjectB-jpa(java类库)
    • 包含entites和META-INF / persistence.xml

ProjectB 包含一些将由许多其他项目(甚至在其他服务器上)使用的授权/管理bean,因此它们是远程的。稍后我将添加一个管理webapp,这就是为什么它是一个企业应用程序,而不是一个简单的ejb项目。
ProjectA 是一个完整的企业项目,其中包含ejb + webapp(后来我可以添加其他使用ProjectB服务的企业项目ProjectC,D等)。 内部 ProjectB-jpa 存储在管理项目(ProjectB)和单个Web应用程序(ProjectA和其他)之间共享的实体。
ProjectB-ejbClient 类库中,我将限定符写为:

@Qualifier
@Target({TYPE, METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface RemoteManagement {    
}


和豆工厂的生产者:

public class ManagementBeanFactory {
    @Produces
    @RemoteManagement
    @EJB(lookup = "java:global/ProjectB/ProjectB-ejb/Management!it.mgmnt.ejb.ManagementRemote")
    private ManagementRemote managementRemote;
}


beans.xml文件是一个简单的JavaEE 7模板,其中声明了属性version="1.1" bean-discovery-mode="all"(我从Oracle教程中获取了它)。 现在,在ProjectA-ejb中,我有类似的东西:

@Stateless
@LocalBean
public class AccessControl {
    public final static String APPLICATION_CODE = "GDS";
    @Inject 
    @RemoteManagement
    //@EJB(lookup = "java:global/ProjectB/ProjectB-ejb/Management!it.mgmnt.ejb.ManagementRemote")
    private ManagementRemote mr;

    public String performLogin(final String username, final String password) {
        String uid = mr.authenticate(username, password, APPLICATION_CODE);
        return uid;        
    }

    //...
}


部署项目时没有任何问题,但是当从Web层调用performLogin时,我得到了javax.ejb.EJBException根本原因org.jboss.weld.exceptions.NullInstanceException: WELD-000044 Unable to obtain instance from null
我已经逐步调试,我发现AccessControl.mr是对远程bean的引用,它不是null,因此生产者正在生成一个代理来进行调用。
如果我用评论的@Inject @RemoteManagement交换@EJB(lookup = "...") annotatin,一切都会完美无缺 我怀疑Weld正在AccessControl.mr属性上为ManagementBeanFactory.managementRemote属性创建一个代理,我认为该属性为null。 使用调试器,我发现“toString()”引用(打印在AccessControl.mr)在@Inject和@EJB之间完全不同,并且似乎@EJB具有不同的生成代理“类型”。
奇怪的是,我曾经使用JBOSS AS 7.1.1Final使用JavaEE 6 beans.xml(具有不同的命名空间等)做同样的事情,它就像一个魅力。
我不知道我是否遗漏了生产者/限定符中的某些东西,或者是否有什么东西从JavaEE 6变为7(需要因为我在这个领域使用了大量的无状态JSF视图和@ViewScoped bean)...或者即使它是Glassfish / Weld缺陷(我怀疑)。 我不想在它最终之前使用Wildfly AS,我会尝试保持开发和运行时同步(相同的应用程序服务器)以获得更可预测的环境。
如果您在项目结构/组织中发现错误或有任何建议,请告诉我。我很高兴收到提示以获得更好的项目风格。
谢谢你的帮助。

0 个答案:

没有答案