Разверните разорванный пакет в Apache Felix с помощью задачи запуска Eclipse

Я ищу способ (пере) развертывания разнесенного пакета (то есть, не скомпрометированного, а в папке) в работающем контейнере Apache Felix OSGi из Eclipse, предпочтительно с использованием задачи запуска.

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

Теперь я думаю, что если бы я мог запускать команды оболочки Gogo из задач запуска Eclipse, это было бы решением, но я также не могу понять, как это сделать. Я полагаю, мне нужен комплект Remote Shell для этого права?

Я начинаю думать о написании клиента telnet на Java, который может подключаться к пакету Remote Shell и выполнять команды Gogo в автоматическом режиме. Я уже видел пример того, что я могу изменить в соответствии со своими потребностями... Однако из-за этого у меня возникает ощущение "изобретать велосипед". Конечно, есть лучший способ?

Некоторые сведения, которые помогут вам понять, что я делаю:

Я создал проект Eclipse "OSGiContainer", который в основном содержит jar-файл Apache Felix и сторонние пакеты, которые я хочу развернуть (например, оболочку Gogo), аналогично настройке проекта, описанной здесь. Затем я создал второй проект "MyBundle", содержащий мой пакет. Я хочу запустить контейнер OSGi, запустив проект OSGiContainer, а затем просто разработать пакет и протестировать свои изменения, запустив проект MyBundle в OSGiContainer, который я просто хочу продолжать работать все время в процессе разработки.

Макет проекта:

  • OSGiContainer
    • корзина (содержит банку Феликса)
    • пачки (сторонние пачки)
    • conf (файл config.properties Феликса)
  • MyBundle
    • ЦСИ
    • цель
      • классы

Затем я могу развернуть свой пакет в контейнере OSGi, вызвав эти команды в оболочке Gogo:

install reference:file:../MyBundle/target/classes
start <bundleId>

Для повторного развертывания я вызываю эти команды:

stop <bundleId>
uninstall <bundleId>
install reference:file:../MyBundle/target/classes
start <bundleId>

Вы можете себе представить, что каждый раз вызывать 4 команды на оболочке - это не так уж и весело... Поэтому, даже если вы можете дать мне способ свести это к меньшему количеству команд для ввода, это уже было бы большим улучшением.

ОБНОВИТЬ

Я взломал немного и придумал класс ниже. Это адаптация примера telnet с некоторыми небольшими изменениями и основным методом с необходимыми командами для удаления пакета, а затем переустановить и запустить его. Путь к комплекту должен быть указан в качестве аргумента программы и будет выглядеть так:

reference:file:../MyBundle/target/classes

Я все еще очень приветствую ответы на этот вопрос, поскольку мне не очень нравится это решение вообще. Однако я убедился, что это работает:

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.SocketException;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;

import org.apache.commons.net.telnet.TelnetClient;

public class GogoDeployer {
    static class Responder extends Thread {
        private StringBuilder builder = new StringBuilder();
        private final GogoDeployer checker;
        private CountDownLatch latch;
        private String waitFor = null;
        private boolean isKeepRunning = true;

        Responder(GogoDeployer checker) {
            this.checker = checker;
        }

        boolean foundWaitFor(String waitFor) {
            return builder.toString().contains(waitFor);
        }

        public synchronized String getAndClearBuffer() {
            String result = builder.toString();
            builder = new StringBuilder();
            return result;
        }

        @Override
        public void run() {
            while (isKeepRunning) {
                String s;

                try {
                    s = checker.messageQueue.take();
                } catch (InterruptedException e) {
                    break;
                }

                synchronized (Responder.class) {
                    builder.append(s);
                }

                if (waitFor != null && latch != null && foundWaitFor(waitFor)) {
                    latch.countDown();
                }
            }
            System.out.println("Responder stopped.");
        }

        public String waitFor(String waitFor) {
            synchronized (Responder.class) {
                if (foundWaitFor(waitFor)) {
                    return getAndClearBuffer();
                }
            }

            this.waitFor = waitFor;
            latch = new CountDownLatch(1);
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
                return null;
            }

            String result = null;
            synchronized (Responder.class) {
                result = builder.toString();
                builder = new StringBuilder();
            }

            return result;
        }
    }

    static class TelnetReader extends Thread {
        private boolean isKeepRunning = true;
        private final GogoDeployer checker;
        private final TelnetClient tc;

        TelnetReader(GogoDeployer checker, TelnetClient tc) {
            this.checker = checker;
            this.tc = tc;
        }

        @Override
        public void run() {
            InputStream instr = tc.getInputStream();

            try {
                byte[] buff = new byte[1024];
                int ret_read = 0;

                do {
                    if (instr.available() > 0) {
                        ret_read = instr.read(buff);
                    }
                    if (ret_read > 0) {
                        checker.sendForResponse(new String(buff, 0, ret_read));
                        ret_read = 0;
                    }
                } while (isKeepRunning && (ret_read >= 0));
            } catch (Exception e) {
                System.err.println("Exception while reading socket:" + e.getMessage());
            }

            try {
                tc.disconnect();
                checker.stop();
                System.out.println("Disconnected.");
            } catch (Exception e) {
                System.err.println("Exception while closing telnet:" + e.getMessage());
            }
        }
    }

    private static final String prompt = "g!";
    private static GogoDeployer client;


    private String host;
    private BlockingQueue<String> messageQueue = new LinkedBlockingQueue<String>();
    private int port;
    private TelnetReader reader;
    private Responder responder;
    private TelnetClient tc;

    public GogoDeployer(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void stop() {
        responder.isKeepRunning = false;
        reader.isKeepRunning = false;

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
        }
        responder.interrupt();
        reader.interrupt();
    }

    public void send(String command) {
        PrintStream ps = new PrintStream(tc.getOutputStream());
        ps.println(command);
        ps.flush();
    }

    public void sendForResponse(String s) {
        messageQueue.add(s);
    }

    public void connect() throws SocketException, IOException {
        tc = new TelnetClient();
        tc.connect(host, port);
        reader = new TelnetReader(this, tc);
        reader.start();
        responder = new Responder(this);
        responder.start();
    }

    public String waitFor(String s) {
        return responder.waitFor(s);
    }

    private static String exec(String cmd) {
        String result = "";
        System.out.println(cmd);
        client.send(cmd);
        result = client.waitFor(prompt);
        return result;
    }

    public static void main(String[] args) {
        try {
            String project = args[0];
            client = new GogoDeployer("localhost", 6666);
            client.connect();
            System.out.println(client.waitFor(prompt));
            System.out.println(exec("uninstall " + project));
            String result = exec("install " + project);
            System.out.println(result);
            int start = result.indexOf(":");
            int stop = result.indexOf(prompt);
            String bundleId = result.substring(start + 1, stop).trim();
            System.out.println(exec("start " + bundleId));
            client.stop();
        } catch (SocketException e) {
            System.err.println("Unable to conect to Gogo remote shell: " + e.getMessage());
        } catch (IOException e) {
            System.err.println("Unable to conect to Gogo remote shell: " + e.getMessage());
        }
    }
}

1 ответ

Когда я выполнил то же самое требование (развернуть комплект из цели / классов так быстро, как смогу), моей первой мыслью было также расширение моего контейнера с некоторой функциональностью оболочки. Моя вторая мысль заключалась в том, чтобы написать простой пакет, который открывает окно всегда сверху, и я могу просто перетащить любой проект (ы) из Eclipse (или Total Commander или что-то еще) в это окно. Код, который проверяет, есть ли у папки (папок), которые были отброшены, папка target / classes и будет ли она развернута.

Исходный код доступен по адресу https://github.com/everit-org/osgi-richconsole

Зависимость доступна от maven-central.

Зависимость это:

<dependency>
    <groupId>org.everit.osgi.dev</groupId>
    <artifactId>org.everit.osgi.dev.richconsole</artifactId>
    <version>1.2.0</version>
</dependency>

Вы можете использовать его в процессе разработки и удалить его при настройке живого сервера. Однако это не обязательно, так как если контейнер работает в автономном режиме, всплывающее окно не отображается.

Я назвал это richconsole, так как хотел бы иметь больше возможностей в будущем (не только развертывание):)

Другие вопросы по тегам