Primefaces调用javax.faces 2.2方法,但2.1位于WebSphere9中的路径中

Primefaces调用javax.faces 2.2方法,但2.1位于WebSphere9中的路径中,primefaces,websphere,Primefaces,Websphere,我在WAS9中使用自定义jsf提供程序部署了一个应用程序(在WAS中设置为默认值)。JAR位于一个共享库中,具有一个独立的类装入器。在我们从richfaces迁移到primefaces之前,一切都很顺利。我们使用javax.faces 2.1.29,但出于某种原因,primefaces似乎检测到我们正在使用2.2,并且正在调用一个只存在于2.2中的方法(getPassThroughAttributes)。查看游戏中的堆栈版本似乎是正确的,所以我不确定为什么要调用2.2方法。有人碰到这个吗 >

我在WAS9中使用自定义jsf提供程序部署了一个应用程序(在WAS中设置为默认值)。JAR位于一个共享库中,具有一个独立的类装入器。在我们从richfaces迁移到primefaces之前,一切都很顺利。我们使用javax.faces 2.1.29,但出于某种原因,primefaces似乎检测到我们正在使用2.2,并且正在调用一个只存在于2.2中的方法(getPassThroughAttributes)。查看游戏中的堆栈版本似乎是正确的,所以我不确定为什么要调用2.2方法。有人碰到这个吗

> 3/19/19 17:19:07:671 CDT] 00000091 ServletWrappe E com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception root cause Faces Servlet: javax.servlet.ServletException: javax/faces/component/UIComponent.getPassThroughAttributes(Z)Ljava/util/Map; (loaded from file:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar by 
com.ibm.ws.classloader.CompoundClassLoader@abecddd0[library:trunkLib]
   Local ClassPath: /opt/IBM/WebSphere/AppServer_2/trunkLib/javax.faces-2.1.29-10.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpclient-4.5.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/httpcore-4.4.4.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/commons-codec-1.11.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-api-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-locator-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/hk2-utils-2.4.0-b34.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/javax.annotation-api-1.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jaxrs-ri-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/jersey-guava-2.22.2.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/validation-api-1.1.0.Final.jar:/opt/IBM/WebSphere/AppServer_2/trunkLib/classes:/opt/IBM/WebSphere/AppServer_2/trunkLib/javassist-3.23.1-GA.jar
   Parent: com.ibm.ws.classloader.ProtectionClassLoader@a5c5ece8


它看起来像PrimeFaces——不幸的是,在这种情况下PrimeFaces必须在WAS提供的JSF 2.2捆绑包中找到这些类。将
primefaces-6.2
移出应用程序
trunk80.war
并移入隔离的共享库
trunkLib
应该可以解决这个问题。

首先让我们开始,primefaces源代码是开放的,很容易调试。只需在源代码中进行简单搜索(在IDE或GitHub中本地搜索)即可获得源代码。您可以检查调用它的位置。在调试模式下运行是最简单的,但是在GitHub中的PrimeFaces存储库中搜索只会显示其中的一个位置

接下来,您应该检查

PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()
这个函数的getter返回一个属性,该属性从

atLeastJsf22 = LangUtils.tryToLoadClassForName("javax.faces.flow.Flow") != null;
在这里,您可以看到,为了确定“最小”版本,他们尝试加载一个仅存在于JSF2.2或更高版本中的类。这意味着,无论您是否使用父类优先加载,或者独立于PrimeFaces的放置位置,如果
javax.faces.flow.flow
位于类路径上,PrimeFaces都会认为JSF 2.2是可用的。JSF2.1是否也在类路径上,甚至在JSF2.2之前,这并不重要,因为这个特定的类在JSF2.1中不存在,并且总是从JSF2.2 JAR加载

要解决这个问题,你有三个选择

  • 覆盖PrimeFaces(例如,通过从web.xml中读取显式上下文属性,以便您可以选择性地手动覆盖版本检测,并使用PrimeFaces为此创建一个pull请求,以便他们可以接受它作为改进)
  • “更正”覆盖JSF版本的方法类似于
  • 切换到JSF2.2

后者将是最好的,甚至可能只是开箱即用。

是的,这是我尝试的第一件事,但我仍然得到同样的例外。
PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()
atLeastJsf22 = LangUtils.tryToLoadClassForName("javax.faces.flow.Flow") != null;