0

我已将我的应用程序从 Glassfish 2.2.1 迁移到 JBoss AS 6。

以前我有一个用于查找 ejbs 的通用类,下面是代码:

public class BeanUtil {
    private static InitialContext ctx; 
    public static <T> T create(Class<T> type){
        try {
            ctx = new InitialContext();
            return (T)ctx.lookup(type.getName());
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }

}

上面的类适用于 glassfish 中的查找。但是在将代码迁移到 JBoss AS 6 之后。我总是得到 javax.naming.NameNotFoundException

下面是我的 ejb 课程之一。

 @Remote
    public interface OperationPerformed {

        public void addRandomNo(String randomNos);

    }

    @Stateless
    @Remote(OperationPerformed.class)
    public class OperationPerformedImpl implements OperationPerformed {

        public void addRandomNo(String randomNos) {
        }

    }

如果我给出 jboss 在部署我的应用程序期间创建的完整 jndi 名称,那么我可以轻松查找相同的名称。但我想要用于查找的通用代码。

下面是我为查找 bean 调用的代码:

OperationPerformed operationPerformed = BeanUtil.create(OperationPerformed.class);

请建议我是否做错了什么。

4

2 回答 2

0

一些建议:

  1. 在接口和实现上同时使用@Remote 注解是很不寻常的。从你的无状态 bean 中移除这个注解,它是多余的。
  2. 我同意其他海报:
    • 不要使用远程接口进行本地查找和注入,创建另一个接口并用@Local 标记它。
    • 当涉及到 JVM 本地操作时,@EJB 注入与手动 JNDI 查找相比要优越得多(请参阅对 http://stackoverflow.com/questions/12681436/ejb-annotation-vs-jndi-lookup 的回复以及关于 SO 的类似问题) .

总而言之:

创建OperationPerformedLocal.java

@Local
public interface OperationPerformedLocal {
    public void addRandomNo(String randomNos);
}

修改你的 SLSB:

@Stateless
public class OperationPerformedImpl implements OperationPerformedLocal, OperationPerformed {

    public void addRandomNo(String randomNos) {
    }
}

并尽可能使用注入而不是 jndi 查找:

@EJB
private OperationPerformedLocal operationPerformed;

在 WAR 模块的情况下,一些 CDI@Injection魔法应该可以工作,但我还没有任何真正的经验。


现在,如果您坚持使用纯 JNDI 查找并希望它们尽可能通用,我想出了这个解决方案:

public class BeanUtil {
    private static InitialContext ctx;
    public static <T, C> T create(Class<C> implType, Class<T> interfaceType) {
        try {
            ctx = new InitialContext();

            return (T)ctx.lookup(implType.getSimpleName()+"/local");
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

你可以这样使用它:

try {
    OperationPerformedLocal operationPerformed =
        BeanUtil.create(OperationPerformedImpl.class, OperationPerformedLocal.class);
    operationPerformed.addRandomNo("123");
} catch (Exception e) {
    e.printStackTrace();
}

我知道这很难看,我有点不好意思发布它。

它不可移植,迫使您了解接口和实现类,并且“/local”部分是硬编码的,使其更加丑陋::sigh::。

将 EJB-JAR(s) 放入 EAR 会使事情变得更加复杂,jndi-name 将以 EAR 名称为前缀:

return (T)ctx.lookup("earName/" + implType.getSimpleName() + "/local");

此外,如果 SLSB 更改名称 ie ,它可能会中断@Stateless(name="someNewName")

于 2013-03-06T10:26:27.910 回答
0

我认为您可以将类名转换为 jndi 名称并正常查找

于 2013-03-05T08:01:37.430 回答