【问题标题】:Running OSGI Bundle Projects运行 OSGI 捆绑项目
【发布时间】:2017-08-02 07:43:44
【问题描述】:

我正在开发 Eclipse IDE 并尝试运行 osgi bundle 项目。我使用插件项目创建了 2 个捆绑包。

  1. CalculatorService(充当发布者)
  2. CalculatorClient(充当订阅者)

这是我的项目结构

当我尝试运行CalculatorService 时,它运行良好并且服务处于活动状态。然后一旦CalculatorServiceACTIVE,我运行CalculatorClient。但它停留在RESOLVED 状态,而不是ACTIVE

尽管无法获得 CalculatorClient Bundle ACTIVE,但我尝试启动该服务并得到如下 gogo 异常。

由于此异常表明 CalculatorClient 捆绑包的 start() 方法存在错误,因此我将其附在此。

package calculatorclient;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import calculatorservice.ICalculatorService;

public class CalculatorClient implements BundleActivator {

    ServiceReference servRef;
    private static BundleContext context;

    static BundleContext getContext() {
        return context;
    }

    /*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
     */
    public void start(BundleContext bundleContext) throws Exception {
        CalculatorClient.context = bundleContext;
        System.out.println("Start calculate client service");
        servRef = context.getServiceReference(ICalculatorService.class.getName());
        ICalculatorService calc = (ICalculatorService)context.getService(servRef);

        //Print
        System.out.println("Enter Operator");
        BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
        String oper = br1.readLine();
        BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));
        double no1 = Double.parseDouble(br2.readLine());
        BufferedReader br3 = new BufferedReader(new InputStreamReader(System.in));
        double no2 = Double.parseDouble(br3.readLine());

        System.out.print("Answer is ");
        calc.calculateService(oper, no1, no2);

    }

    /*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
     */
    public void stop(BundleContext bundleContext) throws Exception {
        CalculatorClient.context = null;
        System.out.println("Good Bye !!!");
        context.ungetService(servRef);
    }

}

CalculatorService 包的激活器类

package calculatorservice;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

public class CalculatorActivator implements BundleActivator {

    ServiceRegistration servReg;
    private static BundleContext context;

    static BundleContext getContext() {
        return context;
    }

    /*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
     */
    public void start(BundleContext bundleContext) throws Exception {
        CalculatorActivator.context = bundleContext;
        ICalculatorService calc = new CalculatorServiceImpl();
        servReg = context.registerService(ICalculatorService.class.getName(), calc, null);
    }

    /*
     * (non-Javadoc)
     * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
     */
    public void stop(BundleContext bundleContext) throws Exception {
        CalculatorActivator.context = null;
        servReg.unregister();
    }

}

CalculatorService MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: CalculatorService
Bundle-SymbolicName: CalculatorService
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: calculatorservice.CalculatorActivator
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: org.osgi.framework;version="1.3.0"
Bundle-ActivationPolicy: lazy
Export-Package: calculatorservice

CalculatorClient MANIFEST.MF

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: CalculatorClient
Bundle-SymbolicName: CalculatorClient
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: calculatorclient.CalculatorClient
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Import-Package: calculatorservice, org.osgi.framework;version="1.3.0"
Bundle-ActivationPolicy: lazy

堆栈跟踪

!STACK 0
org.osgi.framework.BundleException: Could not resolve module: org.sonatype.m2e.mavenarchiver [1674]
  Unresolved requirement: Require-Bundle: org.eclipse.m2e.jdt; bundle-version="[1.0.0,2.0.0)"
    -> Bundle-SymbolicName: org.eclipse.m2e.jdt; bundle-version="1.6.2.20150902-0002"; singleton:="true"
       org.eclipse.m2e.jdt [1376]
         Unresolved requirement: Require-Bundle: org.eclipse.m2e.core; bundle-version="[1.6.0,1.7.0)"
           -> Bundle-SymbolicName: org.eclipse.m2e.core; bundle-version="1.6.2.20150902-0002"; singleton:="true"
              org.eclipse.m2e.core [1371]
                Unresolved requirement: Require-Bundle: org.eclipse.m2e.workspace.cli; bundle-version="0.1.0"

    at org.eclipse.osgi.container.Module.start(Module.java:434)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1582)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.incStartLevel(ModuleContainer.java:1562)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.doContainerStartLevel(ModuleContainer.java:1533)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1476)
    at org.eclipse.osgi.container.ModuleContainer$ContainerStartLevel.dispatchEvent(ModuleContainer.java:1)
    at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
    at org.eclipse.osgi.framework.eventmgr.EventManager$EventThread.run(EventManager.java:340)

任何关于为什么我无法将此 CalculatorClient 捆绑包从 RESOLVED 状态变为 ACTIVE 状态的建议将不胜感激。

【问题讨论】:

  • 如果您使用的是 Equinox,请查看您的 OSGi 容器的配置文件夹。如果未另行指定,Equinox 会将错误消息放入配置文件夹中一些唯一命名的文件中。由于您不知道捆绑包的启动顺序,因此您永远不应在 Activator 的启动方法中使用 context.getService(),因为其他捆绑包可能尚未启动。
  • @BalazsZsoldos 。在我的项目中,我最初是通过右键单击该包的MANIFEST.MF 来启动 CalculatorService 包,然后选择Run as -> OSGI Framework。一旦CalculatorService bundle is ACTIVE` 我在CalculatorClient 包的MANIFEST.MF 上做同样的事情。所以在这种情况下,无论`context.getService()如何,捆绑包不会以我运行它们的相同顺序单独启动吗?
  • 嗯,在你的 start 方法的某个地方有一个异常,但我不知道它的堆栈跟踪写入到哪里。因此,我只能建议丑陋的解决方案,您应该用 try-catch 包装 start 方法的整个主体,并在 catch 中调用 e.printstacktrace。你至少会看到真正的例外。
  • @BalazsZsoldos 我确实打印了堆栈跟踪,并添加了我的问题。您能否根据此提出一些建议。我对 osgi bundles 很陌生。
  • 我几乎不认为这是从您的 start 方法中产生的堆栈跟踪。这是一个例外,但它独立于您当前的问题。 Double.parseDouble 函数调用可能有 NumberFormatException。这是我的第一个猜测,但是使用堆栈跟踪而不是猜测来查看异常会更好。请注意,在实际系统中,您不应该阻塞 bundle 的启动方法(例如:等待一些用户输入),因为它会阻塞整个计算机的启动。

标签: eclipse osgi bundle osgi-bundle activator


【解决方案1】:

我对我的两个 Activator 类做了一些小的修改。

  • 我没有使用在start()stop() 方法中声明的bundle context 实例,而是在start()stop() 方法中使用bundlecontext 对象参数。

  • start()stop() 方法之前添加一个@Override 注释。

  • 在实现发布者包中接口的类中的方法声明之前添加@Override注释。

  • 从 Activator 类中删除项目初始化期间创建的任何不必要的默认声明。

发布者的激活器类

package calculatorservice;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;

public class CalculatorActivator implements BundleActivator {

    ServiceRegistration serviceRegistration;

    @Override
    public void start(BundleContext bundleContext) throws Exception {
        ICalculatorService iCalculatorService = new CalculatorServiceImpl();
        serviceRegistration = bundleContext.registerService(ICalculatorService.class.getName(), iCalculatorService, null);
    }

    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        serviceRegistration.unregister();
    }

}

发布者的实现类

package calculatorservice;

public class CalculatorServiceImpl implements ICalculatorService{
    @Override
    public void calculateService(String operator, double no1, double no2){
        String PLUS = "+";
        String MINUS = "-";
        String MUL = "*";
        String DIV = "/";
        if(PLUS.equals(operator))
        {
            System.out.print((no1+no2));
        }
        else if (MINUS.equals(operator)){
            System.out.println((no1-no2));
        }
        else if (MUL.equals(operator)){
            System.out.print((no1*no2));
        }
        else if(DIV.equals(operator)){
            if(no2 == 0.0){
                System.out.print(" \"Divide by zeo error \" ");
            }
            else{
                System.out.print((no1/no2));
            }
        }
        else if (operator == ""){
            System.out.print(" \"Enter value for operator\" ");
        }
        else{
            System.out.print(" \"Enter one of the operators +_*/ \" ");
        }
    }
}

客户的激活器类

package calculatorclient;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;

import calculatorservice.ICalculatorService;

public class CalculatorClient implements BundleActivator {

    ServiceReference serviceReference;

    @Override
    public void start(BundleContext bundleContext) throws Exception {
        System.out.println("Start calculate client Service");
        serviceReference = bundleContext.getServiceReference(ICalculatorService.class.getName());
        ICalculatorService iCalculatorService = (ICalculatorService)bundleContext.getService(serviceReference);

        System.out.println("Enter operator");
        BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
        String operator = br1.readLine();

        System.out.println("Enter no1 = ");
        BufferedReader br2 = new BufferedReader(new InputStreamReader(System.in));
        double no1 = Double.parseDouble(br2.readLine());

        System.out.println("Enter no2 = ");
        BufferedReader br3 = new BufferedReader(new InputStreamReader(System.in));
        double no2 = Double.parseDouble(br3.readLine());

        iCalculatorService.calculateService(operator,no1,no2);
    }

    @Override
    public void stop(BundleContext bundleContext) throws Exception {
        System.out.println("Good Bye!!!");
        bundleContext.ungetService(serviceReference);       
    }

}

然后我分别启动了发布者的MANIFEST.MF。一旦那是ACTIVE,我就启动了客户端的MANIFEST.MF。一旦这两个都是ACTIVE 启动客户端服务,程序将运行良好。

【讨论】:

    猜你喜欢
    • 2014-04-18
    • 2015-03-12
    • 2015-10-04
    • 1970-01-01
    • 1970-01-01
    • 2013-06-22
    • 2013-11-02
    • 2016-01-07
    • 1970-01-01
    相关资源
    最近更新 更多