CXF 2.7.16: ClassFormatError: JVMCFRE114 field name is invalid; jaxws_asm
CXF 2.7.16: ClassFormatError: JVMCFRE114 field name is invalid; jaxws_asm
我们将 CXF 从 v2.2.6 升级到 v2.7.16。当我们在 Linux 机器上启动 IBM WebSphere Application Server v7.0.0.33 时,报错 jaxws_asm/RetrieveRssFeedResponse:
Caused by: java.lang.ClassFormatError: JVMCFRE114 field name is invalid; class=com/abc/mobile/service/rss/jaxws_asm/RetrieveRssFeedResponse, offset=0
at java.lang.ClassLoader.defineClassImpl(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:287)
at java.lang.ClassLoader.defineClass(ClassLoader.java:224)
at org.apache.cxf.common.util.ASMHelper$TypeHelperClassLoader.defineClass(ASMHelper.java:367)
at org.apache.cxf.common.util.ASMHelper.loadClass(ASMHelper.java:316)
at org.apache.cxf.jaxws.WrapperClassGenerator.createWrapperClass(WrapperClassGenerator.java:229)
这是我们目前的理解:
- 本地Windows机器WAS7.0.0.11不会出现这个错误
- Class jaxws_asm.RetrieveRssFeedResponse 在编译时不存在。相反,它是由 CXF 在运行时生成的。
- 我们的应用代码有Java包:com/abc/mobile/service/rss
Class WrapperClassGenerator in org.apache.cxf/cxf-bundle.jar/2.7.16 appends Java package” jaxws_asm” 在第 160 行:
String pkg = new StringBuilder().append(getPackageName(method)).append(".jaxws_asm").append(anonymous ? "_an" : "").toString();
我们的应用代码com.abc.mobile.service.rss.GlobalProductRssService.java有:
@WebMethod(operationName = "retrieveRssFeed")
Class WrapperClassGenerator in org.apache.cxf/cxf-bundle.jar/2.7.16 appends class name”响应”在第 164 行:
className = new StringBuilder().append(className).append("Response").toString();
我们尝试将asm/asm.jar/3.3.1添加到WEB-INF/lib或WAS7.0/java/jre/lib/ext。没用。
- 我们已通过以下 IBM MustGather 文档启用 class 加载跟踪日志:http://www-01.ibm.com/support/docview.wss?uid=swg21196187.
跟踪日志显示“jaxws.RetrieveRssFeedResponse”正在加载:
[1/5/16 11:39:04:447 EST] 00000014 CompoundClass > loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse this=com.ibm.ws.classloader.CompoundClassLoader@736d736d[PL][war:US-EAR/US.war] Entry
[1/5/16 11:39:04:447 EST] 00000014 CompoundClass > loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse this=com.ibm.ws.classloader.CompoundClassLoader@70207020[app:US-EAR] Entry
[1/5/16 11:39:04:448 EST] 00000014 CompoundClass < loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse failed Exit
[1/5/16 11:39:04:448 EST] 00000014 CompoundClass < loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse failed Exit
我还没有找到为什么上面的class加载跟踪日志会加载“jaxws.RetrieveRssFeedResponse”。如果有人可以分享有关如何解决此 ClassFormatError.
的任何线索,我们将不胜感激
非常感谢您的帮助。该问题已通过从 @WebResult 注释中删除“[]”得到解决。也就是说,原来我们的应用代码有:
@WebMethod(operationName = "retrieveRssFeed")
@WebResult(name = "RssChannelDTO[]")
改成:
错误解决
@WebMethod(operationName = "retrieveRssFeed")
@WebResult(name = "RssChannelDTO")
我们所做的是:
修改CXF/2.7.16/ASMHelper.javadefineClass()方法打印动态生成的classes。一共打印了302 classes
System.out.println("***********ASMHelper.TypeHelperClassLoader.defineClass(): " + name.replace('/', '.'));
try {
java.io.FileOutputStream fos = new java.io.FileOutputStream(name.replace('/', '.') + ".class");
fos.write(bytes);
fos.close();
} catch (java.io.IOException ioe) {
ioe.printStackTrace();
}
在所有生成的 302 个 class 中,只有 RetrieveRssFeedResponse.class 字段名称中有“[]”
@XmlElement(name="RssChannelDTO[]")
private RssChannelDTO[] RssChannelDTO[];
修改CXF/2.7.16/ASMHelper.java增加main方法(因为内部classTypeHelperClassLoader的构造函数是私有的)调用loader.defineClass( ) 方法
运行main方法后,报错:
Exception in thread "main" java.lang.ClassFormatError: Illegal field name "RssChannelDTO[]" in class RetrieveRssFeedResponse
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
at org.apache.cxf.common.util.ASMHelper$TypeHelperClassLoader.defineClass(ASMHelper.java:377)
at org.apache.cxf.common.util.ASMHelper.main(ASMHelper.java:513)
然后我们修改了我们的应用程序代码以从@WebResult 注释中删除“[]”。生成的 RetrieveRssFeedResponse.class 有:
@XmlElement(name="RssChannelDTO")
private RssChannelDTO[] RssChannelDTO;
现在错误消失了,我们的 WebSphere Application Server v7.0 可以正常启动了。
关于IBM class加载跟踪日志只显示"jaxws.RetrieveRssFeedResponse",我估计情况是:
- IBM 日志记录语句在记录期间可能会忽略“_”及其后的任何内容
- 但是 IBM class loader 仍然可以加载 "jaxws_asm.RetrieveRssFeedResponse"
无论如何,这只是我的猜测,我没有检查任何 IBM 源代码。
我们将 CXF 从 v2.2.6 升级到 v2.7.16。当我们在 Linux 机器上启动 IBM WebSphere Application Server v7.0.0.33 时,报错 jaxws_asm/RetrieveRssFeedResponse:
Caused by: java.lang.ClassFormatError: JVMCFRE114 field name is invalid; class=com/abc/mobile/service/rss/jaxws_asm/RetrieveRssFeedResponse, offset=0
at java.lang.ClassLoader.defineClassImpl(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:287)
at java.lang.ClassLoader.defineClass(ClassLoader.java:224)
at org.apache.cxf.common.util.ASMHelper$TypeHelperClassLoader.defineClass(ASMHelper.java:367)
at org.apache.cxf.common.util.ASMHelper.loadClass(ASMHelper.java:316)
at org.apache.cxf.jaxws.WrapperClassGenerator.createWrapperClass(WrapperClassGenerator.java:229)
这是我们目前的理解:
- 本地Windows机器WAS7.0.0.11不会出现这个错误
- Class jaxws_asm.RetrieveRssFeedResponse 在编译时不存在。相反,它是由 CXF 在运行时生成的。
- 我们的应用代码有Java包:com/abc/mobile/service/rss
Class WrapperClassGenerator in org.apache.cxf/cxf-bundle.jar/2.7.16 appends Java package” jaxws_asm” 在第 160 行:
String pkg = new StringBuilder().append(getPackageName(method)).append(".jaxws_asm").append(anonymous ? "_an" : "").toString();
我们的应用代码com.abc.mobile.service.rss.GlobalProductRssService.java有:
@WebMethod(operationName = "retrieveRssFeed")
Class WrapperClassGenerator in org.apache.cxf/cxf-bundle.jar/2.7.16 appends class name”响应”在第 164 行:
className = new StringBuilder().append(className).append("Response").toString();
我们尝试将asm/asm.jar/3.3.1添加到WEB-INF/lib或WAS7.0/java/jre/lib/ext。没用。
- 我们已通过以下 IBM MustGather 文档启用 class 加载跟踪日志:http://www-01.ibm.com/support/docview.wss?uid=swg21196187.
跟踪日志显示“jaxws.RetrieveRssFeedResponse”正在加载:
[1/5/16 11:39:04:447 EST] 00000014 CompoundClass > loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse this=com.ibm.ws.classloader.CompoundClassLoader@736d736d[PL][war:US-EAR/US.war] Entry
[1/5/16 11:39:04:447 EST] 00000014 CompoundClass > loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse this=com.ibm.ws.classloader.CompoundClassLoader@70207020[app:US-EAR] Entry
[1/5/16 11:39:04:448 EST] 00000014 CompoundClass < loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse failed Exit
[1/5/16 11:39:04:448 EST] 00000014 CompoundClass < loadClass com.abc.mobile.service.rss.jaxws.RetrieveRssFeedResponse failed Exit
我还没有找到为什么上面的class加载跟踪日志会加载“jaxws.RetrieveRssFeedResponse”。如果有人可以分享有关如何解决此 ClassFormatError.
的任何线索,我们将不胜感激非常感谢您的帮助。该问题已通过从 @WebResult 注释中删除“[]”得到解决。也就是说,原来我们的应用代码有:
@WebMethod(operationName = "retrieveRssFeed")
@WebResult(name = "RssChannelDTO[]")
改成:
错误解决 @WebMethod(operationName = "retrieveRssFeed")
@WebResult(name = "RssChannelDTO")
我们所做的是:
修改CXF/2.7.16/ASMHelper.javadefineClass()方法打印动态生成的classes。一共打印了302 classes
System.out.println("***********ASMHelper.TypeHelperClassLoader.defineClass(): " + name.replace('/', '.')); try { java.io.FileOutputStream fos = new java.io.FileOutputStream(name.replace('/', '.') + ".class"); fos.write(bytes); fos.close(); } catch (java.io.IOException ioe) { ioe.printStackTrace(); }
在所有生成的 302 个 class 中,只有 RetrieveRssFeedResponse.class 字段名称中有“[]”
@XmlElement(name="RssChannelDTO[]") private RssChannelDTO[] RssChannelDTO[];
修改CXF/2.7.16/ASMHelper.java增加main方法(因为内部classTypeHelperClassLoader的构造函数是私有的)调用loader.defineClass( ) 方法
运行main方法后,报错:
Exception in thread "main" java.lang.ClassFormatError: Illegal field name "RssChannelDTO[]" in class RetrieveRssFeedResponse at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:760) at java.lang.ClassLoader.defineClass(ClassLoader.java:642) at org.apache.cxf.common.util.ASMHelper$TypeHelperClassLoader.defineClass(ASMHelper.java:377) at org.apache.cxf.common.util.ASMHelper.main(ASMHelper.java:513)
然后我们修改了我们的应用程序代码以从@WebResult 注释中删除“[]”。生成的 RetrieveRssFeedResponse.class 有:
@XmlElement(name="RssChannelDTO") private RssChannelDTO[] RssChannelDTO;
现在错误消失了,我们的 WebSphere Application Server v7.0 可以正常启动了。
关于IBM class加载跟踪日志只显示"jaxws.RetrieveRssFeedResponse",我估计情况是:
- IBM 日志记录语句在记录期间可能会忽略“_”及其后的任何内容
- 但是 IBM class loader 仍然可以加载 "jaxws_asm.RetrieveRssFeedResponse"
无论如何,这只是我的猜测,我没有检查任何 IBM 源代码。