我正在尝试从用Java创建的OSGi容器运行BnD OSGi包,但根本没有任何事情发生。
在一个模块中,加载和启动包的模块:
public class Launcher {
private static String[] jars = null;
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");
Framework framework = frameworkFactory.newFramework(config);
try {
framework.start();
} catch (BundleException e) {
e.printStackTrace();
}
context = framework.getBundleContext();
Bundle stageModule = install("stage-module-1.0-SNAPSHOT");
try {
stageModule.start();
} catch (BundleException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Launcher();
}
private String[] getJARs() {
if (jars == null) {
List<String> jarsList = new ArrayList<String>();
File pluginsDir = new File("plugins");
for (String jar : pluginsDir.list()) {
jarsList.add(jar);
}
jars = jarsList.toArray(new String[jarsList.size()]);
}
return jars;
}
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 start(String name) {
Bundle bundle = install(name);
if (bundle != null) {
try {
bundle.start();
} catch (BundleException e) {
e.printStackTrace();
}
}
return bundle;
}
protected Bundle install(String name) {
String found = null;
for (String jar : getJARs()) {
if (jar.startsWith(name + "_") || jar.startsWith(name + "-")) {
found = String.format("file:plugins/%s", jar);
break;
}
}
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;
}
}
以下是我要加载的一个捆绑包:
服务:
public interface StageService {
Stage getStage();
}
实现:
public class StageServiceImpl implements StageService {
private final Stage m_stage;
public StageServiceImpl(Stage stage) {
m_stage = stage;
}
@Override
public Stage getStage() {
return m_stage;
}
}
@Component
public class App extends Application {
@Start
public void startBundle() {
Executors.defaultThreadFactory().newThread(() -> {
Thread.currentThread().setContextClassLoader(
this.getClass().getClassLoader());
launch();
}).start();
}
@Override
public void start(Stage primaryStage) throws Exception {
BundleContext bc = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
DependencyManager dm = new DependencyManager(bc);
dm.add(dm.createComponent()
.setInterface(StageService.class.getName(), null)
.setImplementation(new StageServiceImpl(primaryStage)));
}
@Stop
public void stopBundle() {
Platform.exit();
}
}
然后我使用这个模块加载场景图:
@Component
public class UI {
@ServiceDependency
private volatile StageService m_stageService;
private volatile TabPane tabPane;
private final Map<ServiceReference, AppScreen> screens = new ConcurrentHashMap<>();
@Start
public void start() {
Platform.runLater(() -> {
Stage primaryStage = m_stageService.getStage();
primaryStage.setTitle("Tabs example!");
tabPane = new TabPane();
screens.values().forEach(this::createTab);
primaryStage.setScene(new Scene(tabPane, 300, 250));
primaryStage.show();
});
}
private void createTab(AppScreen s) {
Tab tab = new Tab(s.getName());
tab.setContent(s.getContent());
if (s.getPosition() < tabPane.getTabs().size()) {
tabPane.getTabs().add(s.getPosition(), tab);
} else {
tabPane.getTabs().add(tab);
}
tabPane.getSelectionModel().select(tabPane.getTabs().size() - 1);
}
@ServiceDependency(removed = "removeScreen")
public void addScreen(ServiceReference sr, AppScreen screen) {
if (tabPane != null) {
Platform.runLater(() -> {
createTab(screen);
});
}
screens.put(sr, screen);
}
public void removeScreen(ServiceReference sr) {
Platform.runLater(() -> {
AppScreen remove = screens.remove(sr);
Optional<Tab> findAny = tabPane.getTabs().stream()
.filter(t -> t.getText().equals(remove.getName()))
.findAny();
if (findAny.isPresent()) {
tabPane.getTabs().remove(findAny.get());
}
});
}
}
public interface AppScreen {
String getName();
Node getContent();
int getPosition();
}
以下是将组件加载到场景图上的示例模块。
@Component
public class MainScreen implements AppScreen {
@Override
public String getName() {
return "Main";
}
@Override
public Node getContent() {
return new Label("Main screen");
}
@Override
public int getPosition() {
return 0;
}
}
我没有抛出任何错误。我错过了什么?提前谢谢大家。