2013-07-08 158 views
0

我無法從另一個ejb模塊注入遠程ejb。我有應用程序拆分成一個庫和兩個ejb模塊。我嘗試通過遠程接口從ejb模塊訪問另一個模塊,並獲取javax.naming.NameNotFoundException。 我嘗試從NewBean「@EJB private CountryFacadeRemote」訪問。我用了glassfish。
我必須配置一些東西?謝謝。從另一個ejb模塊調用ejb遠程接口

Download SourceCode

MyAppTestEJBDomainLibrary:

*國家:

public class Country implements Serializable { 
private static final long serialVersionUID = 1L; 
@Id 
@Basic(optional = false) 
@Column(name = "id") 
private Long id; 
@Basic(optional = false) 
@Column(name = "name") 
private String name; 
... 

} 

* CountryFacadeRemote:

@Remote 
public interface CountryFacadeRemote { 

void create(Country country); 
void edit(Country country); 
void remove(Country country); 
Country find(Object id); 
List<Country> findAll(); 
List<Country> findRange(int[] range); 
int count(); 

} 

MyAppTestEJB:(EJB MODUL E)

* AbstractFacade:

public abstract class AbstractFacade<T> { 
private Class<T> entityClass; 

public AbstractFacade(Class<T> entityClass) { 
    this.entityClass = entityClass; 
} 

protected abstract EntityManager getEntityManager(); 
... 

public int count() { 
    javax.persistence.criteria.CriteriaQuery cq = getEntityManager().getCriteriaBuilder().createQuery(); 
    javax.persistence.criteria.Root<T> rt = cq.from(entityClass); 
    cq.select(getEntityManager().getCriteriaBuilder().count(rt)); 
    javax.persistence.Query q = getEntityManager().createQuery(cq); 
    return ((Long) q.getSingleResult()).intValue(); 
} 
} 

* CountryFacade:

@Stateless 
public class CountryFacade extends AbstractFacade<Country> implements CountryFacadeLocal, CountryFacadeRemote { 
@PersistenceContext(unitName = "pu") 
private EntityManager em; 

@Override 
protected EntityManager getEntityManager() { 
    return em; 
} 

public CountryFacade() { 
    super(Country.class); 
} 
} 

MyAppTestEJBOther:(EJB模塊)

* NewBean:

@Singleton 
public class NewBean { 

@EJB 
private CountryFacadeRemote countryFacade; 

@Schedule(hour = "*", minute = "*") 
public void businessMethod() { 
    System.out.println("NumCountries:" + countryFacade.count()); 
} 
} 

錯誤輸出:

WARNING: EJB5184:A system exception occurred during an invocation on EJB NewBean, method: public void net.myapp.myapptestejbother.NewBean.businessMethod() 
WARNING: javax.ejb.EJBException: javax.ejb.CreateException: Initialization failed for Singleton NewBean 
at com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:656) 
at com.sun.ejb.containers.AbstractSingletonContainer.instantiateSingletonInstance(AbstractSingletonContainer.java:396) 
at org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:219) 
at org.glassfish.ejb.startup.SingletonLifeCycleManager.initializeSingleton(SingletonLifeCycleManager.java:180) 
at com.sun.ejb.containers.AbstractSingletonContainer.checkInit(AbstractSingletonContainer.java:368) 
at com.sun.ejb.containers.CMCSingletonContainer._getContext(CMCSingletonContainer.java:116) 
at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2516) 
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1906) 
at com.sun.ejb.containers.BaseContainer.callEJBTimeout(BaseContainer.java:3990) 
at com.sun.ejb.containers.EJBTimerService.deliverTimeout(EJBTimerService.java:1199) 
at com.sun.ejb.containers.EJBTimerService.access$000(EJBTimerService.java:89) 
at com.sun.ejb.containers.EJBTimerService$TaskExpiredWork.run(EJBTimerService.java:1919) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at java.lang.Thread.run(Thread.java:722) 
Caused by: javax.ejb.CreateException: Initialization failed for Singleton NewBean 
at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:483) 
at com.sun.ejb.containers.AbstractSingletonContainer.access$000(AbstractSingletonContainer.java:81) 
at com.sun.ejb.containers.AbstractSingletonContainer$SingletonContextFactory.create(AbstractSingletonContainer.java:654) 
... 17 more 
Caused by: java.lang.IllegalStateException: Exception attempting to inject Remote ejb-ref name=net.myapp.myapptestejbother.NewBean/countryFacade,Remote 3.x interface =net.myapp.ejb.CountryFacadeRemote,ejb-link=null,lookup=,mappedName=,jndi-name=net.myapp.ejb.CountryFacadeRemote,refType=Session into class net.myapp.myapptestejbother.NewBean: Lookup failed for 'java:comp/env/net.myapp.myapptestejbother.NewBean/countryFacade' 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} 
at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:145) 
at org.jboss.weld.injection.InjectionContextImpl.run(InjectionContextImpl.java:46) 
at org.jboss.weld.injection.producer.DefaultInjector.inject(DefaultInjector.java:64) 
at org.jboss.weld.injection.producer.BasicInjectionTarget.inject(BasicInjectionTarget.java:91) 
at org.glassfish.weld.services.JCDIServiceImpl.injectEJBInstance(JCDIServiceImpl.java:257) 
at com.sun.ejb.containers.BaseContainer.injectEjbInstance(BaseContainer.java:1683) 
at com.sun.ejb.containers.AbstractSingletonContainer.createSingletonEJB(AbstractSingletonContainer.java:443) 
... 19 more 
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=net.myapp.myapptestejbother.NewBean/countryFacade,Remote 3.x interface =net.myapp.ejb.CountryFacadeRemote,ejb-link=null,lookup=,mappedName=,jndi-name=net.myapp.ejb.CountryFacadeRemote,refType=Session into class net.myapp.myapptestejbother.NewBean: Lookup failed for 'java:comp/env/net.myapp.myapptestejbother.NewBean/countryFacade' 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} 
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:717) 
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:484) 
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:170) 
at org.glassfish.weld.services.InjectionServicesImpl.aroundInject(InjectionServicesImpl.java:138) 
... 25 more 
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/net.myapp.myapptestejbother.NewBean/countryFacade' 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.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=net.myapp.myapptestejbother.NewBean/countryFacade,Remote 3.x interface =net.myapp.ejb.CountryFacadeRemote,ejb-link=null,lookup=,mappedName=,jndi-name=net.myapp.ejb.CountryFacadeRemote,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote' [Root exception is javax.naming.NamingException: Lookup failed for 'net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote' 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: net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote not found]]] 
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491) 
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438) 
at javax.naming.InitialContext.lookup(InitialContext.java:411) 
at javax.naming.InitialContext.lookup(InitialContext.java:411) 
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:613) 
... 28 more 
Caused by: javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=net.myapp.myapptestejbother.NewBean/countryFacade,Remote 3.x interface =net.myapp.ejb.CountryFacadeRemote,ejb-link=null,lookup=,mappedName=,jndi-name=net.myapp.ejb.CountryFacadeRemote,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote' [Root exception is javax.naming.NamingException: Lookup failed for 'net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote' 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: net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote not found]] 
at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:188) 
at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$EjbReferenceProxy.create(ComponentEnvManagerImpl.java:1143) 
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:745) 
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:715) 
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:159) 
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:471) 
... 32 more 
Caused by: javax.naming.NamingException: Lookup failed for 'net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote' 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: net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote not found] 
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:491) 
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:438) 
at javax.naming.InitialContext.lookup(InitialContext.java:411) 
at javax.naming.InitialContext.lookup(InitialContext.java:411) 
at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:183) 
... 37 more 
Caused by: javax.naming.NameNotFoundException: net.myapp.ejb.CountryFacadeRemote#net.myapp.ejb.CountryFacadeRemote not found 
at com.sun.enterprise.naming.impl.TransientContext.doLookup(TransientContext.java:237) 
at com.sun.enterprise.naming.impl.TransientContext.lookup(TransientContext.java:204) 
at com.sun.enterprise.naming.impl.SerialContextProviderImpl.lookup(SerialContextProviderImpl.java:66) 
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:114) 
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:478) 
... 41 more 

WARNING: EJB5184:A system exception occurred during an invocation on EJB NewBean, method: public void net.myapp.myapptestejbother.NewBean.businessMethod() 
WARNING: javax.ejb.NoSuchEJBException: Singleton NewBean is unavailable because its original initialization failed. 
at com.sun.ejb.containers.AbstractSingletonContainer.checkInit(AbstractSingletonContainer.java:359) 
at com.sun.ejb.containers.CMCSingletonContainer._getContext(CMCSingletonContainer.java:116) 
at com.sun.ejb.containers.BaseContainer.getContext(BaseContainer.java:2516) 
at com.sun.ejb.containers.BaseContainer.preInvoke(BaseContainer.java:1906) 
at com.sun.ejb.containers.BaseContainer.callEJBTimeout(BaseContainer.java:3990) 
at com.sun.ejb.containers.EJBTimerService.deliverTimeout(EJBTimerService.java:1199) 
at com.sun.ejb.containers.EJBTimerService.access$000(EJBTimerService.java:89) 
at com.sun.ejb.containers.EJBTimerService$TaskExpiredWork.run(EJBTimerService.java:1919) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) 
at java.util.concurrent.FutureTask.run(FutureTask.java:166) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at java.lang.Thread.run(Thread.java:722) 

回答

2

解決增加lookup到EJB註解:

@EJB(lookup = "java:global/MyAppTestEJB/CountryFacade!net.myapp.ejb.CountryFacadeRemote")

@Singleton 
public class NewBean { 

    @EJB(lookup = "java:global/MyAppTestEJB/CountryFacade!net.myapp.ejb.CountryFacadeRemote") 
    private CountryFacadeRemote countryFacade; 

    @Schedule(hour = "*", minute = "*") 
    public void businessMethod() { 
     System.out.println("NumCountries:" + countryFacade.count()); 
    } 
} 

有沒有更優雅的方式來做到這一點?