Hi,
Been long term using apache-isis 1.x for client delivered prototypes
successfully. Recently just in 5 weeks we delivered moderately complex
app on Azure in production using 2.0.0-M7 (We knew its not release
version, but we have been betting on our team's previous know-how and
solid isis code-base on fixing any blockers we might get in our way, can
share more details if anyone wants on user list for building
confidence.) Thank you all here for having such a solid piece of
opensource available for enterprise applications.
Talking about blockers we found, the most notorious one, which we
are not sure how to help solve within apache-isis is this one.
"In Java SE 9, threads that are part of the fork/join common pool
will always return the system class loader as their thread context class
loader. In previous releases, the thread context class loader may have
been inherited from whatever thread causes the creation of the fork/join
common pool thread, e.g. by submitting a task. An application cannot
reliably depend on when, or how, threads are created by the fork/join
common pool, and as such cannot reliably depend on a custom defined
class loader to be set as the thread context class loader."
So in summary, the spring-boot class-loader is not available to any
of the work being done in fork-join pool (e.g. submitted for async
executions or parallel streams ) and that raises some odd
"ClassNotFoundExceptions".
The easiest way to reproduce is :
~/github/isis-app-simpleapp$ mvn clean install
~/github/isis-app-simpleapp$ java -jar
webapp/target/simpleapp-jpa-webapp-2.0.0-M7-exec.jar
It would fail with following Jaxb related classes not found error,
which are in-fact available in spring-boot classloader but the
ForkJoinPool.commonPool-worker uses system-class loader where these
would not exists
ERROR 13763 --- [onPool-worker-3]
o.a.i.c.r.m.MenuBarsLoaderServiceDefault :
org.apache.isis.core.config.viewer.web.WebAppContextPath: could not
find readable resource class path resource [menubars.layout.xml] for
the Menubars-Layout.
java.lang.RuntimeException: unrecoverable error: 'Error unmarshalling
XML; object class is
'org.apache.isis.applib.layout.menubars.bootstrap3.BS3MenuBars'' with
cause ...
at
org.apache.isis.commons.internal.exceptions._Exceptions.unrecoverable(_Exceptions.java:144)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.commons.internal.resources._Xml.verboseException(_Xml.java:201)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService$Simple.fromXml(JaxbService.java:160)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService.fromXml(JaxbService.java:83)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.core.runtimeservices.menubars.MenuBarsLoaderServiceDefault.loadMenuBars(MenuBarsLoaderServiceDefault.java:101)
~[isis-core-runtimeservices-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.core.runtimeservices.menubars.MenuBarsLoaderServiceDefault.menuBars(MenuBarsLoaderServiceDefault.java:95)
~[isis-core-runtimeservices-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.core.runtimeservices.menubars.bootstrap3.MenuBarsServiceBS3.loadOrElse(MenuBarsServiceBS3.java:138)
~[isis-core-runtimeservices-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.core.runtimeservices.menubars.bootstrap3.MenuBarsServiceBS3.menuBarsDefault(MenuBarsServiceBS3.java:130)
~[isis-core-runtimeservices-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.core.runtimeservices.menubars.bootstrap3.MenuBarsServiceBS3.menuBars(MenuBarsServiceBS3.java:119)
~[isis-core-runtimeservices-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.core.runtimeservices.menubars.bootstrap3.MenuBarsServiceBS3.menuBars(MenuBarsServiceBS3.java:82)
~[isis-core-runtimeservices-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.menu.MenuBarsService.menuBars(MenuBarsService.java:61)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.core.metamodel.specloader.SpecificationLoaderDefault.createMetaModel(SpecificationLoaderDefault.java:301)
~[isis-core-metamodel-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.commons.internal.concurrent._ConcurrentTask$3.innerCall(_ConcurrentTask.java:150)
[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.commons.internal.concurrent._ConcurrentTask$3.innerCall(_ConcurrentTask.java:146)
[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.commons.internal.concurrent._ConcurrentTask$1.innerCall(_ConcurrentTask.java:109)
[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.commons.internal.concurrent._ConcurrentTask.run(_ConcurrentTask.java:86)
[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1407)
[?:?]
at
java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) [?:?]
at
java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
[?:?]
at
java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) [?:?]
at
java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) [?:?]
* at
java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
[?:?]*
Caused by: java.lang.RuntimeException: unrecoverable error: 'Error
obtaining JAXBContext for class; object class is
'org.apache.isis.applib.layout.menubars.bootstrap3.BS3MenuBars'' with
cause ...
at
org.apache.isis.commons.internal.exceptions._Exceptions.unrecoverable(_Exceptions.java:144)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.commons.internal.resources._Xml.verboseException(_Xml.java:201)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.commons.internal.resources._Xml.contextOf(_Xml.java:226)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705)
~[?:?]
at
org.apache.isis.commons.internal.resources._Xml.jaxbContextFor(_Xml.java:217)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService$Simple.jaxbContextForClass(JaxbService.java:206)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService$Simple.fromXml(JaxbService.java:157)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
... 19 more
Caused by: javax.xml.bind.JAXBException: Implementation of JAXB-API
has not been found on module path or classpath.
at
javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:232)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:375)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
org.apache.isis.commons.internal.resources._Xml.contextOf(_Xml.java:224)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705)
~[?:?]
at
org.apache.isis.commons.internal.resources._Xml.jaxbContextFor(_Xml.java:217)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService$Simple.jaxbContextForClass(JaxbService.java:206)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService$Simple.fromXml(JaxbService.java:157)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
... 19 more
Caused by: java.lang.ClassNotFoundException:
com.sun.xml.bind.v2.ContextFactory
at
jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
~[?:?]
at
jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
~[?:?]
at java.lang.ClassLoader.loadClass(ClassLoader.java:522) ~[?:?]
at
javax.xml.bind.ServiceLoaderUtil.nullSafeLoadClass(ServiceLoaderUtil.java:92)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
javax.xml.bind.ServiceLoaderUtil.safeLoadClass(ServiceLoaderUtil.java:125)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:230)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at javax.xml.bind.ContextFinder.find(ContextFinder.java:375)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:691)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:632)
~[jakarta.xml.bind-api-2.3.3.jar!/:2.3.3]
at
org.apache.isis.commons.internal.resources._Xml.contextOf(_Xml.java:224)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1705)
~[?:?]
at
org.apache.isis.commons.internal.resources._Xml.jaxbContextFor(_Xml.java:217)
~[isis-commons-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService$Simple.jaxbContextForClass(JaxbService.java:206)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
at
org.apache.isis.applib.services.jaxb.JaxbService$Simple.fromXml(JaxbService.java:157)
~[isis-applib-2.0.0-M7.jar!/:2.0.0-M7]
... 19 more
P.S. To note, the spring-boot:run and integration test launchers
use exploded-jar deployment thus these errors won't come in an
IDE/build/test, but only when using jar based deployment environment/docker.
It seems the proper fix is that async executions should be using
custom pool/executor. It would be better if someone from core team can
confirm about the solution, we would be happy to help patch.
Related details :
https://stackoverflow.com/a/49426561
https://stackoverflow.com/a/59444016
https://stackoverflow.com/a/64455537 (we did custom rebuild of exe jar
to solve this)
Thanks,
Dhruv