2010-07-30 37 views
0

任何想法,爲什麼我得到這個錯誤? (是的,我擡頭錯誤,仍然沒有找到一個解決方案)Java自定義類加載器

我的錯誤:

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(); 
     } 
    } 
} 

客戶端。 java:

package org.fellixombc.mysql.net; 

public class Client { 
    public Client() { 
     System.out.println("Hello!"); 
    } 
} 

MysqlC lassLoder.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; 
    } 
} 

回答

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; 

既然你不處理內置樣的對象類,我想你需要趕上從loadClassData的FileNotFoundException異常在你的findClass,然後調用super.findClass。例如爲:

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; 
+0

現在,出於某種原因,它正試圖打開BIN \ java的目錄\ lang \ Object.class java.io.FileNotFoundException:BIN \ java的目錄\ lang \ Object.class(系統找不到指定的路徑) 但我不知道爲什麼。 – Fellixombc 2010-07-30 22:53:29

+0

當我打印出className,我得到org.fellixombc.mysql.net.Client java.lang.Object 所以我必須搞砸了findClass() – Fellixombc 2010-07-30 22:59:20

+0

啊,謝謝。我收到了另一個錯誤,但我想我可以處理這個錯誤。無論如何,謝謝你的時間! – Fellixombc 2010-07-30 23:45:44

1

返回之前您正在閱讀僅ñ字節從.class文件到緩衝區(在loadClassData)(N =類名的長度)。

您需要在返回正確定義的類的緩衝區之前讀取整個類的內容。

+1

所以一個簡單的解決方案是使用DataInputStream並使用readFully()方法? – Fellixombc 2010-07-30 22:39:54

+0

並非如此,您可以使用FileInputStream,但您需要閱讀該課程的全部內容。 loadClassData()中的第二行是問題的原因:byte buff [] = new byte [size];而應該是實際文件的大小。 – 2010-07-30 22:44:10

相關問題