我正在構建一個簡單的OSGi演示應用程序以瞭解該框架。我想更新另一個包中的活動包,或者從嵌入OSGi框架的應用程序更新活動包(如How To Embed OSGi by Neil Bartlett中所述)。來自另一個捆綁包的bundle.update()失敗
我的應用程序被分成這些軟件包(我已經放置代碼在帖子的末尾,方便閱讀):
- com.dc.sszostek.interfaces - 包含與單個形狀接口方法draw()
- com.dc.sszostek.implementations - 這個SymbolicName有兩個bundle,每個實現Shape接口:println是一個Line,另一個是Square。兩個清單文件都是相同的,這些軟件包僅在實現中有所不同。
- com.dc.sszostek.programs - 包含一個Painter程序;它使用Shape接口繪製()(我用OSGi Services - Tutorial by Lars Vogel來編寫它)。
- com.dc.sszostek.xmpp - 包含一個使用SmackAPI實現的Jabber客戶端,等待文件傳輸並在接收文件時嘗試更新com.dc.sszostek.implementations包。
我的問題是,當我發送不同的實現到我的應用程序,文件被寫入,但捆綁不會得到更新。
bundle.update()
被調用,它不會拋出異常,但我的程序不斷繪製一條線(或一個正方形,取決於我先放入哪個束)。當我從OSGi控制檯更新軟件包時,它會被正確替換,並且我的演示開始繪製不同的形狀。
任何人都可以告訴我我犯的錯誤在哪裏,或者指向我的工作示例?
預先感謝您。
com.dc.sszostek.interfaces
MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Provider
Bundle-SymbolicName: com.dc.sszostek.interfaces
Bundle-Version: 1.0.0
Export-Package: com.dc.sszostek.interfaces
Shape.java
package com.dc.sszostek.interfaces;
public interface Shape {
void draw();
}
com.dc.sszostek.implementations
個MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Impl
Bundle-SymbolicName: com.dc.sszostek.implementations
Bundle-Version: 1.0.0
Bundle-Activator: com.dc.sszostek.implementations.Activator
Export-Package: com.dc.sszostek.implementations
Import-Package: org.osgi.framework, com.dc.sszostek.interfaces
Activator.java
package com.dc.sszostek.implementations;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import com.dc.sszostek.interfaces.Shape;
public class Activator implements BundleActivator {
public void start(BundleContext ctx) throws Exception {
ctx.registerService(Shape.class.getName(), new Line(), null);
}
public void stop(BundleContext ctx) throws Exception {}
}
Line.java
package com.dc.sszostek.implementations;
import com.dc.sszostek.interfaces.Shape;
public class Line implements Shape {
public void draw() {
System.out.println("*********");
}
}
com.dc.sszostek.programs
清單。MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Prog
Bundle-SymbolicName: com.dc.sszostek.programs
Bundle-Version: 1.0.0
Bundle-Activator: com.dc.sszostek.programs.Activator
Export-Package: com.dc.sszostek.programs
Import-Package: org.osgi.framework, com.dc.sszostek.interfaces
Activator.java
package com.dc.sszostek.programs;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import com.dc.sszostek.interfaces.Shape;
public class Activator implements BundleActivator {
private MyThread thread;
public void start(BundleContext ctx) throws Exception {
ServiceReference ref = getServiceReference(ctx);
thread = new MyThread((Shape)ctx.getService(ref));
thread.start();
}
public void stop(BundleContext ctx) throws Exception {
ServiceReference ref = getServiceReference(ctx);
ctx.ungetService(ref);
thread.stopThread();
}
private ServiceReference getServiceReference(BundleContext ctx) {
ServiceReference ref = ctx.getServiceReference(Shape.class.getName());
return ref;
}
public static class MyThread extends Thread {
private volatile boolean active = true;
private final Shape service;
public MyThread(Shape service) {
this.service = service;
}
public void run() {
while (active) {
service.draw();
try {
Thread.sleep(5000);
} catch (Exception e) {
System.out.println("Thread interrupted: " + e.getMessage());
}
}
}
public void stopThread() {
active = false;
}
}
}
com.dc.sszostek.programs
MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: FileReceiver
Bundle-SymbolicName: com.dc.sszostek.xmpp
Bundle-Version: 1.0.0
Bundle-Activator: com.dc.sszostek.xmpp.Activator
Bundle-ClassPath: ., lib/smack-3.2.1.jar, lib/smackx-3.2.1.jar
Import-Package: org.osgi.framework, javax.net, javax.security.auth.callback, javax.net.ssl, javax.security.sasl,
javax.naming.directory, javax.naming
Activator.java
package com.dc.sszostek.xmpp;
import org.jivesoftware.smack.*;
import org.jivesoftware.smackx.filetransfer.*;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import java.io.File;
import java.io.IOException;
public class Activator implements BundleActivator {
private Connection connection;
public void start(BundleContext bundleContext) throws Exception {
final BundleContext ctx = bundleContext;
try {
connection = new XMPPConnection("JABBER_SERVER");
connection.connect();
connection.login("USER", "PASS");
final FileTransferManager manager = new FileTransferManager(connection);
FileTransferNegotiator.getInstanceFor(connection);
FileTransferNegotiator.setServiceEnabled(connection, true);
manager.addFileTransferListener(new FileTransferListener() {
public void fileTransferRequest(FileTransferRequest request) {
IncomingFileTransfer transfer = request.accept();
File file = new File("D:\\bundles\\" + transfer.getFileName());
try {
file.createNewFile();
} catch (IOException e) {
System.out.println(e.getMessage());
}
try {
transfer.recieveFile(file);
} catch (XMPPException e) {
System.out.println(e.getMessage());
}
Bundle bundle = ctx.getBundle(2); //com.dc.sszostek.implementations is bundle number 2
try {
bundle.update();
} catch (BundleException e) {
System.out.println(e.getMessage());
}
}
});
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
public void stop(BundleContext bundleContext) throws Exception {
connection.disconnect();
}
}
謝謝你的回答。我已經使用'update(InputStream)',它是解決方案的一部分。像Neil Bartlett建議的那樣,我也修改了這個線程。 也感謝您的意見。這對我來說是一個鍛鍊,下一步將會提高解決方案的質量。我有自己的「OSGi在行動」的副本,這將有助於(如果你可以推薦其他值得閱讀的書籍,我也會感到愧疚)。 – 2013-02-27 14:16:19
你應該閱讀的當然是我的書:-)不幸的是,它不是書面的,因爲它很難證明它的寫法:-( – 2013-03-01 07:30:31