剖析在WAS 6.1.0.19上碰到/snoop时执行不完整而出现ClassFormatError
关键字:WAS Linux 6.1.0.19 snoop ClassFormatError
环境RedHat Linux + WAS 6.1.0.19
部署默认的应用程序 DefaultApplication.ear,访问 /snoop时,出现页面显示不完整,只显示 Servlet Name: 并到 Request Information: 这两项的内容,
然后在页面的源码最下面有一行,虽然源码在最后一行,但是显示却是显示在表格上方,即在 Request Information: 下面
于是只好看此君隐藏在哪个jar里了,通过 JarClassFind 发现在 AppServer\plugins\com.ibm.ws.webcontainer_2.0.0.jar 中。
于是只能通过测试此包是否真的有问题。拷贝一个到另一个目录下,然后执行
在执行解压的过程当中会出现如下错误:
只能说明是包坏了,从另一台机器上面执行同样的解压测试,OK,一切正常,那就下载一个过来,覆盖后重新启动之即可。
附Java Doc的解释为:
当 Java 虚拟机试图读取类文件并确定该文件存在格式错误或无法解释为类文件时,抛出该错误。
与
和
由于在生产环境,坏的包无法拿出来,放上本机正常包的面目,如下图:
真是见怪不怪了。
正常情况下/snoop接下来应当是显示 Request headers: 相关的内容了。
剖析一下看。。。
SRTServletRequest.java
说明了什么问题?匿名类也是仅在需要的时候才去Load,而不是跟主类一并全Load进去。于是 SnoopServlet可以执行一部分,而后面才出错。
部署默认的应用程序 DefaultApplication.ear,访问 /snoop时,出现页面显示不完整,只显示 Servlet Name: 并到 Request Information: 这两项的内容,
然后在页面的源码最下面有一行,虽然源码在最后一行,但是显示却是显示在表格上方,即在 Request Information: 下面
- java.lang.ClassFormatErrorcom/ibm/ws/webcontainer/srt/SRTServletRequest$2unexpectedEOFatoffset=1240
java.lang.ClassFormatError com/ibm/ws/webcontainer/srt/SRTServletRequest$2 unexpected EOF at offset=1240
于是只好看此君隐藏在哪个jar里了,通过 JarClassFind 发现在 AppServer\plugins\com.ibm.ws.webcontainer_2.0.0.jar 中。
于是只能通过测试此包是否真的有问题。拷贝一个到另一个目录下,然后执行
- jarxvfcom.ibm.ws.webcontainer_2.0.0.jar
jar xvf com.ibm.ws.webcontainer_2.0.0.jar
在执行解压的过程当中会出现如下错误:
- java.util.zip.ZipException:invalidentrysize(expected1240butgot1242bytes)
- atjava.util.zip.ZipInputStream.readEnd(ZipInputStream.java(CompiledCode))
- atjava.util.zip.ZipInputStream.read(ZipInputStream.java(CompiledCode))
- atsun.tools.jar.Main.extractFile(Main.java(CompiledCode))
- atsun.tools.jar.Main.extract(Main.java:718)
- atsun.tools.jar.Main.run(Main.java:228)
- atsun.tools.jar.Main.main(Main.java:994)
java.util.zip.ZipException: invalid entry size (expected 1240 but got 1242 bytes)
at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java(Compiled Code))
at java.util.zip.ZipInputStream.read(ZipInputStream.java(Compiled Code))
at sun.tools.jar.Main.extractFile(Main.java(Compiled Code))
at sun.tools.jar.Main.extract(Main.java:718)
at sun.tools.jar.Main.run(Main.java:228)
at sun.tools.jar.Main.main(Main.java:994)
只能说明是包坏了,从另一台机器上面执行同样的解压测试,OK,一切正常,那就下载一个过来,覆盖后重新启动之即可。
附Java Doc的解释为:
- publicclassClassFormatErrorextendsLinkageError
public class ClassFormatError extends LinkageError
当 Java 虚拟机试图读取类文件并确定该文件存在格式错误或无法解释为类文件时,抛出该错误。
与
- unexpectedEOFatoffset=1240
unexpected EOF at offset=1240 ,应当在1240结束,但却没有。
和
- expected1240butgot1242bytes
expected 1240 but got 1242 bytes ,变多了2个字节,呵呵:)
由于在生产环境,坏的包无法拿出来,放上本机正常包的面目,如下图:
真是见怪不怪了。
正常情况下/snoop接下来应当是显示 Request headers: 相关的内容了。
剖析一下看。。。
- SnoopServlet.java
- e=req.getParameterNames();
- if(e.hasMoreElements())
- {
- out.println("<h2>Servletparameters(SingleValuestyle):</h2>");
- out.println("<TABLEBorder=\"2\"WIDTH=\"65%\"BGCOLOR=\"#DDDDFF\">");
- while(e.hasMoreElements())
- {
- Stringname=(String)e.nextElement();
- out.println("<tr><td>"+name+"</td><td>"+req.getParameter(name)+"</td></tr>");
- }
- out.println("</table><BR><BR>");
- }
- publicEnumerationgetAttributeNames()
- {
- /*225*/if(TraceComponent.isAnyTracingEnabled()&&tc.isDebugEnabled())
- /*226*/Tr.debug(tc,"getAttributeNames["+this+"]");
- /*228*/returnnewEnumeration(){
- publicbooleanhasMoreElements()
- {
- /*231*/returniter.hasNext();
- }
- publicObjectnextElement()
- {
- /*235*/returniter.next();
- }
- privateIteratoriter;
- {
- /*229*/iter=_srtRequestHelper._attributes.keySet().iterator();
- }
- }
本文分析了在WAS6.1.0.19环境下访问特定路径时遇到ClassFormatError的问题,并详细记录了解决过程。通过对比不同环境中相同jar包的表现,最终定位到损坏的类文件。


被折叠的 条评论
为什么被折叠?



