Java 9 出来一段时间了,也试着在Java 9 下运行jAlbum,原以为以Java一贯的向下兼容原则,应该都不用重新在JDK9编译,直接运行即可。然鹅,运行时报错,找不到类文件:
完整的失败日志为:
01 | [2018-01-24 22:48:42.104 ERROR] [main web.context.ContextLoader:220] - Context initialization failed |
02 | org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from ServletContext resource [/WEB-INF/beans.xml]; nested exception is org.springframework.beans.FatalBeanException: Invalid NamespaceHandler class [org.apache.cxf.jaxrs.spring.NamespaceHandler] for namespace [http://cxf.apache.org/jaxrs]: problem with handler class file or dependent class; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException |
03 | at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:412) |
04 | at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:334) |
05 | at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:302) |
06 | at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:143) |
07 | at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:178) |
08 | at org.springframework.beans.factory.support.AbstractBeanDefinitionReader.loadBeanDefinitions(AbstractBeanDefinitionReader.java:149) |
09 | at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:124) |
10 | at org.springframework.web.context.support.XmlWebApplicationContext.loadBeanDefinitions(XmlWebApplicationContext.java:93) |
11 | at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:130) |
12 | at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467) |
13 | at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397) |
14 | at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:276) |
15 | at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:197) |
16 | at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47) |
17 | at org.eclipse.jetty.server.handler.ContextHandler.callContextInitialized(ContextHandler.java:890) |
18 | at org.eclipse.jetty.servlet.ServletContextHandler.callContextInitialized(ServletContextHandler.java:532) |
19 | at org.eclipse.jetty.server.handler.ContextHandler.startContext(ContextHandler.java:853) |
20 | at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:344) |
21 | at org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1501) |
22 | at org.eclipse.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1463) |
23 | at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:785) |
24 | at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:261) |
25 | at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:545) |
26 | at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) |
27 | at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:131) |
28 | at org.eclipse.jetty.server.Server.start(Server.java:452) |
29 | at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:105) |
30 | at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:113) |
31 | at org.eclipse.jetty.server.Server.doStart(Server.java:419) |
32 | at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) |
33 | at com.shentar.frontend.FrontMain.main(FrontMain.java:106) |
34 | Caused by: org.springframework.beans.FatalBeanException: Invalid NamespaceHandler class [org.apache.cxf.jaxrs.spring.NamespaceHandler] for namespace [http://cxf.apache.org/jaxrs]: problem with handler class file or dependent class; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException |
35 | at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:139) |
36 | at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1330) |
37 | at org.springframework.beans.factory.xml.BeanDefinitionParserDelegate.parseCustomElement(BeanDefinitionParserDelegate.java:1325) |
38 | at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.parseBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:135) |
39 | at org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.registerBeanDefinitions(DefaultBeanDefinitionDocumentReader.java:93) |
40 | at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.registerBeanDefinitions(XmlBeanDefinitionReader.java:493) |
41 | at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:390) |
43 | Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException |
44 | at org.apache.cxf.jaxrs.spring.NamespaceHandler.init(NamespaceHandler.java:26) |
45 | at org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(DefaultNamespaceHandlerResolver.java:130) |
47 | Caused by: java.lang.ClassNotFoundException: javax.xml.bind.JAXBException |
48 | at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source) |
49 | at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown Source) |
50 | at java.base/java.lang.ClassLoader.loadClass(Unknown Source) |
51 | at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:560) |
52 | at java.base/java.lang.ClassLoader.loadClass(Unknown Source) |
54 | [2018-01-24 22:48:42.106 ERROR] [main web.context.ContextLoader:220] - Context initialization failed |
简单看了下,jaxb找不到,印象中jaxb是有一个独立的工程,但是jse也集成了。试着额外加载jaxb的mvn库,继续报其他web相关的类WebServiceContext找不到。分析了很久,这个就没有可以替代的。感觉不对劲,Google了半天,找到了这个链接:https://stackoverflow.com/questions/43574426/how-to-resolve-java-lang-noclassdeffounderror-javax-xml-bind-jaxbexception-in-j。Java 9 模块化把javax相关的包都默认禁止访问了,需要添加额外的启动参数才能访问。 修改start.bat,添加
--add-modules java.xml.bind,java.xml.ws,java.xml.ws.annotation
后问题解决:
@ cd /d %~dp0
java --add-modules java.xml.bind,java.xml.ws,java.xml.ws.annotation -Xms512M -Xmx512M -Xdebug -Xrunjdwp:transport=dt_socket,address=4321,server=y,suspend=n -jar start.jar pause
要彻底解决这个问题还不是一件简单的事情,因为其它的jdk版本不支持此参数,不能默认都添加。得在启动脚本中识别运行时的jre环境,分析java版本,只有在java9下才添加该参数。更为麻烦的是,还要考虑各个不同的厂商的版本version号的规则不一样。如OpenJDK和Oracle的命名就不完全一样。模块化挺好的,但是破坏兼容性,Java 9 这事儿干得真不明智。