2014-06-15 29 views
1

我正在處理客戶端服務器應用程序,其中我將一個.class文件從一個jvm複製到另一個。我需要使用反射在第二臺機器(該機器不包含其.java文件)中使用此.class文件創建一個實例,但我收到以下錯誤。此外,我的項目由各種軟件包組成 - 一個用於服務器,另一個用於客戶端。在使用反射時,我嘗試提供類名(複製類),這讓我想知道這是否是一個問題。有沒有類路徑的問題,或不提供完全合格的類名或其他東西?從.class文件創建實例的問題

java Server/remoteServer 
Exception in thread "main" java.lang.NoClassDefFoundError: Server/Registry_stub (wrong name: registry/Registry_stub) 
    at java.lang.ClassLoader.defineClass1(Native Method) 
    at java.lang.ClassLoader.defineClass(ClassLoader.java:800) 
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142) 
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:449) 
    at java.net.URLClassLoader.access$100(URLClassLoader.java:71) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:425) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:358) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:190) 
    at generics.Naming.bind(Naming.java:34) 
    at Server.remoteServer.main(remoteServer.java:17) 

這是我在哪裏遇到問題的方法:

public static void bind(String name, myRemoteInterface obj) throws AlreadyBoundException, RemoteException, IOException { 

    RegistryInterface stub = null; 
    try{ 

     stub = (RegistryInterface)Class.forName("Server.Registry_stub").newInstance(); 
    } catch (InstantiationException | IllegalAccessException 
      | ClassNotFoundException e) { 
     e.printStackTrace(); 
    } 
    stub.bind(name, obj); 

} 

的Registry_stub在編譯在不同的機器和.class文件被複制到客戶端機器,其中所述綁定函數被調用(在名爲服務器的包中)。我的目標是調用Registry_stub類中定義的綁定方法,在客戶端中我使用.class類。

謝謝您的幫助

+0

這是一個有趣的問題,但沒有看到你的代碼,我們只能猜測你是如何處理存儲和發送'.class'文件。 – Pshemo

+0

當您發送'.class'文件時,您是否發送完整的軟件包名稱?你是否將它存儲在類路徑的目錄中的'foo/bar/YourClass.class'結構中,以便classloader可以找到它?我們可以看到處理寫入發送類的代碼嗎? – Pshemo

+0

我實際上並沒有使用代碼發送文件。我剛剛使用scp將編譯過的.class文件直接複製到第二臺機器的服務器文件夾中。我猜這是我錯了。 Iam維護我使用Class.forName(服務器。Registry_stub),我將Registry_stub.class文件複製到Server包文件夾中。 – user3453339

回答

0

由於您沒有發佈任何代碼,我不確定這是否真的是您的問題,但在這裏。


有關包的信息也寫在類文件中。我基於這個假設,事實上存在返回包的反射方法getPackage()。示例

System.out.println(String.class.getPackage().getName()); 

將打印java.laang

爲了能夠裝載送類,你將不得不使用它的全包名,換句話說Class.forName("foo.bar.YourClass")和類的ClassLoader會嘗試搜索YourClass.class文件中表示包所以這個結構必須在裏面放置的目錄([...]表示目錄)

[foo] 
    | 
    +-[bar] 
     | 
     +-YourClass.class 

結構(foo目錄必須放置在裏面類路徑中指定目錄中)。

因此,在您的項目中爲這樣的包結構創建一些目錄並將其添加到您的類路徑中。另外不要忘記發送文件的名稱,而不是全包名稱。

0

當加載一個類時,你總是使用一些類加載器。在你的情況下,我會使用新的類加載器,可以訪問複製的.class文件,並確保在嘗試加載類時使用該類加載器。

要獲得更詳細的幫助,您必須提供更多的上下文。只用你提供的堆棧跟蹤,很難以更具體的方式來幫助你。