Java 注入带有@producer error WELD-000044的远程ejb glassfish 4,无法从null获取实例
嗯,我在使用Glassfish 4.0 build 89(开发环境为NetBeans 7.0)的生产者将远程无状态EJB注入另一个无状态EJB时遇到了一些问题。Java 注入带有@producer error WELD-000044的远程ejb glassfish 4,无法从null获取实例,java,jakarta-ee,glassfish,ejb,weld,Java,Jakarta Ee,Glassfish,Ejb,Weld,嗯,我在使用Glassfish 4.0 build 89(开发环境为NetBeans 7.0)的生产者将远程无状态EJB注入另一个无状态EJB时遇到了一些问题。为此,我将使用一个简化的命名,但我的开发结构大致相同,即: ProjectA(企业应用程序-客户端使用的应用程序) ProjectaEJB 发动战争 lib/ProjectB-ejbClient.jar lib/ProjectB-jpa.jar ProjectB(企业应用程序-幕后) ProjectB ejb(包含远程ejb i
为此,我将使用一个简化的命名,但我的开发结构大致相同,即:
- ProjectA(企业应用程序-客户端使用的应用程序)
- ProjectaEJB
- 发动战争
- lib/ProjectB-ejbClient.jar
- lib/ProjectB-jpa.jar
- ProjectB(企业应用程序-幕后)
- ProjectB ejb(包含远程ejb impl)
- ProjectB ejb(包含远程ejb impl)
- ProjectB ejbClient(Java类库)
- 包含远程接口、生产者、限定符和META-INF/beans.xml
- 包含远程接口、生产者、限定符和META-INF/beans.xml
- ProjectB jpa(java类库)
- 包含实体和META-INF/persistence.xml
ProjectA相反,它是一个完整的企业项目,带有ejb+webapp(稍后我可以添加其他使用ProjectB服务的企业项目ProjectC、D等)。
ProjectB jpa内部存储有管理项目(ProjectB)和单个Web应用程序(ProjectA和其他)之间共享的实体。
在ProjectB ejbClient类库中,我编写了以下限定符:
还有一个豆子工厂的生产商:
public class ManagementBeanFactory {
@Produces
@RemoteManagement
@EJB(lookup = "java:global/ProjectB/ProjectB-ejb/Management!it.mgmnt.ejb.ManagementRemote")
private ManagementRemote managementRemote;
}
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无法从null获取实例。
我已经一步一步地调试过了,发现AccessControl.mr
是对远程bean的引用,它不为null,因此生产者正在生成一个代理来进行调用。
如果我将@Inject@RemoteManagement
annotatin与已注释的@EJB(lookup=“…”)
交换,则一切都会完美无瑕。
我怀疑Weld正在AccessControl.mr
属性上为ManagementBeanFactory.managementRemote
属性创建代理,我认为该属性为空。
通过调试器,我发现@Inject和@EJB之间的“toString()”引用(打印在AccessControl.mr
)完全不同,似乎@EJB具有不同的生成代理的“类型”。
奇怪的是,我曾经在JBOSS 7.1.1上做过同样的事情,最后使用JavaEE6beans.xml(有不同的名称空间,等等),它工作起来很有魅力。
我不知道我是否遗漏了producer/qualifier中的某些内容,或者是否从JavaEE6更改为7(之所以需要,是因为我使用了大量无状态JSF视图和@ViewScoped bean),或者即使是Glassfish/Weld缺陷(我怀疑)。
我不想在最终版本之前使用Wildfly,我会尝试保持开发和运行时同步(同一个appserver),以获得一个更可预测的环境。
如果您在项目结构/组织中发现错误或有建议,请让我知道。我很高兴收到关于改进项目风格的提示。
谢谢你的帮助
@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;
}
//...
}