1

ファイルとその絶対パスがあり、 Java 内から.classそのファイルを実行する方法を知る必要があります。私もそれからオブジェクト.classを取得できれば素晴らしいことです。Class

loadClassの方法は知ってClassLoaderいますが、ファイルの「バイナリ名」が必要です。外部.classファイルのバイナリ名を取得できるかどうかはわかりませんが、できれば非常にうまくいくでしょう! そうでない場合、外部.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?*/
4

1 に答える 1

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>
于 2012-12-05T04:55:01.520 に答える