【发布时间】:2014-05-20 02:03:40
【问题描述】:
Glassfish 在以下情况下抛出异常(第二次EJB 查找失败)
定时器服务 -> JMS 队列监听器 -> 第一个 EJB -> 第二个 EJB
不过,如果 Queue 被删除,它会正常工作。
定时器服务 -> 第一个 EJB -> 第二个 EJB
注意:它们都在同一空间的同一台服务器上。
-
Timer Service每运行 30 秒并将JMS Message发送到队列 -
Queue成功接收到该消息,调用FirstEjb函数,实例化为
@EJB -
FirstEjb 的方法已成功调用,但它会尝试在其中实例化为
@EJB的 SecondEjb 的另一个函数(此查找如何失败)。
定时器类
@Stateless
public class MyTimer {
public static final Logger logger = Logger.getLogger(MyTimer.class);
public MyTimer() {
}
@Schedule(second="*/30", minute="*",hour="*", persistent=false)
private void scheduledTimeout(final Timer t) {
logger.warn("********************* MyTimer scheduledTimeout called ********************************");
MyMessageSender sender = new MyMessageSender();
sender.sendMessage(" /////////////// Here is my message for you ////////////// ");
}
}
消息发送者(帮助类)
public class MyMessageSender {
public void sendMessage(String message) {
Context jndiContext = null;
Connection connection = null;
Session session = null;
MessageProducer producer = null;
ConnectionFactory factory = null;
try {
jndiContext = new InitialContext();
factory = (ConnectionFactory) jndiContext
.lookup(NewsUpdatesQueueListener.CONNECTION_FACTORY);
connection = factory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
if (session == null) {
System.out.println("session object is null");
return;
}
Queue queue = (Queue) jndiContext.lookup(NewsUpdatesQueueListener.CONNECTION_QUEUE_JNDI);
if (queue == null) {
System.out.println("queue object for NewsUpdateQueue is null ");
return;
}
producer = session.createProducer(queue);
ObjectMessage msg = session.createObjectMessage();
msg.setStringProperty("text", message);
session.createProducer(queue).send(msg);
} catch (NamingException e) {
e.printStackTrace();
} catch (JMSException e) {
e.printStackTrace();
} finally {
try {
if (connection != null) {
connection.close();
}
if (session != null) {
session.close();
}
if (producer != null) {
producer.close();
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
}
队列监听器
@MessageDriven(
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty( propertyName = "destination", propertyValue = NewsUpdatesQueueListener.CONNECTION_QUEUE_NAME)
},
mappedName = NewsUpdatesQueueListener.CONNECTION_QUEUE_JNDI)
public class NewsUpdatesQueueListener implements MessageListener {
public static final Logger logger = Logger.getLogger(NewsUpdatesQueueListener.class);
public static final String CONNECTION_FACTORY = "jms/NewsConnectionFactory";
public static final String CONNECTION_QUEUE_NAME = "NewsQueue";
public static final String CONNECTION_QUEUE_JNDI = "jms/"+CONNECTION_QUEUE_NAME;
@EJB
FirstEjbRemote first;
public void onMessage(Message message) {
if (message instanceof ObjectMessage) {
ObjectMessage msg = (ObjectMessage) message;
try {
logger.warn("Message recived in Queue listener: "+ msg.getStringProperty("text"));
if (first != null)
first.hello();
else
logger.warn("@EJB first is null");
} catch (JMSException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
第一个 EJb
@Stateless(name="FirstEjb", mappedName="ejb/FirstEjb")
@Local(FirstEjbLocal.class)
@Remote(FirstEjbRemote.class)
public class FirstEjb implements FirstEjbRemote, FirstEjbLocal {
public static final Logger logger = Logger.getLogger(FirstEjb.class);
@EJB
SecondEjbRemote second;
@Override
public void hello() {
logger.warn("********************* Hello function called in first EJB *********");
if (second != null)
second.sayHello();
}
}
第二个 EJB
@Stateless(name="SecondEjb", mappedName = "ejb/SecondEjb")
@Local(SecondEjbLocal.class)
@Remote(SecondEjbRemote.class)
public class SecondEjb implements SecondEjbRemote, SecondEjbLocal {
@Override
public void sayHello() {
System.out.println("********************* Hello function called in second EJB *********");
}
}
部署日志
|INFO|glassfish3.1.2|EJB5181:Portable JNDI names for EJB SecondEjb: [java:global/AppleNew/SecondEjb!com.bbc.news.SecondEjbRemote, java:global/AppleNew/SecondEjb!com.bbc.news.SecondEjbLocal]|#]
|INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5182:Glassfish-specific (Non-portable) JNDI names for EJB SecondEjb: [ejb/SecondEjb, ejb/SecondEjb#com.bbc.news.SecondEjbRemote]|#]
|INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5181:Portable JNDI names for EJB MyTimer: [java:global/AppleNew/MyTimer!com.bbc.news.MyTimer, java:global/AppleNew/MyTimer]|#]
|INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5181:Portable JNDI names for EJB FirstEjb: [java:global/AppleNew/FirstEjb!com.bbc.news.FirstEjbLocal, java:global/AppleNew/FirstEjb!com.bbc.news.FirstEjbRemote]|#]
|INFO|glassfish3.1.2|javax.enterprise.system.container.ejb.com.sun.ejb.containers|_ThreadID=37;_ThreadName=Thread-2;|EJB5182:Glassfish-specific (Non-portable) JNDI names for EJB FirstEjb: [ejb/FirstEjb#com.bbc.news.FirstEjbRemote, ejb/FirstEjb]|#]
|INFO|glassfish3.1.2|javax.enterprise.resource.jms.com.sun.enterprise.connectors.jms.system|_ThreadID=37;_ThreadName=Thread-2;|JMS013: end point determine destionation name, Res name: javax.jms.Queue, JNDI name: NewsUpdatesQueueListener descriptor name : {3}|#]
|INFO|glassfish3.1.2|javax.enterprise.system.tools.admin.org.glassfish.deployment.admin|_ThreadID=37;_ThreadName=Thread-2;|AppleNew was successfully deployed in 332 milliseconds.|#]
请注意如果 JMS 队列被移除并且计时器服务直接调用第一个 ejb 而不是第一个 ejb 调用第二个 ejb,它工作正常。
部分异常(从长异常的中间开始,如果需要我会粘贴完整的异常)
Caused by: javax.ejb.CreateException: Could not create stateless EJB
at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:534)
at com.sun.ejb.containers.StatelessSessionContainer.access$000(StatelessSessionContainer.java:95)
at com.sun.ejb.containers.StatelessSessionContainer$SessionContextFactory.create(StatelessSessionContainer.java:724)
... 45 more
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=com.bbc.news.FirstEjb/second,Remote 3.x interface =com.bbc.news.SecondEjbRemote resolved to intra-app EJB SecondEjb in module AppleNew,ejb-link=SecondEjb,lookup=,mappedName=,jndi-name=ejb/SecondEjb,refType=Session into class com.bbc.news.FirstEjb: Lookup failed for 'java:comp/env/com.bbc.news.FirstEjb/second' 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:703)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.inject(InjectionManagerImpl.java:470)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.injectInstance(InjectionManagerImpl.java:171)
at com.sun.ejb.containers.BaseContainer.injectEjbInstance(BaseContainer.java:1694)
at com.sun.ejb.containers.StatelessSessionContainer.createStatelessEJB(StatelessSessionContainer.java:494)
... 47 more
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/com.bbc.news.FirstEjb/second' 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=com.bbc.news.FirstEjb/second,Remote 3.x interface =com.bbc.news.SecondEjbRemote resolved to intra-app EJB SecondEjb in module AppleNew,ejb-link=SecondEjb,lookup=,mappedName=,jndi-name=ejb/SecondEjb,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'ejb/SecondEjb#com.bbc.news.SecondEjbRemote' [Root exception is javax.naming.NamingException: Lookup failed for 'ejb/SecondEjb#com.bbc.news.SecondEjbRemote' 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.CommunicationException: Communication exception for 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 java.rmi.RemoteException: ; nested exception is:
org.omg.CORBA.INITIALIZE: can't instantiate default ORB implementation com.sun.corba.ee.impl.orb.ORBSingleton vmcid: 0x0 minor code: 0 completed: No]]]]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:409)
at javax.naming.InitialContext.lookup(InitialContext.java:409)
at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl._inject(InjectionManagerImpl.java:599)
... 51 more
Caused by: javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=com.bbc.news.FirstEjb/second,Remote 3.x interface =com.bbc.news.SecondEjbRemote resolved to intra-app EJB SecondEjb in module AppleNew,ejb-link=SecondEjb,lookup=,mappedName=,jndi-name=ejb/SecondEjb,refType=Session' . Actual (possibly internal) Remote JNDI name used for lookup is 'ejb/SecondEjb#com.bbc.news.SecondEjbRemote' [Root exception is javax.naming.NamingException: Lookup failed for 'ejb/SecondEjb#com.bbc.news.SecondEjbRemote' 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.CommunicationException: Communication exception for 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 java.rmi.RemoteException: ; nested exception is:
org.omg.CORBA.INITIALIZE: can't instantiate default ORB implementation com.sun.corba.ee.impl.orb.ORBSingleton vmcid: 0x0 minor code: 0 completed: No]]]
at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:191)
at com.sun.enterprise.container.common.impl.ComponentEnvManagerImpl$EjbReferenceProxy.create(ComponentEnvManagerImpl.java:1109)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:776)
at com.sun.enterprise.naming.impl.GlassfishNamingManagerImpl.lookup(GlassfishNamingManagerImpl.java:744)
at com.sun.enterprise.naming.impl.JavaURLContext.lookup(JavaURLContext.java:169)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:498)
... 55 more
Caused by: javax.naming.NamingException: Lookup failed for 'ejb/SecondEjb#com.bbc.news.SecondEjbRemote' 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.CommunicationException: Communication exception for 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 java.rmi.RemoteException: ; nested exception is:
org.omg.CORBA.INITIALIZE: can't instantiate default ORB implementation com.sun.corba.ee.impl.orb.ORBSingleton vmcid: 0x0 minor code: 0 completed: No]]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:518)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:409)
at javax.naming.InitialContext.lookup(InitialContext.java:409)
at com.sun.ejb.EjbNamingReferenceManagerImpl.resolveEjbReference(EjbNamingReferenceManagerImpl.java:186)
... 60 more
Caused by: javax.naming.CommunicationException: Communication exception for 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 java.rmi.RemoteException: ; nested exception is:
org.omg.CORBA.INITIALIZE: can't instantiate default ORB implementation com.sun.corba.ee.impl.orb.ORBSingleton vmcid: 0x0 minor code: 0 completed: No]
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:542)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
at javax.naming.InitialContext.lookup(InitialContext.java:409)
at javax.naming.InitialContext.lookup(InitialContext.java:409)
at com.sun.ejb.containers.RemoteBusinessObjectFactory.getObjectInstance(RemoteBusinessObjectFactory.java:71)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:556)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:514)
... 64 more
Caused by: java.rmi.RemoteException: ; nested exception is:
org.omg.CORBA.INITIALIZE: can't instantiate default ORB implementation com.sun.corba.ee.impl.orb.ORBSingleton vmcid: 0x0 minor code: 0 completed: No
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:147)
at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:505)
... 71 more
Caused by: org.omg.CORBA.INITIALIZE: can't instantiate default ORB implementation com.sun.corba.ee.impl.orb.ORBSingleton vmcid: 0x0 minor code: 0 completed: No
at org.omg.CORBA.ORB.create_impl_with_systemclassloader(ORB.java:308)
at org.omg.CORBA.ORB.init(ORB.java:293)
at org.omg.CosTransactions.PropagationContextHelper.type(PropagationContextHelper.java:40)
at org.omg.CosTransactions.PropagationContextHelper.insert(PropagationContextHelper.java:18)
at com.sun.jts.pi.InterceptorImpl.send_request(InterceptorImpl.java:346)
at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeClientInterceptorStartingPoint(InterceptorInvoker.java:290)
at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeClientPIStartingPoint(PIHandlerImpl.java:376)
at com.sun.corba.ee.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(CorbaClientRequestDispatcherImpl.java:304)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.request(CorbaClientDelegateImpl.java:228)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.is_a(CorbaClientDelegateImpl.java:393)
at org.omg.CORBA.portable.ObjectImpl._is_a(ObjectImpl.java:130)
at org.omg.CosNaming.NamingContextHelper.narrow(NamingContextHelper.java:69)
at com.sun.jndi.cosnaming.CNCtx.setOrbAndRootContext(CNCtx.java:383)
at com.sun.jndi.cosnaming.CNCtx.initOrbAndRootContext(CNCtx.java:274)
at com.sun.jndi.cosnaming.CNCtx.<init>(CNCtx.java:105)
at com.sun.jndi.cosnaming.CNCtxFactory.getInitialContext(CNCtxFactory.java:49)
at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:684)
at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at javax.naming.InitialContext.init(InitialContext.java:240)
at javax.naming.InitialContext.<init>(InitialContext.java:214)
at com.sun.enterprise.naming.util.IIOPObjectFactory.getObjectInstance(IIOPObjectFactory.java:73)
at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:321)
at com.sun.enterprise.naming.impl.LocalSerialContextProviderImpl.lookup(LocalSerialContextProviderImpl.java:138)
... 72 more
Caused by: java.lang.ClassNotFoundException: com.sun.corba.ee.impl.orb.ORBSingleton
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at org.omg.CORBA.ORB.create_impl_with_systemclassloader(ORB.java:305)
... 94 more
版本详情这是一个生产服务器,此代码不起作用
GlassFish Server Open Source Edition 3.1.2.2 (build 5)
Ubuntu 12.04.4 LTS
**java** version "1.6.0_31"
OpenJDK Runtime Environment (IcedTea6 1.13.3) (6b31-1.13.3-1ubuntu1~0.12.04.2)
OpenJDK 64-Bit Server VM (build 23.25-b01, mixed mode)
2 可以正常工作的测试环境
window 7
GlassFish Server Open Source Edition 3.1.2 (build 23)
java version "1.6.0_32"
Java(TM) SE Runtime Environment (build 1.6.0_32-b05)
Java HotSpot(TM) Client VM (build 20.7-b02, mixed mode, sharing)
测试虚拟机
Ubuntu 12.04.2 LTS
GlassFish Server Open Source Edition 3.0.1 (build 22)
java version "1.6.0_30"
OpenJDK Runtime Environment (IcedTea6 1.13.1) (6b30-1.13.1-1ubuntu2~0.12.04.3)
OpenJDK Client VM (build 23.25-b01, mixed mode, sharing)
【问题讨论】:
-
您使用的是哪个 Java 版本和哪个 Glassfish 版本?
-
请查看更新的问题我已经添加了有关版本的详细信息。
-
检查这个问题报告java.net/jira/browse/GLASSFISH-21047,也许那里描述的解决方法对你有用。
-
你能解释一下吗指定JDK提供的默认ORB单例(int the domain.xml jvmopts):-Dorg.omg.CORBA.ORBSingletonClass=com.sun.corba.se.impl。 orb.ORBSingleton 为我“解决”了这个问题。
-
你必须编辑 domain.xml 找到一个名为 jvmopts 的元素,并在那里添加提到的字符串。这将设置提到的系统属性
标签: jakarta-ee timer glassfish jms ejb-3.0