java - 嵌入式OSGi : accessing dynamically loaded bundle components

标签 java runtime osgi bundle

在处理将 OSGi 嵌入到应用程序/库中、在运行时加载 bundle 然后在主机应用程序/库中使用该 bundle 时,我有点迷失了。

这是从我的主机加载 bundle 的代码:

// framework is the embedded OSGi framework
Bundle b = framework.getBundleContext().installBundle( "file:/project_dir/bundle/MyBundle.jar" );
b.start();

该 bundle 由一些非常简单的东西组成:

public class Activator implements BundleActivator
{
  @Override
  public void start( BundleContext context )
  {
  }

  @Override
  public void stop( BundleContext context )
  {
  }

  public String shout()
  {
    return "let it all out";
  }
}

我如何从主机应用程序访问shout()方法?

最佳答案

以下是有关按照前面的答案使用的代码的一些详细信息:

  • 包含您的方法的接口(interface)。

    public interface MyInterface {
        String shout();
    }
    

    您会注意到,为您的库提供两个 bundle 是一个好方法:一个用于接口(interface),另一个用于实现。当实现包再次出现时,它将防止出现“刷新包”问题。

  • 上一个接口(interface)的实现:

    public class MyImpl implements MyInterface {
        public String shout() {
            return "let it all out";
        }
    }
    

    bundle 不需要导出实现的包。 MyImpl 类不会被服务使用者直接使用。

  • 激活器的新代码:

    public class Activator implements BundleActivator {
        private ServiceRegistration serviceRegistration;
    
        @Override
        public void start( BundleContext context ) {
            this.serviceRegistration = context.registerService(
                MyInterface.class,
                new MyImpl(), new HashMap<String,String>());
        }
    
        @Override
        public void stop( BundleContext context ) {
            if (serviceRegistration!=null) {
                serviceRegistration.unregister();
            }
        }
    }
    

    包含激活器和实现的包需要在其文件 MANIFEST.MF 中导入接口(interface)的包。激活器的包或实现都不需要在此文件中导出。它们必须保留在 bundle 内部。

  • 使用另一个包中的服务的类

    public void callService() {
        ServiceReference<MyInterface> reference
         = bundleContext.getServiceReference(MyInterface.class);
        MyInterface foo = bundleContext.getService(reference);
        try {
            //use service
            String msg = service.shout();
        } finally {
            bundleContext.ungetService( reference );
        }
    }
    

    你可以注意到,消费者只需要导入接口(interface)的包(而不是实现包)。此外,您需要小心处理 OSGi 的动态。该服务可能会在两次调用之间发生!

希望对你有帮助 蒂埃里

关于java - 嵌入式OSGi : accessing dynamically loaded bundle components,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28773862/

相关文章:

java - 从同一个类调用静态方法与不同类Java调用静态方法

java - 当第 3 方 Java 库作为单个 jar 的集合提供时,将它集成到 Maven 项目中的最佳方法是什么?

java - 正则表达式匹配所有\p{L} 但不匹配\p{Alpha}

visual-studio-2010 - MS缺少VSTO 4.0 Runtime下载?

maven - hbase 和 osgi - 找不到 hbase-default.xml

java - 使用rest来通信两个基于表单的springboot应用程序

.net - 需要带有 <supportedRuntime/> 的 .NET 4.0 完整配置文件

sql-server - 在 SQL Server 数据库中存储时间间隔的最佳方法是什么

java - 如何使用osgi在CQ5中显示 "hello world"

java - Apache Karaf - 缺少依赖项(看起来是数据源)