I'm on GlassFish 4.1, Mojarra 2.2.7, PrimeFaces 5.2. I'm trying to start a JPA entity manager dynamically in a JSF action. The entity manager needs to load the JPA entity classes to be able to execute queries. I created and built the JPA JAR at runtime, so I tried adding it to the class loader in the current thread:
File jpaJar = getMyJpaJarFile();
ClassLoader currentThreadClassLoader = Thread.currentThread().getContextClassLoader();
URLClassLoader urlClassLoader = new URLClassLoader(
new URL[]{jpaJar.toURI().toURL()}
, currentThreadClassLoader
);
Thread.currentThread().setContextClassLoader(urlClassLoader);
This enables me to execute JPQL queries, but it gets me into this JSF mess:
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)
How can I modify the class loader without breaking JSF, or work around this problem?