できれば起動タスクを使用して、Eclipse 内から実行中の Apache Felix OSGi コンテナーに展開されたバンドル (jar ではなくフォルダー内を意味する) を (再) デプロイする方法を探しています。
私はこの質問を見つけました。これには近い答えがありますが、Gogo シェルにコマンドを入力することに依存しているため、長期的な開発の使用には不便です。これには Eclipse の起動タスク メカニズムを使用したいと考えていますが、同様に高速で便利な代替手段があれば、それも受け入れます。
Eclipse の起動タスクから Gogo シェル コマンドを起動できれば、それが解決策になると思いますが、その方法について頭を悩ませることもできません。そのためにはリモート シェル バンドルが必要だと思いますか?
Remote Shell バンドルに接続して自動化された方法で Gogo コマンドを実行できる telnet クライアントを Java で作成することを考え始めています。私は自分のニーズに合わせて変更できる例をすでにいくつか 見てきました...しかし、私はそれから「車輪の再発明」のような感覚を得ています。きっともっと良い方法がありますか?
私が何をしているかを理解するのに役立ついくつかの背景:
here で説明されているプロジェクトのセットアップと同様に、基本的に Apache Felix jar とデプロイしたいサード パーティのバンドル (Gogo シェルなど) を含む Eclipse 'OSGiContainer' プロジェクトをセットアップしました。次に、バンドルを含む 2 番目の「MyBundle」プロジェクトを作成しました。OSGiContainer プロジェクトを起動して OSGi コンテナーを開始し、開発中にずっと実行し続けたい OSGiContainer に MyBundle プロジェクトを起動して、バンドルで開発し、変更をテストしたいと考えています。
プロジェクトのレイアウト:
- OSGiコンテナ
- ビン (フェリックス ジャーを含む)
- バンドル (サードパーティのバンドル)
- conf (Felix の config.properties ファイル)
- マイバンドル
- ソース
- 目標
- クラス
次に、Gogo シェルで次のコマンドを呼び出すことにより、バンドルを OSGi コンテナーにデプロイできます。
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());
}
}
}