2017-06-04 57 views
0

注意:在我的情況下,如果這很重要,我將使用Apache Felix實現。無法以編程方式啓動軟件包

我寫了我正在使用的測試包。這是非常簡單的「Hello World」的捆綁開始時做的無非就是打印消息更stdout /停止:

public class Activator implements BundleActivator { 

    @Override 
    public void start(BundleContext context) throws Exception { 
     System.out.println("Hello, World."); 
    } 

    @Override 
    public void stop(BundleContext context) throws Exception { 
     System.out.println("Goodbye, World."); 
    } 

} 

還有MANIFEST文件,其中相當沒有意義,因爲當我通過從標準Apache Felix控制檯部署上面捆綁發佈分發(which can be downloaded here)包會啓動並打印出消息。


下一步我試圖做的是使用編程方法部署相同的包。不幸的是,這不適合我。我的代碼看起來如下:

public static void main(String[] args) throws Exception { 
    FrameworkFactory frameworkFactory = getFrameworkFactory(); 
    Framework framework = frameworkFactory.newFramework(null); 

    System.out.println("BundleID = " + framework.getBundleId()); 
    System.out.println("State = " + getState(framework.getState())); 

    framework.init(); 

    System.out.println("BundleID = " + framework.getBundleId()); 
    System.out.println("State = " + getState(framework.getState())); 

    BundleContext bundleContext = framework.getBundleContext(); 
    bundleContext.addBundleListener((event) -> { 
     System.out.println("Bundle Changed Event"); 
    }); 
    bundleContext.addFrameworkListener((event) -> { 
     System.out.println("Framework Event"); 
    }); 
    bundleContext.addServiceListener((event) -> { 
     System.out.println("Service Changed Event"); 
    }); 

    Bundle bundle = bundleContext.installBundle("file://<absolute-path-to-bundle-jar-same-as-above"); 

    System.out.println("BundleID = " + bundle.getBundleId()); 
    System.out.println("State = " + getState(bundle.getState())); 

    bundle.start(); 

    System.out.println("BundleID = " + bundle.getBundleId()); 
    System.out.println("State = " + getState(bundle.getState())); 
} 

private static FrameworkFactory getFrameworkFactory() throws IllegalStateException { 
    ServiceLoader<FrameworkFactory> loader = ServiceLoader.load(FrameworkFactory.class); 

    FrameworkFactory factory = null; 
    for (FrameworkFactory iterator : loader) { 
     if (factory != null) { 
      throw new IllegalStateException("Ambiguous SPI implementations."); 
     } 

     factory = iterator; 
    } 

    return factory; 
} 

private static String getState(int state) { 
    switch (state) { 
    case Bundle.UNINSTALLED: 
     return "UNINSTALLED"; 
    case Bundle.INSTALLED: 
     return "INSTALLED"; 
    case Bundle.RESOLVED: 
     return "RESOLVED"; 
    case Bundle.STARTING: 
     return "STARTING"; 
    case Bundle.STOPPING: 
     return "STOPPING"; 
    case Bundle.ACTIVE: 
     return "ACTIVE"; 
    default: 
     throw new IllegalStateException("Unknown state"); 
    } 
} 

輸出類似於如下:

BundleID = 0 
State = INSTALLED 
BundleID = 0 
State = STARTING 
Bundle Changed Event 
BundleID = 1 
State = INSTALLED 
BundleID = 1 
State = INSTALLED 

所以據我瞭解捆綁安裝得到了但去年4行表示bundle.start()得到某種原因被忽略。

你能指出我錯過了什麼使這項工作?

回答

0

經過小時的調試和更仔細地閱讀javadoc這是因爲框架只是被初始化而不是被啓動。爲了進行示例工作,您只需在framework.init()之後簡單地添加framework.start()(或者只需撥打framwork.start(),如果發現它需要,則調用framework.init())。

因爲有幾個棘手的事情,我要離開這個信息:

  1. 官方文檔Apache Felix有關於嵌入框架到主機應用程序的信息。不幸的是,只有使用Apache Felix定製機制的示例使其不能移植到其他實現。令人困惑的是warning note,如果你想創建便攜式解決方案,你應該使用init()getBundleContext()。整體注引波紋管:

警告felix.systembundle.activators配置屬性是特定於菲利克斯框架實現。如果您希望代碼與其他框架實現協同工作,則應該在框架實例上調用init(),並直接使用getBundleContext()。否則,這種方法會非常相似。

  • 的JavaDoc init()方法沒有提到關於初始化的參數的版本不相同作爲起始的框架內,雖然有init(FrameworkListener...)這樣的信息。
  • 這個框架實際上不會被啓動,直到啓動被調用。