java.lang.ClassFormatError: Illegal UTF8 string in constant pool in class file Server/Request

Linux服务器上,将本地编译好的文件上传后,Tomcat启动时报错:

Exception in thread "Thread-2" java.lang.ClassFormatError:
Illegal UTF8 string in constant pool in class file Server/Request
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:1847)
at org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:873)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1326)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1205)
at Server.Test.<init>(Test.java:13)
at Server.HttpServer.startServer(HttpServer.java:80)
at Server.HttpServer.run(HttpServer.java:27)
at java.lang.Thread.run(Thread.java:662)

看到这个报错我特别诧异,根据异常提示,Server包下的Request类中某个常量池常量不是合法的UTF-8字符常量

通过异常栈的信息可以看出这是一个类加载器加载类文件过程中(WebappClassLoader),解析class文件时抛出的异常,问题的原因是class文件的格式不符合定义,导致文件解析失败(在Test对象的初始化方法中会首先初始化Request对象,所以可以在异常栈中看到Test.<init>)

Test test = new Test(socket);
Thread t = new Thread(test);
t.start();
public Test(Socket socket) throws Exception{
this.socket = socket;
request = new Request();
}

这样就定位了问题的原因出现在Request类的class文件上,使用javap命令分析一下这个文件

[hadoop@hadoop Server]# javap -verbose Request
Error: error while reading constant pool for Request: unexpected tag at #8: 110

这样就确定了服务器上的这个类文件就是有问题的:常量池中的第8个常量无法解析

本地运行时这个类是没有问题的,那么本地编译的Request.class文件肯定是没问题的,虽然Linux服务器上用的是JDK1.6_45_x64而我本地使用的JDK1.5_15_x86,我认为问题的原因不在于JDK的版本,因为编译版本小于运行版本

在本地使用javap命令查看编译后的文件

E:\Users\...>javap -verbose Request > e:\1.txt

看看1.txt文件中保存的解析结果,常量池中的第八个常量也是没有问题的:

Compiled from "Request.java"
public class Server.Request extends java.lang.Object
SourceFile: "Request.java"
minor version: 0
major version: 49
Constant pool:
const #1 = class #2; // Server/Request
const #2 = Asciz Server/Request;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz CRLF;
const #6 = Asciz Ljava/lang/String;;
const #7 = Asciz ConstantValue;
const #8 = String #9; // \r\n
......

那么就确定了问题发生在本地文件上传至服务器的过程中

使用rz -b命令代替rz命令后,Tomcat运行正常

上一篇:java.lang.ClassFormatError


下一篇:xcode 上 crash 调试的三种方法