Primefaces, вызывающие метод javax.faces 2.2, но 2.1 в пути в Websphere 9 - PullRequest
0 голосов
/ 20 марта 2019

У меня есть приложение, развернутое в WAS 9 с использованием пользовательского провайдера jsf (для которого установлено значение DEFAULT в WAS).Банки находятся в общей библиотеке с изолированным загрузчиком классов.Все работало нормально, пока мы не перешли с richfaces на primefaces.Мы используем javax.faces 2.1.29, но по какой-то причине простые лица, кажется, обнаруживают, что мы используем 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

и

> Caused by: java.lang.NoSuchMethodError: 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
   Delegation Mode: PARENT_LAST) called from class org.primefaces.util.Jsf22Helper (loaded from file:/opt/IBM/WebSphere/AppServer_2/profiles/server1/installedApps/loggerheadNode03Cell/trunk80_war.ear/trunk80.war/WEB-INF/lib/primefaces-6.2.jar

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Похоже, что PrimeFaces ищет путь к классам для классов JSF 2.2 - и, к сожалению, в этом случае PrimeFaces должен находить эти классы в пакете JSF 2.2, предоставляемом WAS. Перемещение primefaces-6.2 из вашего приложения trunk80.war в изолированную общую библиотеку trunkLib должно решить эту проблему.

0 голосов
/ 21 марта 2019

Сначала давайте начнем с того, что источник PrimeFaces ОТКРЫТ, он легко отлажен. Простой поиск по источнику (локально в вашей IDE или в GitHub) даст вам источник Jsf22Helper.java . Вы можете проверить, где это называется. Запуск в режиме отладки является самым простым, но поиск в репозитории PrimeFaces в GitHub показывает только одно местоположение в CoreRenderer.java

protected void renderDynamicPassThruAttributes(FacesContext context, UIComponent component) throws IOException {
    if (PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()) {
        Jsf22Helper.renderPassThroughAttributes(context, component);
    }
}

Далее вы должны осмотреть

PrimeApplicationContext.getCurrentInstance(context).getEnvironment().isAtLeastJsf22()

И получатель для этого возвращает свойство, которое получает его логическое значение из

atLeastJsf22 = LangUtils.tryToLoadClassForName("javax.faces.flow.Flow") != null;

Здесь вы видите, что для определения «минимальной» версии они пытаются загрузить класс, который только присутствует в JSF 2.2 или более поздней версии. Это означает, что независимо от того, используете ли вы первую родительскую загрузку классов или нет, или независимо от того, куда вы положили PrimeFaces, если javax.faces.flow.Flow находится на пути к классам, PrimeFaces будет считать, что JSF 2.2 доступен. Не имеет значения, является ли JSF 2.1 также на пути к классам и даже до JSF 2.2, поскольку этот конкретный класс отсутствует в JSF2.1 и будет всегда загружаться из JSF 2.2 jar .

Чтобы исправить это, у вас есть три варианта

  • Переопределить PrimeFaces PrimeEnvironment.java (например, путем чтения явного свойства контекста из web.xml, чтобы вы могли при необходимости вручную переопределить обнаружение версии и создать для него запрос на извлечение с помощью PrimeFaces, чтобы они могли принять это как улучшение
  • «Правильный» способ переопределить версию JSF, аналогичную Как заставить websphere 8.5 использовать mojarra, а не myfaces
  • Переключиться на JSF 2.2

Последний был бы лучшим и мог бы даже работать из коробки.

...