为什么我收到此错误的任何想法? (是的,我查了一下错误,但仍未找到解决方案)
我的错误:
Exception in thread "main" java.lang.ClassFormatError: Truncated class file
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
at java.lang.ClassLoader.defineClass(Unknown Source)
at org.fellixombc.mysql.util.MysqlClassLoader.findClass(MysqlClassLoader.java:22)
at org.fellixombc.mysql.util.MysqlClassLoader.loadClass(MysqlClassLoader.java:14)
at org.fellixombc.mysql.Main.main(Main.java:9)
文件:
Main.java
package org.fellixombc.mysql;
import org.fellixombc.mysql.util.MysqlClassLoader;
public class Main {
public static void main(String[] args) {
MysqlClassLoader mcl = new MysqlClassLoader();
try {
mcl.loadClass("org.fellixombc.mysql.net.Client");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
Client.java:
package org.fellixombc.mysql.net;
public class Client {
public Client() {
System.out.println("Hello!");
}
}
MysqlClassLoder.java:
package org.fellixombc.mysql.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class MysqlClassLoader extends ClassLoader {
public MysqlClassLoader() {
super(MysqlClassLoader.class.getClassLoader());
}
@Override
public Class<?> loadClass(String className) throws ClassNotFoundException {
return findClass(className);
}
@Override
public Class<?> findClass(String className) throws ClassNotFoundException {
byte[] b = null;
try {
b = loadClassData(className);
Class c = defineClass(className, b, 0, b.length);
if(c != null)
return c;
return super.findClass(className);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private byte[] loadClassData(String className) throws IOException {
int size = className.length();
byte buff[] = new byte[size];
// Open the file
FileInputStream fis = new FileInputStream("bin/" + className.replace('.', File.separatorChar) + ".class");
fis.available();
fis.read(buff);
fis.close();
return buff;
}
}
答案 0 :(得分:3)
是的,您最多读取的字节数等于文件名中的字符数。相反,您需要阅读整个文件。这是一种方法,使用你建议的readFully。
File f = new File("bin/" + className.replace('.', File.separatorChar) + ".class");
DataInputStream is = new DataInputStream(new FileInputStream(f));
int len = (int)f.length();
byte[] buff = new byte[len];
is.readFully(buff);
is.close();
return buff;
由于您没有处理像Object这样的内置类,我认为您需要从findClass中的loadClassData捕获FileNotFoundException,然后调用super.findClass。 E.g:
try {
try {
b = loadClassData(className);
}
catch(FileNotFoundException fnf) {
return super.findClass(className);
}
Class c = defineClass(className, b, 0, b.length);
if(c != null)
return c;
return super.findClass(className);
} catch (IOException e) {
e.printStackTrace();
}
return null;
答案 1 :(得分:1)
在返回之前,您只从.class文件中读取 N 字节(N =类名长度)到缓冲区(在loadClassData中)。
在返回缓冲区以便正确定义类之前,需要读取整个类的内容。