我在GlassFish 4.1、Mojarra 2.2.7、PrimeFaces 5.2上。我试图在JSF操作中动态地启动一个JPA实体管理器。实体管理器需要加载JPA实体类才能执行查询。我在运行时创建并构建了JPAJAR,所以我尝试将它添加到当前线程中的类加载器中:
File jpaJar = getMyJpaJarFile();
ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader urlClassLoader = new URLClassLoader(
new URL[]{jpaJar.toURI().toURL()}
, currentThreadClassLoader
);
Thread.currentThread().setContextClassLoader(urlClassLoader);
这使我能够执行JPQL查询,但它让我陷入了JSF混乱:
Severe: Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI?
Severe: Application was not properly initialized at startup, could not find Factory: javax.faces.component.visit.VisitContextFactory. Attempting to find backup.
Severe: Error Rendering View[/my.xhtml]
java.lang.IllegalStateException: Could not find backup for factory javax.faces.component.visit.VisitContextFactory.
at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:1135)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:379)
at javax.faces.component.visit.VisitContext.createVisitContext(VisitContext.java:219)
at com.sun.faces.application.view.FaceletPartialStateManagementStrategy.saveView(FaceletPartialStateManagementStrategy.java:468)
at com.sun.faces.application.StateManagerImpl.saveView(StateManagerImpl.java:89)
at javax.faces.application.StateManager.getViewState(StateManager.java:593)
at com.sun.faces.context.PartialViewContextImpl.renderState(PartialViewContextImpl.java:483)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:325)
at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:60)
at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:219)
at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:1004)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:430)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:337)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
如何在不破坏JSF的情况下修改类加载器,或者解决这个问题?
我复制了它,当我将GlassFish捆绑的Mojarra 2.2.7升级到当前可用的2.2.11时,问题消失了(只需替换/modules
文件夹中的javax.faces.jar
(。事实证明,它已经在Mojarra 2.2.9中得到了承认,并根据问题3341"Mojarra对ThreadContextClassLoader替换没有弹性"进行了修复。