2012-12-05 149 views
1

因此,我有一個.class文件,以及它的絕對路徑,我需要知道如何去執行從Java內部的.class文件。如果我也能從中獲得一個Class對象,那將是非常棒的。執行外部.class文件?

我知道方法ClassLoader,但它需要文件的「二進制名稱」。我不確定是否有可能獲得外部.class文件的二進制名稱,但是如果可以的話,那將非常有效!但是,如果沒有,還有其他方法可以執行或獲取外部文件的實例嗎?

/*For those of us who work better with examples.. 
Let's say I have a .class file located at C:/Users/USER/Desktop. So..*/ 

String absolutePath = "C:/Users/USER/Desktop/FILE.class"; 

/*Now, having that, how would I get an instance of that class, or, 
at least, execute it?*/ 
+0

你是指「執行」它是什麼意思?它是否有你想要調用的'main'方法?你可能想參考http://stackoverflow.com/questions/738393/how-to-use-urlclassloader-to-load-a-class-file –

+1

1)FILE.class在默認包中, '桌面'軟件包或其他東西? 2)反思是實現你想要的方式(禁止第4點)。它通常要求在類路徑上有類(通常通過'URLClassLoader'),然後用完全限定名加載它,例如, 'our.com.File'。 3)反射有時是至關重要的,但通常是正確用戶功能的錯誤解決方案。這將提供什麼用戶功能? 4)使用'ProcessBuilder'可以在單獨的'Process'中調用一個具有'static public void main(String [])'的類。 –

回答

4

訣竅是要訪問ClassLoader的defineClass方法。比方說,你想動態加載一個實現了已知接口的隨機類文件(如果你不知道接口,你會使用反射api來查找和調用方法)。

package com.example.fileclassloader; 

public interface Dynamo { 
    public Integer beDynamic(String s); 
} 

某處是實現該接口的編譯類。它可能看起來像:

public class Sample implements com.example.fileclassloader.Dynamo { 

    public Integer beDynamic(String s) { 
    System.out.println(String.format("The value is: %s", s)); 
    return s.length(); 
    } 
} 

我們使用它,我們需要擴展類加載器,所以我們可以訪問的defineClass方法。這一個將只取文件名,加載字節並創建實例:

package com.example.fileclassloader; 

import java.io.File; 
import java.io.IOException; 
import java.security.SecureClassLoader; 

public class MyDynamoClassLoader extends SecureClassLoader { 

     public Object createObjectFromFile(String fileName) throws 
       InstantiationException, IOException, IllegalAccessException { 

      File file = new File(fileName); 
      byte[] classBytes =  
      org.apache.commons.io.FileUtils.readFileToByteArray(file); 
      Class<?> clazz = defineClass(null, classBytes, 0, classBytes.length); 
      return clazz.newInstance(); 
     } 
} 

現在我們需要使用動態加載的類實例。我們將它轉​​換爲我們期待它符合接口,並且使用它像接口的任何其他實例:

package com.example.fileclassloader; 

import java.io.FileNotFoundException; 
import java.io.IOException; 

public class App { 

    public static void main() throws FileNotFoundException, IOException, 
          InstantiationException, IllegalAccessException { 

     String fname = "target/classes/com/example/fileclassloader/Sample.class"; 

     MyDynamoClassLoader loader = new MyDynamoClassLoader(); 
     Dynamo dynamo = (Dynamo) loader.createObjectFromFile(fname); 
     Integer i = dynamo.beDynamic("Testing"); 

     System.out.println(String.format("Dynamo (%s) returned %d", fname, i)); 

    } 

} 

和良好的措施,這裏是構建它的pom.xml文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 

    <groupId>com.example</groupId> 
    <artifactId>fileclassloader</artifactId> 
    <version>1.0-SNAPSHOT</version> 
    <packaging>jar</packaging> 

    <properties> 
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>commons-io</groupId> 
      <artifactId>commons-io</artifactId> 
      <version>2.4</version> 
     </dependency> 
    </dependencies> 
</project>