注入的EJB有时为空

问题描述 投票:0回答:2

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

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

ejb-3.0 ejb
2个回答
1
投票

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 名称作为您要查找的名称的第一个部分(上例中的

tutorial
)。

参考资料:


0
投票

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

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

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;
}

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

© www.soinside.com 2019 - 2024. All rights reserved.