Home > Java, Spring > Wicket using Spring Dynamic Modules on DM server

Wicket using Spring Dynamic Modules on DM server

This is the third project I am using Spring Dynamic Modules on Spring DM server. Though I like the idea behind OSGI, I have been struggling with it for a couple of days before I got it up and running.

Hopefully with this blog entry, I can prevent some of the problems that you might run into when you try it.

Project software

  • Maven 2
  • Spring framework 3
  • Spring DM
  • Wicket 1.4.7
  • Springsource DM server 2.0
  • Eclipse with Springsource tool

Project structure

Standard maven structure:
- parent
|– Iwin (par)
|– IwinWeb (war)
|– IwinServices (jar)
|– IwinDomain (jar)
|– IwinIntegration (jar)

Springsource tool tips:

  • Generate MANIFEST.MF file is supported using the a template.mf file. SST generates the manifest in the source folder /META-INF. This is not a problem for jars but for war application, you need the MANIFEST in the webapp/META-INF folder. When you setup the project using Maven eclipse:eclipse, the webapp is not part of the project source path. Because SST cannot find the manifest file, it will generate it always in the source folder. To solve this I had to add the webapp as a eclipse source folder. Then SST will scan and find an existing manifest file and generate the content in there.
  • After initial setup with maven, you need to do some extra work to get is working in SST. First of all you need to add SST nature in the project and add OSGI bundle nature. If you also (like me) have create a maven project with type ‘par’, you cannot at par nature to the project any more. I could only solve that by removing the bundle nature and add ‘com.springsource.server.ide.facet.core.parnature’ in the .project file.
  • Because of the manual updates on the eclipse project files, you cannot run eclipse:eclipse anymore since it will reset the settings of your project. (kinda weird because according to doc it shouldn’t happen unless you run eclipse:clear). For me this was a bit annoying since I always add dependencies in the pom and run eclipse:eclipse. To solve this, I have added the Maven Eclipse plugin which is running quite nicely. After updating the dependencies, you can manually select to regenerate the dependencies in eclipse (which basically just updates the classpath).
  • You can add bundles to the par project by selecting the manifest file. You will see an extra tab on the bottom where you can add dependencies. This is needed if you deploy the par using SST. Don’t forget to add the bundle nature to the jar projects.
  • Don’t forget to update the pom.xml file for the par because you would need it when you run a maven build command

Though there are somethings you need to get use to in SST, the tool in general works quite nice. There are miss matches when you use SST combined with Maven.
Dependencies for web applications in Maven are placed in the WEB-INF lib folder when you run the ‘package’ command. On your local environment the classpath is linking to the repository. This works well for WTP but if you need embedded libraries in your web application, you need to add Bundle-classpath to your manifest file. In my case I had to add wicket-spring-1.4.7.jar as embedded jar. In the classpath I added ‘/WEB-INF/lib/wicket-spring-1.4.7.jar’. When I packaged it and deployed it to DM server, it worked. When I start it from local dev, it didn’t work. Reason is that the libraries are not in WEB-INF/lib in the src/main/webapp. To solve this, I copied the embedded jars to src/main/webapp/WEB-INF/lib. Though this works, I don’t like this because now when I commit the source, the libs are included. If I don’t include, other developers will have to do it again before they can run from local SST. If any one knows a better solution, please leave a comment :)

Now probably you will be saying, embedding jars is a bad idea. You can add wicket as separate bundle. I thought the same thing. This thought has cost me another day of struggling. At first, I added wicket as bundle in DM server by copying it in the DM repository. Then I added in my manifest file, the import statement and my hello world wicket app was working. Great! Then I added Spring DM and used the <osgi:reference …. /> and <osgi:service …..> in the spring context files. The service was provided by my IwinServices project which is a osgi bundle. It was added to the par and it should work.

There were two main issues that I ran into:

  1. bundle context was not found
  2. interface is not visible for class loader

First issue eventually turned out to be that because I used ‘OsgiBundleXmlWebApplicationContext’ in the web.xml configuration as I followed nicely written tutorial http://cwiki.apache.org/CAMEL/tutorial-osgi-camel-part2c.html to setup my application. But it turned out that DM server is setting the application context in different attribute within the servlet context. To solve this, I have switched over to use the ‘com.springsource.server.web.dm.ServerOsgiBundleXmlWebApplicationContext’ as contextClass. This solved the context issue. One additional tip, if you have added ‘org.springframework.osgi.web’ artifact in your POM, you should remove it. If you keep it in the pom and package the par, the application doesn’t start up leaving you with some useless messages. I needed to add this reference because it is added to your manifest file if you refer to the OsgiBundleXmlWebApplicationContext in your web.xml.

After setting this all up, the application starts up. I was very happy for a moment just be see a wicket stacktrace page which told me that the osgi service interface was not visible in the class loader. I am using SpringBean annotation to inject the osgi:service in the Page compenent. To keep this story short, after several hours, it turns out that the Proxy used in Wicket to inject the beans in the page component is loading the class from his class loader. Since I deployed the Wicket bundle as a separate bundle in DM server, it had its own class loader. That’s why I cannot find the class within the Par package since DM server is shielding the par in its own context. To solve this, I have used the ‘discouraged osgi approach’ by embedding the jars in the web application. Since wicket is then loaded within the web applications classloader, it can successfully inject the service bean in the page component.

Though there were still many small things that went wrong, these were the main things that I ran into. I am not a very structured writer unless I spent a lot of time in writing so I will keep this post as it is now. Hopefully someone might find it useful.

Leave a comment if you have any information regarding this topic. I need the information to prevent myself from running into these issues while the deadline of the project is upcoming :)

If I have time I will strip a small sample app and add it as attachment to this post. If I haven’t done it because of lack of time (or simply to lazy :) ) and you would like to have it, you can leave a comment.

Categories: Java, Spring

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.