1

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?

Jasper de Vries
  • 19,370
  • 6
  • 64
  • 102
  • I'm wondering why you don't just inject the `EntityManager` the [usual way](https://stackoverflow.com/questions/4727920/injecting-entity-manager-into-managed-bean). – DavidS Jul 06 '15 at 16:29
  • In my application I generate the JPA classes and build the JAR, so I need to do it at runtime. – Jasper de Vries Jul 06 '15 at 16:32

1 Answers1

1

I reproduced it and the problem disappeared when I upgraded GlassFish-bundled Mojarra 2.2.7 to currently available 2.2.11 (simply replace javax.faces.jar in /modules folder). It turns out that it was already acknowledged and fixed in Mojarra 2.2.9 as per issue 3341 "Mojarra not resilient to ThreadContextClassLoader replacement".

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks! I think our company really should consider migrating to WildFly. The issues in GlassFish 4.1 (and the bundled libraries) keep piling up. – Jasper de Vries Jul 07 '15 at 10:10
  • You're welcome. WildFly has its own set too. [Recent example](http://stackoverflow.com/questions/31263272/el-expressions-in-omnifaces-cdn-resource-handler-not-resolved-in-wildfly-9) ;) We're all humans, after all. – BalusC Jul 07 '15 at 10:12
  • For now I've created an ugly workaround for this problem by starting a new thread (I was async polling for the results anyway). I'll check to see if we can upgrade Mojarra on all servers running GF4.1. Thanks again. – Jasper de Vries Jul 07 '15 at 10:38