java 在 POJO 中使用 EJB 注入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13249908/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using EJB injection in a POJO
提问by Sabry Shawally
I know that injection using the @EJB annotation is only possible in an EJB class, a servlet, or a JSF managed bean, but in the same time I need to have an instance of a some injected business interface in a POJO class, so I thought of doing the following:
我知道使用 @EJB 注释的注入只能在 EJB 类、servlet 或 JSF 托管 bean 中进行,但同时我需要在 POJO 类中有某个注入业务接口的实例,所以我想到做以下事情:
in my JSF managed bean
在我的 JSF 托管 bean 中
@EJB BusinessInterfaceLocal businessInterface;
private void someMethod(){
PojoInterface pojo = new PojoClass(this.businessInterface);
}
and in my POJO class I have this constructor
在我的 POJO 类中,我有这个构造函数
BusinessInterfaceLocal businessInterface;
public PojoClass(BusinessInterfaceLocal businessInterface){
this.businessInterface = businessInterface;
//The following throws a Null Pointer Exception
this.businessInterface.someMethodCall();
}
Shouldn't the above work correctly? but it doesn't, the businessInterface object at the PojoClass is evaluated to null, and thus throwing a null pointer exception.
以上不应该正常工作吗?但事实并非如此,PojoClass 中的 businessInterface 对象被评估为空,从而引发空指针异常。
I was hoping if anyone could point me out, on what I'm doing wrong.
我希望如果有人能指出我做错了什么。
Thanks in advance.
提前致谢。
回答by Qkyrie
verification
确认
Is it possible you create the PojoClass before the EJB gets injected. By that I mean, where do you invoke "someMethod"? Is it in the constructor of the managed bean? A variable simply does not lose its referenced value.
是否有可能在注入 EJB 之前创建 PojoClass。我的意思是,你在哪里调用“someMethod”?是在托管 bean 的构造函数中吗?变量不会丢失其引用值。
You said you could see the BusinessInterfaceLocalbean isn't null in the Managed bean, can you verify you create the Pojo after that check?
你说你可以看到托管 bean 中的 BusinessInterfaceLocalbean 不为空,你能验证你在检查后创建了 Pojo 吗?
Alternative solutions:
替代解决方案:
solution 1You can use the POJO as a stateless bean, I don't see any problems in doing that, unless of course you are trying to use the POJO outside of your EE container, which is, by the looks of it not the case.
解决方案 1您可以将 POJO 用作无状态 bean,我认为这样做没有任何问题,当然除非您尝试在 EE 容器之外使用 POJO,从外观上看并非如此.
Making the POJO stateless would make you able to inject the EJB.
使 POJO 无状态将使您能够注入 EJB。
solution 2OR a JNDI lookup, implemented as followed:
解决方案 2或 JNDI 查找,实现如下:
@Stateless(name="myEJB")
public class MyEJB {
public void ejbMethod() {
// business logic
}
}
public class TestEJB {
public static void main() {
MyEJB ejbRef = (MyEJB) new InitialContext().lookup("java:comp/env/myEJB");
ejbRef.ejbMethod();
}
}
回答by Tom Anderson
With the code you show above, the only way that a NullPointerException
could be thrown at the line indicated is if the businessInterface
field in the managed bean is null. References cannot mysteriously become null when passed from one object to another, and the PojoClass
doesn't do anything which would cause the variable to become null. I suggest you do some debugging or logging to definitively determine the value of the field in the managed bean at the point at which the constructor is called. If it is null, then the problem is with injection into the bean, and is not anything to do with the POJO, and you should fix that.
使用上面显示的代码,NullPointerException
可以在指示的行处抛出a 的唯一方法是businessInterface
托管 bean 中的字段是否为空。当从一个对象传递到另一个对象时,引用不会神秘地变为空,并且PojoClass
不会做任何会导致变量变为空的事情。我建议您进行一些调试或日志记录,以明确确定在调用构造函数时托管 bean 中字段的值。如果它为空,那么问题出在注入到 bean 中,与 POJO 无关,您应该解决这个问题。
If the exception being thrown is actually from deeper than the line you show, then this could be a problem with the use of an EJB proxy in the wrong context. As you may know, a reference to an EJB is typically not a reference to the EJB itself, but rather to some sort of proxy which passes method calls on to the EJB; the proxy exists so that the container can step in and do things like start transactions, check authorization, and so on. The proxy may need to call on certain contextual resources to do its work which are available when the EJB is accessed from the managed bean but not, for some non-obvious and twisted reason, from the POJO. The unavailability of those resources could lead to a NullPointerException
. Now, i think it is highly unlikely that simply passing a reference from a managed bean to a POJO would get you into that situation; this would only happen if you did something like accessing the managed bean from a different thread. So, it's probably not this!
如果抛出的异常实际上比您显示的行更深,那么这可能是在错误的上下文中使用 EJB 代理的问题。您可能知道,对 EJB 的引用通常不是对 EJB 本身的引用,而是对某种将方法调用传递给 EJB 的代理的引用;代理存在以便容器可以介入并执行诸如启动事务、检查授权等操作。代理可能需要调用某些上下文资源来完成其工作,这些资源在从托管 bean 访问 EJB 时可用,但由于某些不明显和扭曲的原因,从 POJO 访问时则不可用。这些资源的不可用可能会导致NullPointerException
. 现在,我认为简单地将引用从托管 bean 传递到 POJO 不太可能让您陷入这种情况;这只会发生在您执行诸如从不同线程访问托管 bean 之类的操作时。所以,应该不是这个!
回答by Sabry Shawally
The problem was caused by me trying to use the businessInterface object in the constructor, while the container injects the ejb only after it's done instantiating the managed bean,
问题是由于我试图在构造函数中使用 businessInterface 对象引起的,而容器仅在完成托管 bean 的实例化后才注入 ejb,
reference to a similar question https://stackoverflow.com/a/6537228/1249304
参考一个类似的问题https://stackoverflow.com/a/6537228/1249304
What I did is that I created a method and annotated it with the @PostConstruct annotation, this way after the container is done with instantiating the managed bean, the annotated method gets called and the businessInterface object is no longer null
我所做的是我创建了一个方法并使用 @PostConstruct 注释对其进行了注释,这样在容器完成实例化托管 bean 之后,注释的方法被调用并且 businessInterface 对象不再为空
@PostContsruct
public void onInit(){
//businessInterface is no longer null
businessInterface.someMethod();
}