ClassRunnerは、現在のJVMと同じクラスパスとライブラリパスを使用して、クラスパス内の任意の使用可能なクラスのメイン機能を実行するためにProcessBuilderをを使用しています。現在のJVMの環境と作業ディレクトリもクローンされます。
警告:ClassRunnerはjava
は、現在のJVMのPATH
にあることを前提としています。あなたはSystem.getProperty("java.home")
に基づいjava
またはjava.exe
を見つけるの周りにいくつかのロジックを配置すること:)
ClassRunner.javaのリスト:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class ClassRunner
{
private final Class<?> classToRun;
public ClassRunner(Class<?> classToRun)
{
this.classToRun = classToRun;
}
public void run(String... args) throws Exception
{
String javaCommand = "java";
String libraryPath = "-Djava.library.path=\"" + System.getProperty("java.library.path") + "\"";
String classpath = "\"" + System.getProperty("java.class.path") + "\"";
ProcessBuilder processBuilder = new ProcessBuilder(javaCommand,
libraryPath,
"-classpath", classpath,
classToRun.getCanonicalName());
processBuilder.redirectErrorStream();
for (String arg : args) processBuilder.command().add(arg);
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) System.out.println(line);
reader.close();
process.waitFor();
}
public static void main(String[] args) throws Exception
{
new ClassRunner(Main.class).run("Hello");
}
}
Main.javaのリスト:
public class Main
{
public static void main(String... args)
{
System.out.println("testing Main");
for (String arg : args) System.out.println(arg);
}
}
残念ながら、新しいJVMインスタンスが必要です。 "動機付け"の段落に(おそらく不明瞭に)述べられているように、私は本質的に同じ完全修飾クラス名(自動生成され、変更するのが難しいかもしれない)のいくつかの異なる.classファイルを持っています。 http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html#loadClass%28java.lang.String,%20boolean%29のように、loadClassは最初に既にロードされているものを検索しますクラス(findLoadedClass)を使用しているため、単に新しいクラスでURLローダーを使用することはできません。 – gatoatigrado
これは、新しいVMを開始する理由ではありません。同一のVM内に同じ完全修飾名を持つ2つの異なるバージョンのクラスを持つことは間違いなく可能です。なぜなら、別のClassLoaderをロードしたときに*別のクラスとみなされるからです。 –
クラスは、その名前とクラスローダーの一意の組み合わせです。アプリケーションサーバは、同じクラス名の多くのバージョンを持ち、いくつかは再ロードして他のものに影響を与えることができます。新しいJVMの開始には有効な用途があります。 GCオプションを変更し、別のバージョンのJavaを実行します。 –