Websphere JNDI 查找在 Quartz 作业中失败
Websphere JNDI lookup fails in a Quartz job
做一些可以帮助我在 Quartz 作业中进行 EJB 初始化的事情
我有这样的 Quartz:
@DisallowConcurrentExecution
public class TestJob implements Job{
private TestEJBServiceLocal testEJBService;
private void initEJB() {
this.testEJBService = new JNDIUtil()
.getByJndiName("java:comp/env/ejb/TestEJBService");
}
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
// DO STUFF
}
}
在网络中 XML 我有:
<ejb-local-ref>
<description />
<ejb-ref-name>ejb/TestEJBService</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home />
<local>com.ibm.blue.ejb.TestEJBServiceLocal</local>
<ejb-link>TestEJBService</ejb-link>
</ejb-local-ref>
Liberty 配置文件无法初始化 EJB 并出现异常:
2015-06-04 16:18:00 ERROR JNDIUtil:38 - JNDIUtil lookup error;
javax.naming.NamingException: CWNEN1000E: A JNDI operation on a java:comp/env name cannot be completed because the current thread is not associated with a Java Enterprise Edition application component. This condition can occur when the JNDI client using the java:comp/env name does not occur on the thread of a server application request. Make sure that a Java EE application does not run JNDI operations on java:comp/env names within static code blocks or in threads created by that application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on java:comp/env names.
at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getInjectionScopeData(InjectionJavaColonHelper.java:110)
at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getObjectInstance(InjectionJavaColonHelper.java:67)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:319)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:357)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:423)
at JNDIUtil.lookup(JNDIUtil.java:36)
at getByJndiName(JNDIUtil.java:24)
at Job.initEJB(Job.java:52)
at execute(Job.java:68)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
2015-06-04 16:18:00 ERROR JNDIUtil:38 - JNDIUtil lookup error;
我是 运行 IBM Liberty 配置文件 V.8.5.5.5
更新
我已尝试更新 JNDI 查找字符串(全局 JNDI 在 trace.log
中的应用程序启动期间打印)我仍然遇到相同的异常。这是我在工作中的更新:
private void initEJB() {
Context context;
String jndi = "java:global/TestEAR/TestEJBS/TestEJBService!com.ibm.blue.ejb.TestEJBServiceLocal"
try{
context = new InitialContext();
this.testEJBService = (TestEJBServiceLocal)context.lookup(jndi);
} catch (NamingException e) {
System.out.println("-->Test with InitialContext: Error");
e.printStackTrace();
}
try {
this.testEJBService = new JNDIUtil().getByJndiName(jndi);
} catch (Exception e) {
System.err.println("-->Test with JNDIUtil: Error");
e.printStackTrace();
}
}
这是输出日志:
[err] -->Test with InitialContext: Error
[err] javax.naming.NamingException: CWNEN1000E: A JNDI operation on a java:comp/env name cannot be completed because the current thread is not associated with a Java Enterprise Edition application component. This condition can occur when the JNDI client using the java:comp/env name does not occur on the thread of a server application request. Make sure that a Java EE application does not run JNDI operations on java:comp/env names within static code blocks or in threads created by that application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on java:comp/env names.
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getInjectionScopeData(InjectionJavaColonHelper.java:110)
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getObjectInstance(InjectionJavaColonHelper.java:67)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:319)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:357)
[err] at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
[err] at javax.naming.InitialContext.lookup(InitialContext.java:423)
[err] at Job.initEJB(Job.java:38)
[err] at execute(Job.java:75)
[err] at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
[err] at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
[err] -->Test with JNDIUtil: Error
[err] java.lang.RuntimeException: Cannot get bean by JNDI name; JNDI=java:global/TestEAR/TestEJBS/TestEJBService!com.ibm.blue.ejb.TestEJBServiceLocal
[err] at JNDIUtil.lookup(JNDIUtil.java:39)
[err] at JNDIUtil.getByJndiName(JNDIUtil.java:24)
[err] at initEJB(Job.java:62)
[err] at Job.execute(Job.java:75)
[err] at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
[err] at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
[err] Caused by:
[err] javax.naming.NamingException: CWNEN1000E: A JNDI operation on a java:comp/env name cannot be completed because the current thread is not associated with a Java Enterprise Edition application component. This condition can occur when the JNDI client using the java:comp/env name does not occur on the thread of a server application request. Make sure that a Java EE application does not run JNDI operations on java:comp/env names within static code blocks or in threads created by that application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on java:comp/env names.
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getInjectionScopeData(InjectionJavaColonHelper.java:110)
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getObjectInstance(InjectionJavaColonHelper.java:67)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:319)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:357)
[err] at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
[err] at javax.naming.InitialContext.lookup(InitialContext.java:423)
[err] at JNDIUtil.lookup(JNDIUtil.java:36)
[err] ... 5 more
Quartz 使用非托管线程,因此 java:comp/env 命名空间和引用在那里不可用。
您可以:
使用 EJB 的完整 JNDI 名称 <=== UPDATE2 我暂时不能 运行 来自非托管线程的本地接口(我现在没有时间玩它)。因此,您要么需要使用支持远程 EJB 的 Liberty Beta,要么将您的 bean 更改为具有远程接口。或者您可以尝试将 Quartz 配置为使用 Liberty 并发功能提供的托管线程工厂(以类似 here 的方式(但这是针对完整的 WAS)。我没有尝试过,所以不知道是否可以实际上是可能的)。
或者,用
代替 Quartz 可能会更好
WebSphere Liberty 的 concurrent-1.0
功能,它使用托管线程并可以访问 Java EE 上下文,例如 Managed scheduled executor
- 或使用 EJB 计时器和
@Schedule
注释。
更新
当它被服务器绑定时,您可以在消息日志中找到完整的 JNDI 名称:
[INFO ] CNTR0167I: The server is binding the test.Hello interface of the Hello enterprise bean in the HelloEJBLocal.war module of the HelloEJBLocal application.
The binding location is: java:global/HelloEJBLocal/Hello!test.Hello
然后你查找它使用(这只适用于 Java EE 应用程序组件或托管线程):
ctx.lookup("java:global/HelloEJBLocal/Hello!test.Hello");
做一些可以帮助我在 Quartz 作业中进行 EJB 初始化的事情
我有这样的 Quartz:
@DisallowConcurrentExecution
public class TestJob implements Job{
private TestEJBServiceLocal testEJBService;
private void initEJB() {
this.testEJBService = new JNDIUtil()
.getByJndiName("java:comp/env/ejb/TestEJBService");
}
@Override
public void execute(JobExecutionContext arg0) throws JobExecutionException {
// DO STUFF
}
}
在网络中 XML 我有:
<ejb-local-ref>
<description />
<ejb-ref-name>ejb/TestEJBService</ejb-ref-name>
<ejb-ref-type>Session</ejb-ref-type>
<local-home />
<local>com.ibm.blue.ejb.TestEJBServiceLocal</local>
<ejb-link>TestEJBService</ejb-link>
</ejb-local-ref>
Liberty 配置文件无法初始化 EJB 并出现异常:
2015-06-04 16:18:00 ERROR JNDIUtil:38 - JNDIUtil lookup error;
javax.naming.NamingException: CWNEN1000E: A JNDI operation on a java:comp/env name cannot be completed because the current thread is not associated with a Java Enterprise Edition application component. This condition can occur when the JNDI client using the java:comp/env name does not occur on the thread of a server application request. Make sure that a Java EE application does not run JNDI operations on java:comp/env names within static code blocks or in threads created by that application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on java:comp/env names.
at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getInjectionScopeData(InjectionJavaColonHelper.java:110)
at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getObjectInstance(InjectionJavaColonHelper.java:67)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:319)
at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:357)
at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
at javax.naming.InitialContext.lookup(InitialContext.java:423)
at JNDIUtil.lookup(JNDIUtil.java:36)
at getByJndiName(JNDIUtil.java:24)
at Job.initEJB(Job.java:52)
at execute(Job.java:68)
at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
2015-06-04 16:18:00 ERROR JNDIUtil:38 - JNDIUtil lookup error;
我是 运行 IBM Liberty 配置文件 V.8.5.5.5
更新
我已尝试更新 JNDI 查找字符串(全局 JNDI 在 trace.log
中的应用程序启动期间打印)我仍然遇到相同的异常。这是我在工作中的更新:
private void initEJB() {
Context context;
String jndi = "java:global/TestEAR/TestEJBS/TestEJBService!com.ibm.blue.ejb.TestEJBServiceLocal"
try{
context = new InitialContext();
this.testEJBService = (TestEJBServiceLocal)context.lookup(jndi);
} catch (NamingException e) {
System.out.println("-->Test with InitialContext: Error");
e.printStackTrace();
}
try {
this.testEJBService = new JNDIUtil().getByJndiName(jndi);
} catch (Exception e) {
System.err.println("-->Test with JNDIUtil: Error");
e.printStackTrace();
}
}
这是输出日志:
[err] -->Test with InitialContext: Error
[err] javax.naming.NamingException: CWNEN1000E: A JNDI operation on a java:comp/env name cannot be completed because the current thread is not associated with a Java Enterprise Edition application component. This condition can occur when the JNDI client using the java:comp/env name does not occur on the thread of a server application request. Make sure that a Java EE application does not run JNDI operations on java:comp/env names within static code blocks or in threads created by that application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on java:comp/env names.
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getInjectionScopeData(InjectionJavaColonHelper.java:110)
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getObjectInstance(InjectionJavaColonHelper.java:67)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:319)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:357)
[err] at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
[err] at javax.naming.InitialContext.lookup(InitialContext.java:423)
[err] at Job.initEJB(Job.java:38)
[err] at execute(Job.java:75)
[err] at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
[err] at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
[err] -->Test with JNDIUtil: Error
[err] java.lang.RuntimeException: Cannot get bean by JNDI name; JNDI=java:global/TestEAR/TestEJBS/TestEJBService!com.ibm.blue.ejb.TestEJBServiceLocal
[err] at JNDIUtil.lookup(JNDIUtil.java:39)
[err] at JNDIUtil.getByJndiName(JNDIUtil.java:24)
[err] at initEJB(Job.java:62)
[err] at Job.execute(Job.java:75)
[err] at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
[err] at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
[err] Caused by:
[err] javax.naming.NamingException: CWNEN1000E: A JNDI operation on a java:comp/env name cannot be completed because the current thread is not associated with a Java Enterprise Edition application component. This condition can occur when the JNDI client using the java:comp/env name does not occur on the thread of a server application request. Make sure that a Java EE application does not run JNDI operations on java:comp/env names within static code blocks or in threads created by that application. Such code does not necessarily run on the thread of a server application request and therefore is not supported by JNDI operations on java:comp/env names.
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getInjectionScopeData(InjectionJavaColonHelper.java:110)
[err] at com.ibm.ws.injectionengine.osgi.internal.naming.InjectionJavaColonHelper.getObjectInstance(InjectionJavaColonHelper.java:67)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:319)
[err] at com.ibm.ws.jndi.url.contexts.javacolon.internal.JavaURLContext.lookup(JavaURLContext.java:357)
[err] at org.apache.aries.jndi.DelegateContext.lookup(DelegateContext.java:161)
[err] at javax.naming.InitialContext.lookup(InitialContext.java:423)
[err] at JNDIUtil.lookup(JNDIUtil.java:36)
[err] ... 5 more
Quartz 使用非托管线程,因此 java:comp/env 命名空间和引用在那里不可用。
您可以:
使用 EJB 的完整 JNDI 名称 <=== UPDATE2 我暂时不能 运行 来自非托管线程的本地接口(我现在没有时间玩它)。因此,您要么需要使用支持远程 EJB 的 Liberty Beta,要么将您的 bean 更改为具有远程接口。或者您可以尝试将 Quartz 配置为使用 Liberty 并发功能提供的托管线程工厂(以类似 here 的方式(但这是针对完整的 WAS)。我没有尝试过,所以不知道是否可以实际上是可能的)。
或者,用
代替 Quartz 可能会更好-
WebSphere Liberty 的
concurrent-1.0
功能,它使用托管线程并可以访问 Java EE 上下文,例如 Managed scheduled executor- 或使用 EJB 计时器和
@Schedule
注释。
更新
当它被服务器绑定时,您可以在消息日志中找到完整的 JNDI 名称:
[INFO ] CNTR0167I: The server is binding the test.Hello interface of the Hello enterprise bean in the HelloEJBLocal.war module of the HelloEJBLocal application.
The binding location is: java:global/HelloEJBLocal/Hello!test.Hello
然后你查找它使用(这只适用于 Java EE 应用程序组件或托管线程):
ctx.lookup("java:global/HelloEJBLocal/Hello!test.Hello");