0

Tapestry アプリケーションで EJB を取得する際に問題があります。アプリケーションの他の部分は OSGi バンドルにあり、すべて Glassfish にデプロイされます。

現在、これは私のものがどのように見えるかです:

私のインターフェース(jarとしてパッケージ化):

@Remote
public interface MyEJBInterface {
    public static final String JNDI_NAME = "ejb/MyEJBInterface";
    public String sayHello(String name);

}

私の実装(バンドルとしてパッケージ化):

@Stateless
@EJB(name = MyEJBInterface.JNDI_NAME, beanInterface = MyEJBInterface.class)
public class MyEJBImplementation implements MyEJBInterface {

    @Override
    public String sayHello(String name) {
        return "Hello " + name;
    }
}

AppModule クラスの私の Tapestry ビルド メソッド:

public MyEJBService buildMyEJBService() {
    MyEJBInterface myEjb = new JndiLookupHelper<MyEJBInterface>().lookupNoPrefix(MyEJBInterface.JNDI_NAME);

    MyEJBService service = new MyEJBServiceMock(myEjb);

    return service;
}

そして、私はそれを次のように調べます:

public class JndiLookupHelper<T> {
    private T remoteObject;

    public T lookupNoEjbPrefix(String name) {
        String jndiPath = "java:comp/env/" + name;
        try {
            InitialContext ic = new InitialContext();
            remoteObject = (T) ic.lookup(jndiPath);
        } catch (NamingException ne) {
            ne.printStackTrace();
        }
        return remoteObject;
    }
}

私の問題は、EJB が見つからず、例外がスローされることです。

javax.naming.NamingException: Lookup failed for 'java:comp/env/ejb/MyEJBInterface' in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming} [Root exception is javax.naming.NameNotFoundException: No object bound to name java:comp/env/ejb/MyEJBInterface]
4

3 に答える 3

1

あなたはこれがより良いと思うかもしれません:

public static class EjbServiceBuilder<T> implements ServiceBuilder<T> {
    private Class<T> type;
    private String name;

    public EjbServiceBuilder<T>(Class<T> type, String name) {
        this.type= type;
        this.name = name;
    }

    public T buildService(ServiceResources resources) {
        try {
            return type.cast(InitialContext.doLookup(name));
        } catch (NamingException e) {
            throw new RuntimeException(e);
        }
    }
}

public static void bind(ServiceBinder binder) {
    binder.bind(MyEJBInterface.class, new EjbServiceBuilder<MyEJBInterface>(MyEJBInterface.class, MyEJBInterface.JNDI_NAME));
    binder.bind(MyEJBOtherInterface.class, new EjbServiceBuilder<MyEJBOtherInterface>(...));

    // MyEJBInterface will be injected into MyEJBServiceMock constructor
    binder.bind(MyEJBService.class, MyEJBServiceMock.class);
}
于 2013-09-26T08:17:20.900 に答える
0

私はついに解決策にたどり着きました。ここにあります:

インターフェース:

public interface MyEJBInterface {
    public static final String JNDI_NAME = "java:global/ejb/MyEJBInterface";
    public String sayHello(String name);

}

実装:

@Stateless
@EJB(name = MyEJBInterface.JNDI_NAME, beanInterface = MyEJBInterface.class)
public class MyEJBImplementation implements MyEJBInterface {

    @Override
    public String sayHello(String name) {
        return "Hello " + name;
    }
}

ビルド方法:

public MyEJBService buildMyEJBService() {
    MyEJBInterface myEjb = new JndiLookupHelper<MyEJBInterface>().lookup(MyEJBInterface.JNDI_NAME);

    MyEJBService service = new MyEJBServiceMock(myEjb);

    return service;
}

ルックアップ:

public class JndiLookupHelper<T> {

    private T remoteObject;

    @SuppressWarnings("unchecked")
    public T lookup(String name) {
        try {
            remoteObject = (T) InitialContext.doLookup(name);
        } catch (NamingException ne) {
            ne.printStackTrace();
        }
        return remoteObject;
    }
}
于 2013-09-24T14:15:37.927 に答える