2017-02-01 29 views
0

我試圖運行一個JavaFX OSGi的模塊,但我不斷收到錯誤:如何啓動一個JavaFX OSGi包

org.osgi.framework.BundleException: Unable to resolve OSGiDmHelloWorldProvider [7](R 7.0): missing requirement [OSGiDmHelloWorldProvider [7](R 7.0)] osgi.wiring.package; (osgi.wiring.package=javafx.application) Unresolved requirements: [[OSGiDmHelloWorldProvider [7](R 7.0)] osgi.wiring.package; (osgi.wiring.package=javafx.application)] 
    at org.apache.felix.framework.Felix.resolveBundleRevision(Felix.java:4112) 
    at org.apache.felix.framework.Felix.startBundle(Felix.java:2118) 
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:998) 
    at org.apache.felix.framework.BundleImpl.start(BundleImpl.java:984) 

這是我如何加載和啓動模塊:

import org.osgi.framework.Bundle; 
import org.osgi.framework.BundleContext; 
import org.osgi.framework.BundleException; 
import org.osgi.framework.Constants; 
import org.osgi.framework.launch.Framework; 
import org.osgi.framework.launch.FrameworkFactory; 

import java.io.File; 
import java.util.*; 


public class Launcher { 

    private static String[] libs = null; 

    private BundleContext context; 

    private Launcher() { 

     FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next(); 

     Map<String, String> config = new HashMap<String, String>(); 
     config.put("osgi.console", ""); 
     config.put("osgi.clean", "true"); 
     config.put("osgi.noShutdown", "true"); 
     config.put("eclipse.ignoreApp", "true"); 
     config.put("osgi.bundles.defaultStartLevel", "4"); 
     config.put("osgi.configuration.area", "./configuration"); 

     // automated bundles deployment 
     config.put("felix.fileinstall.dir", "./dropins"); 
     config.put("felix.fileinstall.noInitialDelay", "true"); 
     config.put("felix.fileinstall.start.level", "4"); 

     config.put(Constants.FRAMEWORK_BOOTDELEGATION, "javafx.*,com.sun.javafx.*"); 
     config.put(Constants.FRAMEWORK_BUNDLE_PARENT, Constants.FRAMEWORK_BUNDLE_PARENT_APP); 

     Framework framework = frameworkFactory.newFramework(config); 

     try { 
      framework.init(); 
      framework.start(); 
     } catch (BundleException e) { 
      e.printStackTrace(); 
     } 

     context = framework.getBundleContext(); 

     Bundle OSGiDmHelloWorldProvider = install("OSGiDmHelloWorldProvider"); 
     try { 

      OSGiDmHelloWorldProvider.start(); 

     } catch (BundleException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     new Launcher(); 
    } 

    private String[] getLibs() { 
     if (libs == null) { 
      List<String> jarsList = new ArrayList<String>(); 
      File pluginsDir = new File("libs"); 

      System.out.println("PATHS : " + pluginsDir.getAbsolutePath()); 

      for (String jar : pluginsDir.list()) { 
       jarsList.add(jar); 
      } 
      libs = jarsList.toArray(new String[jarsList.size()]); 
     } 
     return libs; 
    } 

    protected Bundle install(String name) { 
     String found = null; 

     for (String jar : getLibs()) { 
      if (jar.startsWith(name)) { 
       found = String.format("file:libs/%s", jar); 
       System.out.println(found); 
       break; 
      } 
     } 
     if (found == null) { 
      throw new RuntimeException(String.format("JAR for %s not found", name)); 
     } 
     try { 
      return context.installBundle(found); 
     } catch (BundleException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
} 

OSGiDmHelloWorldProvider Activator類:

import com.bw.osgi.provider.able.HelloWorldService; 
import com.bw.osgi.provider.impl.HelloWorldServiceImpl; 
import javafx.application.Platform; 
import javafx.scene.Scene; 
import javafx.scene.control.Label; 
import javafx.scene.layout.BorderPane; 
import javafx.stage.Stage; 
import org.osgi.framework.BundleActivator; 
import org.osgi.framework.BundleContext; 
import org.osgi.framework.ServiceRegistration; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

public class ProviderActivator implements BundleActivator { 

    Logger logger = LoggerFactory.getLogger(ProviderActivator.class); 

    Stage stage; 

    private ServiceRegistration registration; 
    BundleContext bundleContext; 

    @Override 
    public void start(BundleContext bundleContext) throws Exception { 
     registration = bundleContext.registerService(
       HelloWorldService.class.getName(), 
       new HelloWorldServiceImpl(), 
       null); 

     Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 
       stage = new Stage(); 
       BorderPane pane = new BorderPane(); 
       Scene scene = new Scene(pane, 400, 200); 
       pane.setCenter(new Label("This is a JavaFX Scene in a Stage")); 
       stage.setScene(scene); 
       stage.show(); 
      } 
     }); 

     System.out.println("STAGE CALLED !!!"); 
    } 

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

     logger.info("Set4Jfx Bundle: stop()"); 
     Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 
       stage.close(); 
      } 
     }); 
    } 
} 

我怎樣才能加載使用了JavaFx在Maven的OSGi應用程序模塊?

謝謝大家提前。

回答

0

我已經發布了一些Drombler FX的第一個版本 - 基於OSGi和Maven的JavaFX模塊化應用框架(POM第一版)。

它負責初始化JavaFX和OSGi。

也許你覺得它有用。應用程序框架是開源的,代碼可在GitHub上找到。

還有一個tutorialGetting Started線索。

+0

Hi @Puce。謝謝回覆。我已經在嘗試Dromler FX。我想學習如何做到這一點。我打算使用Drombler作爲我的主應用程序。你知道如何讓我的問題奏效嗎? –

+1

Drombler FX首先啓動一個JavaFX應用程序,然後是OSGi框架,然後是捆綁軟件目錄中的OSGi軟件包。這是開箱即用的。你不必做任何事情。我想這應該已經回答了關於混合JavaFX和OSGi的問題。如果您有更多Drombler FX問題,請詢問後續問題。如果我誤解了某些內容,請解釋一下。 – Puce

1

錯誤消息意味着您的包導入包javafx.application,並且沒有包導出該包。因此導入無法解決。

我注意到,在您的啓動程序代碼中,您嘗試將bootdelegation設置爲javafx.*。那可能允許類從引導類路徑加載,如果您的包一直運行,但由於未解析的導入它不能得到那麼遠。

如果您打算從啓動類加載器加載JavaFX類,那麼您應該從自己的包中刪除包導入。您還必須安排JavaFX類實際由引導類加載程序提供,因爲AFAIK通常僅在擴展類加載程序中可見。

但是,更好的解決方案是單獨導入,並安排從包中導出javafx.application包。這可以通過系統軟件包使用Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA來完成。

更新

你或許應該看看從@Puce的Drombler FX工具/框架,因爲它聽起來像他已經做了很多的這些設置任務。但是我覺得他的回答並沒有直接解決你爲什麼代碼失敗的問題。

+0

感謝@Neil Bartlett的回覆。我怎麼能從包中導出** javafx.application **? –

+0

構建一個包含該代碼並導出它的包。如果你不確定如何做到這一點,你應該運行OSGi「入門」教程。 –