当尝试获取已在应用程序中加载的类时,来自workmanager的NPE

时间:2014-11-20 14:42:19

标签: websphere workmanagers

我正在使用WebSphere 8.5和JSF2.0,我在使用WorkManager时遇到了问题(来自websphere - async bean)。我有一个实现Work接口的 workManagerExample 类。当我从我的应用程序调用workManagerExample时,我不再可以获取已在我的应用程序中加载的类的方法。 情况我在我的应用程序中有一个Utility类(它工作正常)但是当我尝试使用它时(例如Utility.someMethod)来自workManagerExample我得到了一个N​​PE。我在调用'startWork(WorkManagerExample)'之前检查了Utility类,并且不是null,我可以像往常一样使用它。顺便说一句,workManager工作正常,无需从我的应用程序调用任何已加载的类。我无法将Utility类作为workManagerExample构造函数的参数传递(这是来自客户/客户的限制)。我的问题是为什么我不再使用这个Asyn Bean的Utility类函数了?

web.xml
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
//some extra config not related
    <resource-ref>
        <description>WorkManager</description>
        <res-ref-name>wm/default</res-ref-name>
        <res-type>com.ibm.websphere.asynchbeans.WorkManager</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref> 
</web-app>

ibm-web-bnd.xml
<web-bnd xmlns="http://websphere.ibm.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://websphere.ibm.com/xml/ns/javaee http://websphere.ibm.com/xml/ns/javaee/ibm-web-bnd_1_0.xsd"
version="1.0">
    <virtual-host name="default_host" />
    <resource-ref name="wm/default" binding-name="wm/default" />
</web-bnd>

这是我的参考指南http://www.bencode.net/blog/2014/07/26/was-async-beans/

一些java代码: Class1.java

WorkManager workManager = getWorkManager();
if (workManager!=null){   
  GetInfoWork currentOfferWork = new GetInfoWork(); //GetInfoWork implements Work
  workManager.startWork(currentOfferWork);  
}

在GetInfoWork.java中,当我尝试'FacesContext.getCurrentInstance();'我总是得到NULL但是如果我尝试从Class1.java它按预期工作。文件夹结构与通常的JSF2 Web应用程序一样,这是一个现有的应用程序,现在我想通过workManager(来自com.ibm.ws.runtime.jar)添加这个Async Bean功能。

1 个答案:

答案 0 :(得分:1)

FacesContext.getCurrentInstance()不是您的实用程序类,而是JSF框架的内部部分。如果你看一下java doc:

public static FacesContext getCurrentInstance()
     

返回当前线程正在处理的请求的FacesContext实例。

FacesContext需要一个处理Web请求的线程才能正常工作,异步bean在单独的线程中调用,根本不了解JSF上下文,这就是你得到null的原因。您的Class1由处理Web请求的线程调用。

但是你的陈述中你不正确:
我无法将Utility类作为workManagerExample构造函数的参数传递(这是一个限制)。

我不知道你在哪里发现了这个限制,但事实并非如此。请参阅信息中心 - Developing work objects to run code in parallel

所以你的代码应该是这样的:

WorkManager workManager = getWorkManager();
if (workManager!=null){ 
  // extract from FacesContext what you need
  ....
  // and pass it to work item  
  GetInfoWork currentOfferWork = new GetInfoWork(pass, whatEver, objectsYouNeed, inWork); //GetInfoWork implements Work
  workManager.startWork(currentOfferWork);  
}

<强>更新
如果不是通过构造函数,您可以通过setter方法传递它。但是不要传递FacesContext,而是传递你真正需要的东西,因为来自该上下文的一些数据在Web请求结束后将无效。 e.g:

GetInfoWork currentOfferWork = new GetInfoWork(); //GetInfoWork implements Work
currentOfferWork.setMyParam1(param1);
currentOfferWork.setMyParam2(param2);
workManager.startWork(currentOfferWork);