gpt4 book ai didi

java - 来自另一个包的bundle.update()失败

转载 作者:行者123 更新时间:2023-12-01 14:49:03 24 4
gpt4 key购买 nike

我正在构建一个简单的 OSGi 演示应用程序来了解该框架。我想从另一个 bundle 中或从嵌入了 OSGi 框架的应用程序更新 Activity bundle (如 How To Embed OSGi by Neil Bartlett 中所述)。

我的应用程序被分成这些包(我已将代码放在帖子末尾以便于阅读):

  1. com.dc.sszostek.interfaces - 包含一个具有draw()方法的Shape接口(interface)
  2. com.dc.sszostek.implementations - 有 2 个具有此 SymbolicName 的包,每个包都实现 Shape 接口(interface):println 是一条线,另一个是方形。它们的 list 文件是相同的, bundle 仅在实现上有所不同。
  3. com.dc.sszostek.programs - 包含 Painter 程序;它使用 Shape 接口(interface)来绘制()(我使用 OSGi Services - Tutorial by Lars Vogel 来编写它)。
  4. com.dc.sszostek.xmpp - 包含使用 SmackAPI 实现的 Jabber 客户端,等待文件传输并在收到文件时尝试更新 com.dc.sszostek.implementations 包。

我的问题是,当我向应用程序发送不同的实现时,文件会被写入,但 bundle 不会更新。

bundle.update() 被调用,它不会抛出异常,但我的程序不断绘制一条线(或一个正方形,取决于我首先放入的包)。当我从 OSGi 控制台更新包时,它会被正确替换,并且我的演示开始绘制不同的形状。

谁能告诉我我犯的错误在哪里,或者给我指出一个可行的示例?

提前谢谢您。

<小时/>

com.dc.sszostek.interfaces

list .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

形状.java

    package com.dc.sszostek.interfaces;

public interface Shape {
void draw();
}
<小时/>

com.dc.sszostek.implementations

list .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

list .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

list .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();
}
}
<小时/>

最佳答案

不要从 OSGi 中的激活器开始,激活器是过去时代的不幸遗骸。激活器是单例的(这真的很糟糕!),它们迫使您自己处理依赖项。尽管它们有时在非常特殊的情况下很有用,因为它们不依赖于其他 bundle 。然而,几乎所有情况下,声明式服务都是正确的选择。

很多人都想从底层学习 OSGi,但使用激活器就像学习如何驾驶 Fred Flintstone 的汽车在今天的道路上行驶一样。肯定会让自己受伤。

您实际上展示了使用激活器时发生在您身上的所有陷阱。当您启动激活器时,不保证服务存在。您还展示了一个非常糟糕的主意,在激活器中打开与外部服务的连接。激活器启动/停止方法必须非常快才能快速启动所有 bundle 。

无论如何,除了尼尔的建议。您意识到 update() 使用的是您提供的旧网址吗?您是否更改了 URL 指向的文件?您可能希望使用 update(InputStream) 方法来确保包确实更新。

关于java - 来自另一个包的bundle.update()失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15068011/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com