Запустите Java-программу с объектной моделью в качестве параметра - PullRequest
0 голосов
/ 19 июля 2009

Сервер прослушивает порт, ожидая входящих запросов от клиентов (клиент по сути является ejb). Эти запросы передают полную объектную модель в качестве параметра (например, список сотрудников, каждый сотрудник - список задач и т. Д.).

Теперь сервер должен запустить другую Java-программу в новом экземпляре JVM на том же компьютере, с этой объектной моделью в качестве параметра.

Эта другая Java-программа должна быть автономной Java-программой, но я не могу передать объектную модель в качестве параметра методу main (void main(String[] args)).

Так что же делать? Я ищу "простое" решение, например, желательно без базы данных или файла для постоянства. Автономная программа действительно интенсивно использует процессор и не может быть размещена на сервере приложений.

Thx.

Ответы [ 6 ]

4 голосов
/ 19 июля 2009

Запустите приложение и перехватите его входящие / исходящие потоки, затем пропустите через него сериализованную объектную модель. Новое приложение должно десериализовать входные данные из System.in.

Пример концепции (я просто хотел убедиться, что мой пример работает, извините за задержку):

package tests;

import java.io.File;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class AppFirst {
    public static void main(String[] args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("java", "-cp", 
            "./bin", "tests.AppSecond");
        pb.directory(new File("."));
        pb.redirectErrorStream(true);
        Process proc = pb.start();

        ObjectOutputStream out = new ObjectOutputStream(
            proc.getOutputStream());
        ObjectInputStream oin = null;

        for (int i = 0; i < 1000; i++) {
            out.writeObject("Hello world " + i);
            out.flush();
            if (oin == null) {
                oin = new ObjectInputStream(proc.getInputStream());
            }
            String s = (String)oin.readObject();
            System.out.println(s);
        }
        out.writeObject("Stop");
        out.flush();

        proc.waitFor();
    }
}

package tests;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class AppSecond {
    public static void main(String[] args) throws Exception {
        ObjectInputStream oin = null;
        ObjectOutputStream out = new ObjectOutputStream(System.out);
        while (true) {
            if (oin == null) {
                oin = new ObjectInputStream(System.in);
            }
            String s = (String)oin.readObject();
            if ("Stop".equals(s)) {
                break;
            }
            out.writeObject("Received: " + s);
            out.flush();
        }
    }
}

Редактировать: Добавлена ​​зацикленная версия. Обратите внимание, что с OOS должен быть трюк, поскольку он мгновенно начинает читать переданный поток (и блокирует ваше приложение. Если вы делаете это на неправильном шаге - он должен быть обернут ПОСЛЕ первого объекта отправляется дочернему процессу).

1 голос
/ 19 июля 2009

Посмотрите на RMI . Ваш сервер может запустить новую службу, которая, в свою очередь, публикует и экспортирует себя в локальный реестр. Тогда ваш новый сервис может получить объектную модель в качестве параметра для метода с удаленным расширением. Должно быть очень простым, не требующим доступа к файлам или дополнительной службы, и не более тяжелым, чем любые другие ответы.

1 голос
/ 19 июля 2009

Вы можете сериализовать объект и записать его в файловую систему. Затем вы можете прочитать этот сериализованный объект во время выполнения. В качестве альтернативы вы можете использовать JMS для передачи этого объекта в виде потока байтов.

Подробнее о сериализации .

Подробнее о JMS . Я всегда использовал ActiveMQ, проект Apache для своих нужд JMS. Это простой в использовании и очень скальп. Ах да, и это бесплатно.

0 голосов
/ 19 июля 2009

Подход сериализации хорош. Кроме того, вам нужен корневой объект для переноса некоторых ссылок на соответствующие объекты для вызова. В прошлом я выполнял сериализацию всего графа объектов и позволял корневому объекту реализовывать некоторый интерфейс, такой как Runnable, а затем на принимающем узле приводил этот корневой объект к Runnable и выполнял на нем run().

0 голосов
/ 19 июля 2009

В любом случае, вы не можете передать объектную модель, поскольку она существует в памяти. Если вы хотите передать объектную модель, вам нужно будет найти способ кодировать и декодировать эту модель во что-то, что вы можете передать.

Поскольку данные уже отправляются через EJB, сериализация объектов является очевидным выбором, хотя в XML, JSON и т. Д. Нет ничего плохого

Вам также необходимо передать объект из серверной программы во вновь вызванную JVM. Если объектная модель достаточно мала, вы можете передать сериализованный объект в Java-программу в качестве аргумента командной строки. Вы также можете, как предложил Джордж IV, записать его в файловую систему и затем сообщить вашему новому приложению, где найти файл, содержащий сериализованные данные. Вы могли бы использовать JMS. Веб-сервисы. Розетки.

Но если ваше серверное приложение уже основано на EJB, самое простое, что нужно сделать - это вызвать ваше новое приложение на уровне EJB в качестве клиента EJB для запроса данных, которые вы ищете.

0 голосов
/ 19 июля 2009

Один из способов заключается в том, что исходная JVM открывает сокет для прослушивания, а новый экземпляр JVM запускает программу, которая подключается к этому сокету и получает параметры через сокет (сериализация Java по умолчанию, вероятно, будет достаточно хорошей). Таким образом, вам нужно только передать номер порта сокета в качестве параметра main, и файлы / базы данных не нужны. Тот же метод может также использоваться для передачи других команд между JVM.

...