Вопрос новичка Java: более богатые подпроцессы Java - PullRequest
1 голос
/ 01 июня 2009

Я хотел бы создать подпроцессную виртуальную машину Java (через вызов API Java) и связаться с ней.

Может быть, я просто не ищу нужную вещь в Google, но я все время возвращаюсь к Runtime.exec (), а это не то, что мне нужно. Я знаю, что могу подключить стандартный ввод / вывод и использовать различные методы сериализации или использовать удаленный вызов методов, но они кажутся громоздкими / тяжелыми. Кажется, что вызов API может быть более надежным, чем попытка вызова Runtime.exec ("/ usr / bin / java -cp [system.getclasspath] ...").

Цель / мотивация этого состоит в том, что динамическая перезагрузка классов со многими зависимостями кажется несколько хитрой (несколько сайтов упоминают о чтении файла .class и передаче его в [ClassLoader] .defineClass, но это не обрабатывает загрузку файлов зависимых классов). Что ж). Если мне не нужна большая пропускная способность или низкая задержка, я думаю, что новый экземпляр JVM будет работать нормально; это то, что общение с ним кажется громоздким. В любом случае этот вопрос не является приоритетным; Я, вероятно, пойду прямым путем и посмотрю, как я могу загрузить файлы зависимых классов (например, файлы для внутренних классов).

Ответы [ 4 ]

2 голосов
/ 01 июня 2009

Я бы определенно рекомендовал взглянуть на механизм загрузчика классов, используемый контейнером сервлета Tomcat - они, похоже, точно имеют ту же проблему загрузки классов и, похоже, решили ее очень хорошо.

2 голосов
/ 01 июня 2009

Пока классы, которые вы хотите загрузить, находятся в файле JAR или в дереве каталогов, отдельном от вашего основного приложения, использование URLClassLoader и запуск их в отдельном потоке работает нормально. AFAIK все серверы приложений Java работают так, поэтому это определенно проверенный метод.

0 голосов
/ 04 августа 2010

ClassRunner (показано в листинге ниже) использует ProcessBuilder для запуска функции main любого доступного класса в вашем пути к классам с использованием того же пути к классу и библиотеки путь как текущая JVM. Он даже клонирует среду и рабочий каталог текущей JVM.

Предупреждение: ClassRunner предполагает, что java находится на PATH текущей JVM. Вы можете использовать логику для поиска java или java.exe, основываясь на System.getProperty("java.home"):)

Список 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);
    }
}
0 голосов
/ 01 июня 2009

Если вы идете по маршруту связи, вы должны рассмотреть Java RMI .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...