Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

Running Spring MVC Web Applications in OSGi

For the past couple of weeks, I've been developing a web application that deploys into an OSGi container (Equinox) and uses Spring DM's Spring MVC support. The first thing I discovered was that Spring MVC's annotations weren't supported in the M1 release. This was apparently caused by a bug in Spring 2.5.3 and not Spring DM. Since Spring DM 1.1.0 M2 was released with Spring 2.5.4 today, I believe this is fixed now.

The story below is about my experience getting a Spring MVC application up and running in Equinox 3.2.2, Jetty 6.1.9 and Spring DM 1.1.0 M2 SNAPSHOT (from last week). If you want to read more about why Spring MVC + OSGi is cool, see Costin Leau's Web Applications and OSGi article.

To get a simple "Hello World" Spring MVC application working in OSGi is pretty easy. The hard part is setting up a container with all the Spring and Jetty bundles installed and started. I imagine SSAP might solve this. Luckily for me, this was done by another member of my team.

After you've done this, it's simply a matter of creating a MANIFEST.MF for your WAR that contains the proper information for OSGi to recognize. Below is the one that I used when I first tried to get my application working.

Manifest-Version: 1
Bundle-ManifestVersion: 2
Spring-DM-Version: 1.1.0-m2-SNAPSHOT
Spring-Version: 2.5.2
Bundle-Name: Simple OSGi War
Bundle-SymbolicName: myapp
Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar,
Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,

Ideally, you could generate this MANIFEST.MF using the maven-bundle-plugin. However, it doesn't support WARs in its 1.4.0 release.

You can see this is an application that uses Spring MVC, FreeMarker, SiteMesh and the URLRewriteFilter. You should be able to download it, unzip it, run "mvn package" and install it into Equinox using "install file://<path to war>".

That's all fine and dandy, but doesn't give you any benefits of OSGi. This setup works great until you try to import OSGi services using a context file with an <osgi:reference> element. After adding such a reference, it's likely you'll get the following error:

SEVERE: Context initialization failed
Configuration problem: Unable to locate Spring NamespaceHandler for
XML schema namespace []

To fix this, add the following to your web.xml (if you're using ContextLoaderListener, as an <init-parameter> on DispatcherServlet if you're not):


After doing this, you might get the following error on startup:

SEVERE: Context initialization failed
org.springframework.context.ApplicationContextException: Custom
context class []
is not of type [org.springframework.web.context.ConfigurableWebApplicationContext] 

To fix this, I change from referencing the Spring JARs in WEB-INF/lib to importing the packages for Spring (which were already installed in my Equinox container).

Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar,

After rebuilding my WAR and reloading the bundle in Equinox, I was confronted with the following error message:

SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'freemarkerConfig' defined in ServletContext
resource [/WEB-INF/myapp-servlet.xml]: Instantiation of bean failed;
nested exception is java.lang.NoClassDefFoundError:

As far as I can tell, this is because the version of Spring MVC installed in Equinox cannot resolve the FreeMarker JAR in my WEB-INF/lib directory.

To prove I wasn't going insane, I commented out my "freemarkerConfig" and "viewResolver" beans in myapp-servlet.xml and changed to a regular ol' InternalResourceViewResolver:

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"/>
    <property name="suffix" value=".jsp"/>

This worked and I was able to successfully see "Hello World" from a JSP in my browser. FreeMarker/SiteMesh worked too, but FreeMarker didn't work as a View for Spring MVC.

To attempt to solve this, I create a bundle for FreeMarker using "java -jar bnd-0.0.249.jar wrap freemarker-2.3.12.jar" and installed it in Equinox. I then change my MANIFEST.MF to use FreeMarker imports instead of referencing the JAR in WEB-INF/lib.


Unfortunately, this still doesn't work and I still haven't been able to get FreeMarker to work with Spring MVC in OSGi. The crazy thing is I actually solved this at one point a week ago. Shortly after, I rebuilt Equinox from scratch and I'm been banging my head against the wall over this issue ever since. Last week, I entered an issue in Spring's JIRA, but thought I'd fixed it a few hours later.

I've uploaded the final project that's not working to the following URL:

If you'd like to see this project work with Spring MVC + JSP, simply modify myapp-servlet.xml to remove the FreeMarker references and use the InternalResourceViewResolver instead.

I hope Spring DM + Spring MVC supports more than just JSP as a view technology. I hope I can't get FreeMarker working because of some oversight on my part. If you have a Spring DM + Spring MVC application working with Velocity or FreeMarker, I'd love to hear about it.

Posted in Java at Apr 30 2008, 12:42:34 AM MDT 14 Comments


Great to see you working on OSGi stuff.

With regard to your Freemarker problem, sadly bringing a third party library into OSGi is rarely as simple as just running "bnd wrap" over it. The issue is the dependencies... bnd does bytecode analysis to discover all of the static dependencies inside Freemarker and it adds those to the manifest. So if it discovers a dependency on (say) org.apache.commons.lang, then the FM bundle won't resolve unless you have commons-lang bundleized and installed as well.

The real the problem is that many libraries include dependencies on crazy stuff. For example lots have a dependency on JUnit because they have not properly separated their tests from their runtime parts. However bnd has no way to automatically discriminate between "true" runtime dependencies and the ones that are just sitting around in the JAR. So you have to help it along. The initial step is to run bnd and then look at the imports it has included, then you determine which of those imports are not really needed, and you write a properties file to tell bnd that those imports should be made optional.

I am in the process of documenting these issues in my book, but I haven't yet released the chapter on working with 3rd party libraries. But you may still find something useful in the chapters that I have released:

Neil PS I tried to download Freemarker myself and check if this was in fact the problem, but unfortunately SourceForge seems to be down at present.

Posted by Neil Bartlett on April 30, 2008 at 11:49 AM MDT #

I've tried to do the same thing around 6 months ago and finally gave up, things were not as ready as they should then and seem that neither they are now. The idea is cool though, let's see if in some months time...

Posted by Carlos Sanchez on April 30, 2008 at 04:03 PM MDT #

Hi Matt,

This was a great challenge application for the SpringSource Application Platform - especially in the light of the comments from Neil Bartlett and Carlos Sanchez above.

I'm pleased to say that getting this application to work on the SpringSource Application Platform was trivial, and a testament to the points I made in my blog last night Completing the picture, Spring, OSGi, and the SpringSource Application Platform.

Here are the steps I followed:
  1. Download the zip file from your blog
  2. Run 'mvn'
  3. cp target/mpapp.war to the pickup directory of the Platform
  4. startup the platform: bin/ I got the following output to the console:
    com.springsource.platform.deployer.core.DeploymentException: Unable to satisfy constraints of 'myapp' version '0.0.0': Cannot resolve: myapp
      Unsatisfied leaf constraints:
        Bundle: myapp_0.0.0 - Import-Package:; version="0.0.0"
          Did you mean: ''?
        Bundle: myapp_0.0.0 - Import-Package: freemarker.ext.servlet; version="0.0.0"
          Did you mean: 'javax.servlet'?
        Bundle: myapp_0.0.0 - Import-Package: freemarker.core; version="0.0.0"
          Did you mean: 'org.hamcrest.core'?
        Bundle: myapp_0.0.0 - Import-Package: freemarker.template; version="0.0.0"
          Did you mean: 'org.antlr.tool'?
        Bundle: myapp_0.0.0 - Import-Package: freemarker.cache; version="0.0.0"
          Did you mean: 'org.apache'?
    These are expected messages since I don't have freemarker or the osgi.web.context support bundles installed in the platform.
  5. Go to Type "freemarker" into the search box, find the one matching entry and click on the link to download it. Copy the downloaded bundle in repository/bundles/usr
  6. Simplify the manifest to point to the new bundles and libraries on the platform. Your original manifest looked like this:
    Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
    and I took it down to:
    Import-Package: org.apache.commons.logging
    Import-Library: org.springframework.spring;version="[2.5.4,3.0.0)"
    Import-Bundle: com.springsource.freemarker;version="2.3.12"
    When we know you are deploying a web application, the commonly required imports are automatically added at deployment time. Import-Library and Import-Bundle allow you to conveniently refer to libraries and bundles in a single statement. I also deleted your "Bundle-Classpath" entry as the application platform will automatically detect libraries in WEB-INF/lib and add them to the bundle classpath.
  7. I edited web.xml and commented out the <context-param> declaration since there is no need to use a custom application context type here.
  8. Run 'mvn' again, and copy the myapp.war into the pickup directory.
  9. The Application Platform automatically redeployed the application
  10. Point a browser at http://localhost:8080/myapp/ .... SUCCESS!

I think this is a nice demonstration of the value proposition of the platform in smoothing the path of making enterprise libraries work under OSGi.

I'm happy to send you the updated code if you would like it, but it should be very easy to recreate these simplifications to your application :)

Regards, Adrian.

Posted by Adrian Colyer on May 02, 2008 at 02:22 PM MDT #

Thanks Adrian - I've confirmed these instructions do work. However, I found I need contextClass=OsgiBundleXmlWebApplicationContext in order to load context files with <osgi:reference> in them. Is this not needed with running in S2AP?

Posted by Matt Raible on May 02, 2008 at 05:04 PM MDT #

If you want to use <osgi:reference> then you will need that context class, yes. We distinguish between "shared library" war files that simply use Import Package / Bundle / Library in their manifest, and "shared service" war files that also can inject references to OSGi services. These two stages form a migration path towards a true par file. Your initial application didn't use any "shared services" so the special context wasn't needed. Good luck with the application - do keep us posted on any issues you run into so that we can continue to make things work better for you.

Thanks, Adrian.

Posted by Adrian Colyer on May 03, 2008 at 06:33 AM MDT #


Please bear in mind that using the Import-Library and Import-Bundle headers as recommended by Adrian will tie you to S2AP, as these are non-standard extensions introduced by SpringSource.

My recommendation is to stick with the full Import-Package list. Yes it is long, but at least the dependencies of your bundle are defined <strong>in your bundle</strong> rather than in some external artifact which might change.

I have detailed some of my issues with SpringSource's extensions in my blog post here:


Posted by Neil Bartlett on May 08, 2008 at 10:09 AM MDT #

Matt, As Adrian describes here ( we will be providing a tool to convert Import-Bundle and Import-Library into the corresponding Import-Package statements to allow for the creation of 100% OSGi standard bundles. This tool removes any danger of lock-in. As Neil says, listing all the Import-Packages yourself is lengthy, but he neglects to mention that it is error prone as well. Consider the scenario where, because of dynamic subclass generation, your web bundles have to import Hibernate packages - all of which have to be identified by trial and error :( I think the fact that Adrian was able to get your app up and running in a matter of minutes is testament to the ease-of-use of the Platform. Cheers, Rob

Posted by Rob Harrop on May 08, 2008 at 05:49 PM MDT #

Adrian and/or Rob - you mention there might be a tool that allows expanding Import-Bundle and Import-Library into OSGi-compliant MANIFESTs. Does this tool exist yet? I'd like to try to get working in an Equinox environment and I suspect that it's just a matter of having the proper MANIFEST.MF. Thanks!

Posted by Matt Raible on May 14, 2008 at 04:38 PM MDT #

Hi Matt,

The tool that Adrian and Rob mentioned does not yet exist; however, I'll share a perhaps little know tip with you...

If you create a bundle using Import-Bundle or Import-Library, you can view the Platform's trace (i.e., PLATFORM_HOME/serviceability/trace/trace.log) and see exactly how those manifest headers get translated into standard OSGi Import-Package statements. Just search for "transformed from:", and just after that you'll find a "to:" with the transformed manifest immediately following.

Now to answer the question you posted on the S2AP beta forum regarding how to get your sample web application to run on the Platform without any SpringSource specific manifest headers: As Adrian already mentioned, it's rather trivial to convert your web-app to run using Import-Bundle and Import-Library. So, to get it to run on the SpringSource Application Platform using only Import-Package, simply follow Adrian's above steps, but use the following manifest instead:

Manifest-Version: 1
Bundle-ManifestVersion: 2
Bundle-Name: Simple OSGi War
Bundle-SymbolicName: myapp
Import-Package: javax.servlet,

Delete the following, as they are not necessary for deploying WARs or Web Modules on the S2AP:

Spring-DM-Version: 1.1.0-m2-SNAPSHOT
Spring-Version: 2.5.2
Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar

And in web.xml, use PlatformOsgiBundleXmlWebApplicationContext instead of OsgiBundleXmlWebApplicationContext as the 'contextClass' context-param for Spring MVC's ContextLoaderListener. For example:


I hope this gets you up and running with your Freemarker web-app on the S2AP!

Best regards,


Posted by Sam Brannen on May 17, 2008 at 04:03 AM MDT #

Hi, I am trying to test and install:

but when I do:

cd myapp
mvn jetty:run

I get:

2010-10-10 22:35:15.526::WARN:  Nested in org.springframework.context.ApplicationContextException: Failed to load custom context class []; nested exception is java.lang.ClassNotFoundException:

and when I go to http://localhost:8080/myapp I get:



Powered by jetty://

Any ideas?

Thank you

Posted by Misha Koshelev on October 11, 2010 at 03:36 AM MDT #

[Trackback] Thanks. There seem to be some fairly straightforward ways to migrate, e.g.: <a href=""></a> <a href=""></a> <br/><br/> but none of...

Posted by JIRA: OpenMRS Trunk on October 11, 2010 at 10:30 PM MDT #


I have installed successfully on Virgo Web Server:

I enable the Equinox telnet console by uncommenting the following line:

misha@misha-d630:~/opt/virgo-web-server-2.1.0.M06-incubation$ cat config/ | grep console
# osgi console support

then drop the following bundle into pickup:

I go to the console, install bundle, it is active:

telnet localhost 2401
Trying ::1...
Connected to localhost.
Escape character is '^]'.

osgi> install file:///tmp/myapp.war
Bundle id is 64

osgi> start myapp

osgi> ss myapp

Framework is launched.

id	State       Bundle
64	ACTIVE      myapp_0.0.0

Yet get a 404 from the suggested URL:

 curl http://localhost:8080/myapp/

Any ideas?

Thank you!

Posted by Misha Koshelev on October 13, 2010 at 01:18 AM MDT #

The only thing I can think of is your app is at http://localhost:8080/myapp_0.0.0 or it's available on a different port.

Posted by Matt Raible on October 13, 2010 at 04:07 AM MDT #

I download your zip and packaged and installed the war. But I am getting this error.

install file:/Users/kaleeswaran/Downloads/myapp/target/myapp.war 
Bundle ID: 38
g! start 38
org.osgi.framework.BundleException: Unresolved constraint in bundle myapp [38]: Unable to resolve 38.0: missing requirement [38.0] osgi.wiring.package; (osgi.wiring.package=org.apache.commons.logging)

Where I am wrong, Thanks.

Posted by Muthu on August 31, 2013 at 06:33 PM MDT #

Post a Comment:
  • HTML Syntax: Allowed