【发布时间】:2011-02-05 14:39:38
【问题描述】:
我试图从tread 调用一些ejb bean 方法。并得到错误:
(和 glassfish v3 一样)
日志级别
严重的记录器
javax.enterprise.system.std.com.sun.enterprise.v3.services.impl 名称-值对
{_ThreadName=Thread-1, _ThreadID=42} 记录号 928 消息 ID
java.lang.NullPointerException 在 ua.co.rufous.server.broker.TempLicService.run(TempLicService.java 完成消息 35) 在 java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 在 java.lang.Thread.run(Thread.java:637)
这是胎面
public class TempLicService implements Runnable {
String hash;
//it`s Stateful bean
@EJB
private LicActivatorLocal lActivator;
public TempLicService(String hash) {
this.hash= hash;
}
@Override
public void run() {
lActivator.proccessActivation(hash);
}
}
我的线程池执行器
public class RequestThreadPoolExecutor extends ThreadPoolExecutor {
private boolean isPaused;
private ReentrantLock pauseLock = new ReentrantLock();
private Condition unpaused = pauseLock.newCondition();
private static RequestThreadPoolExecutor threadPool;
private RequestThreadPoolExecutor() {
super(1, Integer.MAX_VALUE, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
System.out.println("RequestThreadPoolExecutor created");
}
public static RequestThreadPoolExecutor getInstance() {
if (threadPool == null)
threadPool = new RequestThreadPoolExecutor();
return threadPool;
}
public void runService(Runnable task) {
threadPool.execute(task);
}
protected void beforeExecute(Thread t, Runnable r) {
super.beforeExecute(t, r);
pauseLock.lock();
try {
while (isPaused) unpaused.await();
} catch (InterruptedException ie) {
t.interrupt();
} finally {
pauseLock.unlock();
}
}
public void pause() {
pauseLock.lock();
try {
isPaused = true;
} finally {
pauseLock.unlock();
}
}
public void resume() {
pauseLock.lock();
try {
isPaused = false;
unpaused.signalAll();
} finally {
pauseLock.unlock();
}
}
public void shutDown() {
threadPool.shutdown();
}
//<<<<<< creating thread here
public void runByHash(String hash) {
Runnable service = new TempLicService(hash);
threadPool.runService(service);
}
}
以及我调用它的方法(它是 gwt servlet,但无法调用不包含 ejb 的线程):
@Override
public Boolean submitHash(String hash) {
System.out.println("submiting hash");
try {
if (tBoxService.getTempLicStatus(hash) == 1) {
//<<< here is the call
RequestThreadPoolExecutor.getInstance().runByHash(hash);
return true;
}
} catch (NoResultException e) {
e.printStackTrace();
}
return false;
}
我需要组织一些向服务器提交哈希的池(调用 LicActivator bean),ThreadPoolExecutor 设计是个好主意,为什么它在我的情况下不起作用? (据我所知,我们不能在 bean 中创建线程,但我们可以从不同的线程调用 bean 吗?)。 如果否,组织此类请求池的最佳做法是什么?
谢谢。
所以..
2.我可以在 Tread 中使用手动查找吗? ---- 是的
3.我可以使用扩展 ThreadPoolExecutor 的 Bean 并调用另一个实现 Runnable 的 bean 吗?还是不允许?
【问题讨论】:
-
我可能遗漏了一些东西,但是您在哪里查找会话 bean?如果不初始化 lActivator,lActivator.proccessActivation(hash) 将抛出 NullPointerException。 @EJB 注入在您的示例中不起作用。另见stackoverflow.com/questions/848675/ejb-annotation-in-clients
-
我正在使用 DI (EJB 3.1) 所以我不需要在这里查找。 (应用程序包含在 ear 和其中的两个模块(web 模块和 ejb)中,它非常适合我)。但我只能在托管类中使用它。 1. 所以我可以在 Tread 中使用手动查找? 2. 我可以使用扩展 ThreadPoolExecutor 的 Bean 并调用另一个实现 Runnable 的 bean 吗?还是不允许?
标签: java multithreading ejb threadpool