打印

剖析在WAS 6.1.0.19上碰到/snoop时执行不完整而出现ClassFormatError

剖析在WAS 6.1.0.19上碰到/snoop时执行不完整而出现ClassFormatError

环境RedHat Linux + WAS 6.1.0.19
部署默认的应用程序 DefaultApplication.ear,访问 /snoop时,出现页面显示不完整,只显示 Servlet Name: 并到 Request Information: 这两项的内容,
然后在页面的源码最下面有一行,虽然源码在最后一行,但是显示却是显示在表格上方,即在 Request Information: 下面
Java代码

  • 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 中。

于是只能通过测试此包是否真的有问题。拷贝一个到另一个目录下,然后执行
Java代码

  • jar xvf com.ibm.ws.webcontainer_2.0.0.jar  

在执行解压的过程当中会出现如下错误:
Java代码

  • 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的解释为:

Java代码

  • public class ClassFormatError extends LinkageError  

当 Java 虚拟机试图读取类文件并确定该文件存在格式错误或无法解释为类文件时,抛出该错误。

Java代码

  • unexpected EOF at offset=1240  

,应当在1240结束,但却没有。

Java代码

  • expected 1240 but got 1242 bytes  

,变多了2个字节,呵呵:)
由于在生产环境,坏的包无法拿出来,放上本机正常包的面目,如下图:



真是见怪不怪了。

正常情况下/snoop接下来应当是显示 Request headers: 相关的内容了。

剖析一下看。。。
Java代码

  • SnoopServlet.java   
  •                 e = req.getParameterNames();   
  •                 if ( e.hasMoreElements() )   
  •                 {   
  •                         out.println("<h2>Servlet parameters (Single Value style):</h2>");   
  •                         out.println("<TABLE Border=\"2\" WIDTH=\"65%\" BGCOLOR=\"#DDDDFF\">");   
  •                         while ( e.hasMoreElements() )   
  •                         {   
  •                                 String name = (String)e.nextElement();   
  •                                 out.println("<tr><td>" + name + "</td><td>" + req.getParameter(name) + "</td></tr>");   
  •                         }   
  •                         out.println("</table><BR><BR>");   
  •                 }  

SRTServletRequest.java
Java代码

  •             public Enumeration getAttributeNames()   
  •             {   

  • /* 225*/        if(TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())   

  • /* 226*/            Tr.debug(tc, "getAttributeNames [" + this + "]");   

  • /* 228*/        return new Enumeration() {   
  •   
  •                     public boolean hasMoreElements()   
  •                     {   

  • /* 231*/                return iter.hasNext();   
  •                     }   
  •   
  •                     public Object nextElement()   
  •                     {   

  • /* 235*/                return iter.next();   
  •                     }   
  •   
  •                     private Iterator iter;   
  •   
  •                        
  •                     {   

  • /* 229*/                iter = _srtRequestHelper._attributes.keySet().iterator();   
  •                     }   
  •         }  

说明了什么问题?匿名类也是仅在需要的时候才去Load,而不是跟主类一并全Load进去。于是 SnoopServlet可以执行一部分,而后面才出错。
简单就是美!
我的Java:http://www.Java2Class.net

TOP