我们当前的旧版Web应用程序在其中创建线程,而不由Application Server Containers管理。我必须使用JavaEE标准对它进行修改以实现多线程。
我的Web应用程序在Tomcat上运行良好,但在Websphere上运行失败。
Websphere错误:
... ... Caused by: javax.naming.ConfigurationException: A JNDI operation on a "java:" name cannot be completed because the server runtime is not able to associate the operation's thread with any J2EE application component. This condition can occur when the JNDI client using the "java:" name is not executed on the thread of a server application request. Make sure that a J2EE application does not execute JNDI operations on "java:" names within static code blocks or in threads created by that J2EE 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:" names.
at com.ibm.ws.naming.java.javaURLContextImpl.throwExceptionIfDefaultJavaNS(javaURLContextImpl.java:534) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.naming.java.javaURLContextImpl.throwConfigurationExceptionWithDefaultJavaNS(javaURLContextImpl.java:564) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.naming.java.javaURLContextImpl.lookupExt(javaURLContextImpl.java:485) ~[com.ibm.ws.runtime.jar:?]
at com.ibm.ws.naming.java.javaURLContextRoot.lookupExt(javaURLContextRoot.java:485) ~[com.ibm.ws.runtime.jar:?]
为了解决此问题,我指的是Concurrency Utilities in Java EE。我发现了ManagedExecutorService和ManagedThreadFactory的类似描述和示例。
ManagedExecutorService:应用程序使用托管执行程序服务来异步执行提交的任务。任务是
在由容器启动和管理的线程上执行。的
容器的上下文传播到执行
任务。
ManagedThreadFactory:应用程序使用托管线程工厂来创建托管线程。线程启动并
由容器管理。容器的上下文被传播
到执行任务的线程。这个对象也可以用来
提供针对特定用例的自定义工厂(带有自定义线程)
并为这些设置特定的/专有的属性
对象。
在哪种情况下首选哪个,为什么?
最佳答案
我已经通过使用ManagedExecutorService解决了问题。
ExecutorService框架确实具有更多处理线程的方法,而ManagedThreadFactory只能调用newThread()方法。
可以使用ManagedExecutorService或ManagedThreadFactory解决Websphere问题。两者都可以。但是对于进一步的线程处理,ManagedExecutorService的结果要好得多。
现在,此解决方案导致同一Web应用程序在Tomcat上失败。 JNDI命名异常。根据我的研发,TomEE服务器支持基于容器的并发,而Tomcat不支持,因此我们必须使用路由机制根据基础应用服务器在代码之间进行切换。