2013-03-31 2 views
1

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

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

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

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

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

Я создал проект затмении «OSGiContainer», который в основном содержит банку Apache Felix и пакеты сторонних я хочу, чтобы развернуть (как Гого shell), аналогично описанной в проекте here. Затем я создал второй проект «MyBundle», содержащий мой пакет. Я хочу запустить контейнер OSGi, запустив проект OSGiContainer, а затем просто развернусь на своем комплекте и протестирую свои изменения, запустив проект MyBundle в OSGiContainer, который я просто хочу продолжать работать в течение всего времени разработки.

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

  • OSGiContainer
    • бин (содержит ФЕЛИКС баночку)
    • пучки (пучки сторонних)
    • конф (Felix»файл 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 команды на раковине каждый раз, когда не так много удовольствия ...Поэтому, даже если вы можете дать мне способ сварить это до меньшего количества команд, чтобы напечатать его, это было бы большим улучшением уже.

UPDATE

Я взломал вокруг немного и придумал ниже класса. Это адаптация примера 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

Любой причины, почему вы хотите жить с такой сложной установкой ?? С bndtools все, что вы делаете, - это после смены источника, и каждый сменившийся пакет получает перераспределение за считанные секунды. И он использует настоящие банки, а не то, что «почти» выглядит так. –

+0

На самом деле, настройка моего проекта OSGiContainer происходит прямо с самого сайта Apache. Другой пакетный проект прост, как может быть. Вы говорите без инструментов BND, что будет очень сложно передислоцировать? В настоящее время я использую Maven с m2eclipse, поэтому я не решаюсь добавить еще один инструмент сборки в микс ... –

+0

Уточнение: я использую Maven с maven-bundle-plugin для сборки пакета через BND и интеграции Maven в Eclipse с плагин m2eclipse ... Я попробую bndtools. –

ответ

1

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

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

Зависимость доступна от мавена-центре.

Зависимость является:

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

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

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

+0

Спасибо, классная идея, я попробую это, как только я снова запустил разработку пакета OSGi (в настоящее время работает над чем-то совсем другим) –