注入的 EJB 有时为 Null

发布于 2024-08-21 21:54:22 字数 98 浏览 2 评论 0原文

我通过 @EJB 注释使用无状态 EJB...大多数时候一切都正常工作,但似乎有时应该注入的内容会解析为 NULL,从而导致空指针异常。

什么可能导致这种间歇性问题?

I'm using a stateless EJB via the @EJB annotation... most of the time everything works as it should but it seems that from time to time what is supposed to be injected resolves to a NULL causing a null pointer exception.

What could cause this intermittent problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

累赘 2024-08-28 21:54:22

JBoss 4.x 不会自动将 EJB 注入 Servlet/JSP/POJO。但它也不会抱怨注释,它在运行时根本不起作用,并且对象将保持为 Null。您必须使用 JNDI 查找。

来自 JBoss 文档:

EJB @EJB 注释的查找是
可用于 servlet 和 JSP,但是
不幸的是,我们还没有更新
tomcat支持它。还有,雄猫
使用旧的 XML 格式,因此您
也不能使用XML。所以现在,你
必须通过其全局查找 EJB
JNDI 名称。这不符合规定,但是
如果你抽象得足够多,你就会
很好。

示例

public void init() throws ServletException
   {
      super.init();
      try
      {
         InitialContext ctx = new InitialContext();

         // J2EE 1.5 has not yet defined exact XML <ejb-ref> syntax for EJB3
         CalculatorLocal calculator = (CalculatorLocal)ctx.lookup("tutorial/CalculatorBean/local");
         setCalculator(calculator);
      }
      catch (NamingException e)
      {
         throw new RuntimeException(e);
      }
}

请务必使用您的 EAR 名称作为您要查找的名称的第一个部分(上例中的教程)。

参考文献:

JBoss 4.x won't automatically inject EJB's into Servlets/JSPs/POJOs. But it won't complain about the annotations either, it simply won't work at runtime, and the objects will remain Null. You have to use JNDI lookup.

From the JBoss docs:

Lookup of EJBs @EJB annotations are
usable in servlets and JSPs, but
unfortunately, we have not yet updated
tomcat to support it. Also, Tomcat
works with the old XML format so you
cannot use XML either. So for now, you
must lookup the EJB via its global
JNDI name. This is not compliant, but
if you abstract out enough you'll be
fine.

Example:

public void init() throws ServletException
   {
      super.init();
      try
      {
         InitialContext ctx = new InitialContext();

         // J2EE 1.5 has not yet defined exact XML <ejb-ref> syntax for EJB3
         CalculatorLocal calculator = (CalculatorLocal)ctx.lookup("tutorial/CalculatorBean/local");
         setCalculator(calculator);
      }
      catch (NamingException e)
      {
         throw new RuntimeException(e);
      }
}

Be sure to use the name of your EAR as the first segment in the name you are looking up (tutorial in the example above).

References:

趴在窗边数星星i 2024-08-28 21:54:22

我知道已经晚了,但我们遇到了同样的问题。最重要的信息是,这种情况有时会发生,但我们无法找出原因。

他注意到的第二件事是“父”类中的字段存在问题,我们有一个类

public abstract class SessionContained {
    @EJB
    protected SessionStoreLocal sessionStoreEJB;

    ....
}
@Stateless
public class SomeEJB extends SessionContained {

    @EJB
    SomeAnotherRemote anotherEJB;

    ...
}

在调试中 SomeAnotherRemote anotherEJB; 已正确初始化,但 SessionStoreLocal sessionStoreEJB; 为空。

我们找到了一些解决这个问题的方法,首先创建 EjbUtil 类:

public class EjbUtil
{
    public static String ejbContextClassName = System.getProperty("ejbContextClass", EJB31Context.class.getName());
    public static EjbContext ejbContext;

    public static <T> T lookup(Class<T> interfejz)
    {
        Log log = new Log(EjbUtil.class);
        try {
            log.trace("EJButil.lookup: {}", interfejz.getName());

            return getEJBContext().lookup(interfejz);
        }
        catch (Exception e) {
            log.error("Blad podczas operacji lookup", e.getCause());
        }

        return null;
    }

    public static EjbContext getEJBContext()
            throws ClassNotFoundException
    {
        if (ejbContext == null) {
            try {
                Class<EjbContext> clazz = (Class<EjbContext>)Class.forName(ejbContextClassName);
                ejbContext = clazz.getConstructor(new Class[] {}).newInstance((Object[])null);
            }
            catch (Throwable e) {
                Log log = new Log(EjbUtil.class);
                log.error("Blad podczas inicjalizacji ejbContext", e.getCause());
            }
        }
        return ejbContext;
    }
}

并添加:


public abstract class SessionContained {

    @EJB
    private SessionStoreLocal sessionStoreEJB;

    @NotLogged
    public SessionStoreLocal getSessionStoreLocal() {
        if (sessionStoreEJB == null) {
            log.warn("SessionStoreLocal is null! Trying to retrieve instance.");
            sessionStoreEJB = EjbUtil.lookup(SessionStoreLocal.class);
            if (sessionStoreEJB == null) {
                log.error("SessionStoreLocal is null! Returning null as homenet session.");
                return null;
            }

        }
        return sessionStoreEJB;
}

它看起来现在可以工作......也许它会帮助处理这个旧代码的人。

I know it's late, but we had the same problem. The most important information is that, this happens sometimes and we could not find out why.

Second thing that whe had noticed was that there was problem with fields that were in "parent" class f.e. we have a class

public abstract class SessionContained {
    @EJB
    protected SessionStoreLocal sessionStoreEJB;

    ....
}
@Stateless
public class SomeEJB extends SessionContained {

    @EJB
    SomeAnotherRemote anotherEJB;

    ...
}

In debug SomeAnotherRemote anotherEJB; was correctly initialized but SessionStoreLocal sessionStoreEJB; was null.

We found some work around for this problem, first create EjbUtil class:

public class EjbUtil
{
    public static String ejbContextClassName = System.getProperty("ejbContextClass", EJB31Context.class.getName());
    public static EjbContext ejbContext;

    public static <T> T lookup(Class<T> interfejz)
    {
        Log log = new Log(EjbUtil.class);
        try {
            log.trace("EJButil.lookup: {}", interfejz.getName());

            return getEJBContext().lookup(interfejz);
        }
        catch (Exception e) {
            log.error("Blad podczas operacji lookup", e.getCause());
        }

        return null;
    }

    public static EjbContext getEJBContext()
            throws ClassNotFoundException
    {
        if (ejbContext == null) {
            try {
                Class<EjbContext> clazz = (Class<EjbContext>)Class.forName(ejbContextClassName);
                ejbContext = clazz.getConstructor(new Class[] {}).newInstance((Object[])null);
            }
            catch (Throwable e) {
                Log log = new Log(EjbUtil.class);
                log.error("Blad podczas inicjalizacji ejbContext", e.getCause());
            }
        }
        return ejbContext;
    }
}

and add:


public abstract class SessionContained {

    @EJB
    private SessionStoreLocal sessionStoreEJB;

    @NotLogged
    public SessionStoreLocal getSessionStoreLocal() {
        if (sessionStoreEJB == null) {
            log.warn("SessionStoreLocal is null! Trying to retrieve instance.");
            sessionStoreEJB = EjbUtil.lookup(SessionStoreLocal.class);
            if (sessionStoreEJB == null) {
                log.error("SessionStoreLocal is null! Returning null as homenet session.");
                return null;
            }

        }
        return sessionStoreEJB;
}

It looks like it works for now.... Maybe it will help someone dealing with this old code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文