Migrating From Spring dm Server
The easiest way to develop Spring-powered OSGi applications is to use SpringSource Tools (Eclipse plug-in) and SpringSource dm Server combo. They allow rapid development such as MANIFEST.MF validation, convenient deployment and automatic downloading of required (and OSGi-fied) libraries. Later on, when you need to migrate to plain OSGi (just like I do), you can follow this tutorial series.
A month ago I started development of an application with SpringSource dm Server (ssdms). In the middle of the project, concerns arose to deploy it in "plain" OSGi container (namely Equinox). The migration was rocky, so I decided to blog it for the sake of sharing.
First I downloaded the bare bone "Framework" from Eclipse. The "Eclipse Equinox" version (listed topmost) is Framework+stuff, but I didn't use it since I wanted to build everything from scratch (and it's stuffed with old Servlet 2.4 and Jetty 5).
The framework is a < 1MB jar runnable with "java -jar JARNAME.JAR -console". It wasn't fun to start it that way, so following instructions in QuickStart Guide (do spend some time reading the last section, it's worth it) I downloaded a native launcher for my Mac from the same download page.
Note for Mac users: Since it's the same launcher used in Eclipse IDE, it doesn't work in Java 6 64-bit. Neither does the Cocoa version.
Verify the framework by running it. At the osgi> console, type ss. It will show one active bundle (which is the framework itself). Type close to shutdown.
osgi> ss Framework is launched. id State Bundle 0 ACTIVE org.eclipse.osgi_3.4.0.v20080605-1900
If you want to enable JMX, open eclipse.ini (it's in Eclipse.app if you're using Mac) and add the following entries:
-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=6789 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false
Run jconsole from Terminal or Command Prompt (assuming JDK/bin in your path) and enter service:jmx:rmi:///jndi/rmi://localhost:6789/jmxrmi in JMX URL. You should be able to see "inside" the framework:

Next step is to fill it with libraries. The easiest way is to copy from ssdms distribution to our Equinox's /plugins:
- Every jar in /lib EXCEPT:
- Jars started with com.springsource.server
- Jars having slf4j if you want "unified" logging like I do (will explain this later)
- Jars started with org.eclipse.osgi because they may conflict with our OSGi framework
- Every jar in /repository/bundles/ext EXCEPT:
- Jars having slf4j and anything related to any logging framework (commons-logging, Log4J) if you want "unified" logging
- Jars having -sources unless you want to keep the source code
- Jars started with org.springframework.osgi because we will use the ones from Spring Dynamic Modules distribution
- Every jar in /repository/bundles/usr EXCEPT:
- Jars having slf4j and anything related to any logging framework (commons-logging, Log4J) if you want "unified" logging
- Jars having -sources unless you want to keep the source code
What is "unified" logging? Well, you might want to unify your logging facility to be like this:

Essentially everything goes to one sink, easing administration. Anyway the logging deserves its own blog entry so I'll skip it now. Let's download Spring Dynamic Modules and copy the following jars from /dist to our Equinox's /plugins:
- spring-osgi-core-VERSION.jar
- spring-osgi-extender-VERSION.jar
- spring-osgi-io-VERSION.jar
- spring-osgi-web-VERSION.jar
- spring-osgi-web-extender-VERSION.jar
Note: For now, you can use (download and put to /plugins) any logging framework library of your choice. Later on, when you decide to use the unified approach, you must replace them with the SLF4J bridges.
You will definitely want Tomcat and Spring Dynamic Modules to run everytime framework is started. You can go to console and start them manually (the framework remembers last active bundles upon shutdown and will start them next time it's started), or you can list them in /configuration/config.ini. The latter is prefered since you can "reset" the framework (delete all configuration and cache) and still have the desired bundles run on startup. To do that, put the following entry:
osgi.bundles=org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start,
catalina.start.osgi-VERSION.jar@3:start, spring-osgi-extender-VERSION.jar@4:start,
spring-osgi-web-extender-VERSION.jar@4:start
eclipse.ignoreApp=true
osgi.noShutdown=true
Verify our configuration by running the framework again. You should see logs of Tomcat and Spring Dynamic Modules activity. More or less you should see something like this:
14:48 Start Thread I o.s.o.w.t.i.Activator - Starting Apache Tomcat/6.0.18 ... 14:48 Start Thread I o.s.o.w.t.i.Activator - Using default XML configuration bundleresource://3/conf/default-server.xml Mar 11, 2009 2:48:09 PM org.apache.catalina.startup.ClusterRuleSetFactory getClusterRuleSet INFO: Unable to find a cluster rule set in the classpath. Will load the default rule set. 14:48 t Dispatcher I o.s.o.e.i.a.ContextLoaderListener - Starting [org.springframework.osgi.extender] bundle v.[1.2.0.m2] Mar 11, 2009 2:48:09 PM org.apache.coyote.http11.Http11AprProtocol init INFO: Initializing Coyote HTTP/1.1 on http-8080 Mar 11, 2009 2:48:09 PM org.apache.catalina.startup.Catalina load INFO: Initialization processed in 227 ms Mar 11, 2009 2:48:09 PM org.apache.catalina.core.StandardService start INFO: Starting service Catalina Mar 11, 2009 2:48:09 PM org.apache.catalina.core.StandardEngine start INFO: Starting Servlet Engine: Apache Tomcat/6.0.18 Mar 11, 2009 2:48:09 PM org.apache.coyote.http11.Http11AprProtocol start INFO: Starting Coyote HTTP/1.1 on http-8080 14:48 Start Thread I o.s.o.w.t.i.Activator - Succesfully started Apache Tomcat/6.0.18 @ Catalina:8080 14:48 Start Thread I o.s.o.w.t.i.Activator - Published Apache Tomcat/6.0.18 as an OSGi service 14:48 t Dispatcher I o.s.o.e.i.s.ExtenderConfiguration - No custom extender configuration detected; using defaults... 14:48 t Dispatcher I o.s.s.t.TimerTaskExecutor - Initializing Timer 14:48 t Dispatcher I o.s.s.t.TimerTaskExecutor - Initializing Timer 14:48 t Dispatcher I o.s.o.w.e.i.a.WarLoaderListener - Starting [org.springframework.osgi.web.extender] bundle v.[1.2.0.m2] 14:48 xtender-Init I o.s.o.w.e.i.a.WarListenerConfiguration - No custom extender configuration detected; using defaults... 14:48 xtender-Init I o.s.o.w.d.t.TomcatWarDeployer - No Catalina Service set; looking for one in the OSGi service registry... 14:48 xtender-Init I o.s.o.w.d.t.TomcatWarDeployer - Found service Catalina
That's it for now, later I will write about making EclipseLink JPA to work (dynamically!) and integrating BlazeDS for Flex remoting.
(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)





Comments
JS Bournival replied on Wed, 2009/03/11 - 7:52am
Alessandro Santini replied on Wed, 2009/03/11 - 8:09am
Andrew McVeigh replied on Wed, 2009/03/11 - 10:16am
in response to:
Alessandro Santini
i don't know if these are the exact reasons, but from his previous article: http://www.jroller.com/wiradikusuma/entry/experience_in_developing_osgi_with
Thomas Wiradikusuma replied on Wed, 2009/03/11 - 10:53am
Jim Moore replied on Wed, 2009/03/11 - 11:00am
Great article. Just a little confused about the comments regarding logging, since a quick Google turned up
- http://bit.ly/17VTyD (using my own app's logging instead of via the server)
- http://bit.ly/gDlE7 (turning down logging/tracing in general)
I think the SpringSource dm Server folks have JNDI and the like on their roadmap. (I just use the OSGi registry in the same way that I used to use JNDI, so it hasn't affected me, but I can see why people would want JNDI to ease migration.) I'm looking forward to seeing what you did to get Eclipselink to work outside of dm Server.Mladen Girazovski replied on Wed, 2009/03/11 - 12:30pm
My quesion is a bit offtopic for sure, but i'll ask anyway :)
Have you considered/tried using Maven2 for building your OSGi apps?
How do you perform Integrationtests? Since the combination of SpringDM and Maven2 offers a lot of support and makes it easy to write an Integrationtest, i was wondering if there is there any similar support by the Eclipse Plugins.
Thomas Wiradikusuma replied on Wed, 2009/03/11 - 4:36pm
@jdigger when I started exploring OSGi, after some Hello World with Activators and basic usage of OSGi facilities, I quickly jumped to SpringSource dm Server (don't laugh, but any Spring maniac would ask "Hmm, I wonder if there's any Spring support for this technology I'm currently looking at.."). At the moment my mindset was "conventional" Java developer, some of it was the thought that I supposedly be able to configure my logging simply by putting configuration file AND I use SLF4J+Logback. Well guess what, SSDMS won't let me do that. It won't even let me use MDC (one big reason to use SLF4J)! So that's why I complained :)
And yes, you can toggle tracing, but as somebody in Spring Forum complained, you can't turn it off completely (the access log part if I'm not mistaken). Sorry I can't provide you with link :(
@mgira I'm a user of Maven 2. Apparently you can't make both (Maven--with plugins-- and SpringSource Tools) to work together nicely. The problem rots in dependency management "ownership" (they both manage dependencies and are incompatible each other) and MANIFEST.MF generation (they both generate MANIFEST.MF their own way and each other are incompatible too). So what approach did I take? I let SpringSource Tools "rules" in Eclipse (because it's very convenient to work with due to close IDE integration) while periodically verifying my pom.xml in IntelliJ to make sure it compiles from Maven :D As for the MANIFEST.MF, I assemble it by hand (using SpringSource Tools amazing Manifest Editor) and told Maven to use it and not replace it. Btw I could blog the detail if you're interested.Mongo Jerry replied on Thu, 2009/03/12 - 3:52am
I've done some experimentation with Spring dm Server and I see some real issues if you want OSGi runtime portability (I reserve the right to have misunderstood how things work ;-) ):
Syntatic Sugar
There's the new Import-Bundle and Import-Library directives. Yes, they are expanded at runtime to the good, old Import-Package we know and love, but it's a conversion step that would be needed at build-time if you want to support different OSGi runtimes. Yes, you can avoid them, but they are highly tempting to use if they are there.
Synthetic Application Bundle
Spring dm Server solves the problems experienced with libraries that use the context class loader by creating a fake bundle that imports everything the set of application bundles exports. This fake bundle's class loader is then used as the context class loader. This solves the typical problems of Hibernate not being able to see your domain classes (and any other library that uses a similar approach).
Now I think this solution is much more elegant that Eclipse's buddy policy approach (also non-portable) because Spring's solution "just works" whereas the buddy approach requires you to add non-standard entries to the manifests, but it's non-portable.
Jason Liechty replied on Tue, 2009/05/12 - 8:13am
in response to:
Thomas Wiradikusuma
Chuck Canning replied on Wed, 2009/05/27 - 2:31am
in response to:
Thomas Wiradikusuma
When will you be releasing the next part of the series?