Thursday, November 11, 2010

Using OSGi in JBoss AS7

Recently the first milestone of JBoss Application Server 7 has been released which now comes with OSGi support built-in!

OSGi Support in JBoss AS7 what does that mean?
It means that AS7 comes with an OSGi framework inside that you can use to deploy your OSGi bundles in. Besides providing standards-compliant OSGi functionality, the OSGi framework in AS7 will also provide integration with non-OSGi components (such as JavaEE ones) deployed in the Application Server. This is realized by the JBoss OSGi framework that was developed from the ground up with a specific focus to provide the best possible integration with AS7. The framework is mostly the work of Thomas Diesler, although I have also been involved in writing bits of it over the past few months...

Let's give it a go!
So if you're curious, here's a quick demo on how to develop a 'hello world' bundle using Eclipse and deploy it into AS7. But first start by downloading an AS7 build from here: http://www.jboss.org/jbossas/downloads. Unzip it somewhere on disk and start it up by running:
  bin/standalone.sh

Develop your OSGi bundle
You can develop your bundle any way you like. For little projects or simply to get started I always use the Eclipse PDE that's part of the 'classic' distribution. For more serious projects I normally use maven with the Felix Bundle Plugin.

Here I simply follow the PDE wizard to develop my new TestBundle. Go File | New Project | Plug-in Project, specifying a standard OSGi Framework as the target platform:


Select the 'Hello OSGi Bundle' template:


And after hitting 'Finish' you've got a simple OSGi bundle, which has an Activator provided by the template:


For this posting I'm not making any changes to the OSGi bundle code, so let's just simply File | Export it as a deployable plugin:
This puts the OSGi bundle in the directory that you specified in the wizard. In my case the bundle is called TestBundle_1.0.0.jar.

Now deploy in JBoss AS7!
I started AS7 somewhere using the bin/standalone.sh script and it has started up:
...
13:47:22,633 INFO  [org.jboss.as.deployment] (pool-1-thread-2) Started FileSystemDeploymentService for directory /home/davidb/temp/as7/jboss-7.0.0.Alpha1/standalone/deployments
13:47:22,636 INFO  [org.jboss.as.server] (pool-1-thread-1) JBoss AS 7.0.0.Alpha1 "Halloween" started in 3627ms. - Services [Total: 150, On-demand: 7. Started: 143]

Ok, so it has started up. A little bit higher in the log you'll also see:
13:47:21,007 INFO  [osgi] Activating OSGi Subsystem

Good - OSGi is there.
Now I copy my TestBundle_1.0.0.jar into the .../jboss-7.0.0.Alpha1/standalone/deployments folder and a moment later I can see the following message in the log:
13:52:24,116 INFO  [stdout] (pool-1-thread-2) Hello World!!
This is the message printed by our OSGi Bundle Activator running in AS7!


Control the framework through JMX
The OSGi Framework in JBoss AS7 does not currently come with a console application - you can control it through JMX. So let's fire up jconsole, use service:jmx:rmi:///jndi/rmi://127.0.0.1:1090/jmxrmi to connect to the Remote Process:
In the MBean tab you will find the org.osgi tree which allows us to control the OSGi framework through a JMX API standardized in the Enterprise Expert Group. You can find the listBundles() API in the bundleState operations:
Yes, our TestBundle is there, and it has bundle ID 6.

Let's now uninstall it using the framework MBean:
Hit the uninstallBundle JMX API with the bundle ID (6) and you'll see that the bundle gets stopped and then uninstalled.
14:14:00,041 INFO  [stdout] (RMI TCP Connection(13)-127.0.0.1) Goodbye World!!
14:14:00,057 INFO  [org.jboss.osgi.framework.bundle.AbstractBundle] (RMI TCP Connection(13)-127.0.0.1) Bundle uninstalled: TestBundle:1.0.0

You can also control the OSGi framework through a webconsole, which can currently get installed via a separate installer, we're working on making the webconsole available in the AS7 distributable in a future milestone.

Conclusion
OSGi support is now available from the very first milestone of JBoss AS7. Give it a try!
If you have any questions, reach us on the forums: http://community.jboss.org/en/jbossosgi or via JIRA: https://jira.jboss.org/browse/JBOSGI

More in-depth details can be found in Thomas Diesler's blog post: http://jbossosgi.blogspot.com/2010/11/jboss-as7-osgi-integration.html

Thursday, June 17, 2010

Eek! Java reflection can cause NoClassDefFoundError after 15 calls

Now this came as a bit of a surprise to me. Reading this thread on the Felix mailing list...

I can't believe this: when using reflection after about 15 calls, the internal behaviour of the Sun JRE changes. With the changed behaviour comes in a package dependency on the sun.reflect package! When running under OSGi you are very much in charge of what comes in via the classloader so a new package that comes in over the same code path after about 15 calls is bad news - you really want to know your package dependencies up front.
The solution is obviously to import that sun.reflect package in your affected bundle but how are you supposed to know? Let's say you have a test suite that properly tests your code and everything is looking nice. I would imagine that a testsuite doesn't test every method call 15 times to make sure its still ok. Moreover, how do we know it's 15? There could be another optimization lurking in the JRE that requires 300 calls in order for it to be exposed.
Another problem with importing sun.reflect is that it's implementation specific. Do other implementations have a similar issue?

Here's a message to all JVM implementors: optimize all you can but please don't change the package dependency graph after a number of invocations. At the very least make your implementation fail fast, not after x method calls.

There is a bug for this at sun: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6265952
Accepted in 2005 but still open...