Integrating new technologies is something that I like. The combination of JavaFX RIA technology and the OSGi platform was on my wish-list for some time. The title of this entry contains "part 1" since I assume this is an ongoing effort. When combining JavaFX and OSGi, a number of possibilities exist:
The latest OSGi specification contains a framework launch API. This allows the framework to be instantiated by third party code. This is cool, since it allows me to start an OSGi framework without any code change to the framework implementation code.
For my proof of concept, I use the
KnopflerFish framework from Makewave.
This is an Open Source implementation of the OSGi specification, and it is
very readable.
Running the Knopflerfish framework in JavaFX is not too difficult. You have
to be careful with the threading system of JavaFX though ("don't block the
AWT thread", remember?). I did it this way:
This approach leads to 4 classes:
Here is the code:
package com.lodgon.kfix;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Bundle;
import java.util.HashMap;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.TextBox;
import javafx.scene.control.Button;
import javafx.scene.Group;
import javafx.scene.layout.VBox;
import javafx.scene.control.Label;
import javafx.async.Task;
/**
* @author johan
*/
var urlText: TextBox = TextBox {
text: "http://xavier.lodgon.com/osgi/log_all-2.0.0.jar"
width: 282
selectOnFocus: true
}
var installButton: Button = Button {
translateX: 300;
text: "install"
action: function() {
var installer: BundleInstaller = BundleInstaller {
bc:bc;
location:urlText.text;
}
installer.start();
}
}
var installGroup: Group = Group {
translateY:10;
content: [urlText, installButton];
}
public var eventListBox: VBox = VBox {
translateY:50;
};
var stage: Stage = Stage {
title: "Application title"
width: 450
height: 180
scene: Scene {
content: bind [
installGroup,
eventListBox
]
}
}
var bc: BundleContext;
var listener: FxServiceListener ;
function run () {
stage;
var knopflerfish: org.knopflerfish.framework.Main =
new org.knopflerfish.framework.Main();
var factory:FrameworkFactory = knopflerfish.getFrameworkFactory();
var map:HashMap = new HashMap();
var framework: Framework = factory.newFramework(map);
framework.init();
listener = FxServiceListener{};
bc = framework.getBundleContext();
bc.addServiceListener (listener);
bc.addBundleListener (listener);
}
BundleInstaller:
package com.lodgon.kfix;
import javafx.async.JavaTaskBase;
import javafx.async.RunnableFuture;
import org.osgi.framework.BundleContext;
/**
* @author johan
*/
public class BundleInstaller extends JavaTaskBase {
public-init var bc: BundleContext;
public-init var location: String;
var installer: NativeInstaller;
override protected function create() : RunnableFuture {
installer = new NativeInstaller(bc, location);
return installer;
}
}
NativeInstaller:
package com.lodgon.kfix;
import javafx.async.RunnableFuture;
import org.osgi.framework.BundleContext;
/**
*
* @author johan
*/
public class NativeInstaller implements RunnableFuture {
private final String location;
private final BundleContext bc;
public NativeInstaller (BundleContext bc, String loc) {
this.bc = bc;
this.location = loc;
}
@Override
public void run() throws Exception {
System.out.println ("[JVDBG] I have to install bundle at "+location);
bc.installBundle(location);
System.out.println ("[JVDBG] I installed "+location);
}
}
FxServiceListener:
package com.lodgon.kfix;
import org.osgi.framework.*;
import javafx.scene.control.Label;
/**
* @author johan
*/
public class FxServiceListener extends ServiceListener, BundleListener {
override function serviceChanged (evt: ServiceEvent) {
println ("[KFiX] Service changed: {evt}");
var label: Label = Label {
text: "service changed: {evt}"
}
insert label into Main.eventListBox.content;
}
override function bundleChanged (evt: BundleEvent) {
println ("[KFiX] Bundle changed: {evt}");
var label: Label = Label {
text: "bundle changed: {evt}"
}
insert label into Main.eventListBox.content;
}
}
That's it for now, but I have more ideas...
written on 20:21.
Create commentDecember October March January
November September August May February January
December November October September July June May March February January
December November October September August July June May April March February
December November October September August July June May April March February January