Ejb 3查找不在Jboss AS 6中工作

时间:2013-03-05 07:52:31

标签: jboss glassfish ejb-3.0 jboss6.x

我已将我的应用程序从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);

如果我做错了,请建议。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

一些建议:

  1. 在接口和实现上同时使用@Remote注释是很不寻常的。从无状态bean中删除此注释,这是多余的。
  2. 我同意其他海报:
    • 不要使用远程接口进行本地查找和注入,创建另一个接口并使用@Local标记它。
    • 当谈到JVM本地操作时,与手动JNDI查找相比,@ EJB注入非常有用(请参阅对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放入EAR会使事情进一步复杂化,jndi-name将以EAR名称为前缀:

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

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