» tagged pages
» logout

(Feed found, click Add Page to syndicate.) Error finding feed, please try again » Find feed title

A Blog Page allows you to add entries, for news or other time sensitive postings

(Login required to save to your tagged pages.)
(or Cancel)

Make further edits, (or Cancel)

(Login required to save to your tagged pages.)
(or Cancel)

(Editing anonymously: to be credited for your changes, login or register a new account)

Change Page Permissions? Changing these permissions will adjust who can modify this page.

Anonymous (change)
(change)
(or Cancel)
Upload an image from your computer:
or Copy an image from a URL:
or Erase the current icon:
Icon Preview:

or Cancel

Erase platform? The contents of platform page and all pages directly attached to platform will be erased.

or Cancel

(Editing anonymously: to be credited for your changes, login or register a new account)

other page actions:
platform

platform

Tags Applied to platform

No one has tagged this page.

platform Wiki Pages

What is platform? Edit this page and describe it here.

sorted by: recent | see : popular
Content Tagged platform

Springframework.org

Welcome to the home of the Spring Framework, the leading full-stack Java/JEE application framework.

Spring: del.icio.us/tag/SpringFramework

Pion - The Open Source Complex Event Processing (CEP) Platform

Pion Platform is open source software for building complex event processing (CEP) systems. Pion uses the most modern C++ libraries and techniques to enable best in class enterprise scaleability. It can distribute processing tasks across any number of CPU

open-source: del.icio.us tag/open-source

Working with SpringSource Application Platform's provisioning repository

One of the main advantages of the SpringSource Application Platform is its ability to provision dependencies on an as-needed basis. The benefits of this are two-fold: it ensures that the Platform's memory footprint is as small as possible and it allows applications to be deployed without encapsulating all of their dependencies in a monolithic deployment unit, e.g. a WAR file. To take advantage of these capabilities you will require an understanding of the Platform's provisioning repository and this blog intends to provide just that.

Where is the provisioning repository and how does it work?

By default the Platform's provisioning repository can be found in the repository directory at the root of the installation:

Directory structure of the provisioning repository
As you can see, there are three main directories: bundles, installed and libraries. installed is for the Platform's internal use so we'll focus on the bundles and libraries directories here. Each contains a number of subdirectories to separate the different types of dependencies:

  • ext contains external dependencies that are provided with the Platform but are not part of the Platform itself.
  • subsystems contains all of the subsystems that comprise the Platform.
  • usr is initially empty and is intended to contain user-added dependencies, i.e. anything upon which your applications depend that is not already provided by the Platform.

The Platform searches the repository directory structure for both bundles and libraries during its initial startup. I'll talk about how this searching can be configured later on in this entry. As bundles and libraries are found within the repository, details of their symbolic names, exported packages etc. are added to an in-memory index of the repository. Upon completing the scan the in-memory indexes are cached to disk. Minimising the Platform's startup time was a priority for us during development. This caching allows the Platform to save some time during startup: it can skip the scan unless it detects that the contents of the repository have changed.

Runtime provisioning

In a plain OSGi environment a bundle's dependencies can only be satisfied by other bundles which have already been installed in the environment. For example, installing and starting a bundle that imports the org.apache.commons.dbcp package will fail if no bundle which exports that package has already been installed. This can be a real pain for users as they have to manually install all of a bundle's dependencies. Thankfully, the SpringSource Application Platform improves upon this significantly by dynamically installing dependencies on an as-needed basis.

When a deployed application is started by the Platform its bundles are installed into Equinox. The Platform then asks Equinox for a list of all of the bundles' unsatisfied dependencies and tries to satisfy them. Let's analyse this process by walking through a simple example scenario:

  1. A bundle which imports org.apache.commons.dbcp is installed by the Platform into Equinox.
  2. The Platform asks Equinox for the bundle's unsatisfied dependencies and is told that the import of org.apache.commons.dbcp cannot be satisfied.
  3. The Platform searches its index of the provisioning repository for a bundle which exports org.apache.commons.dbcp
  4. The Platform installs the bundle which exports org.apache.commons.dbcp into Equinox
  5. Having satisfied the original bundle's dependencies the Platform successfully starts the original bundle.

We hope that this will make our users' lives much easier: as long as your application's dependencies are available to the Platform you can simply deploy your application and go! There's no need to get your hands dirty with the time consuming process of manually installing all of your application's dependencies. One great thing about this process is that dependencies are only installed when they're needed. You can add as many bundles as you wish to the provisioning repository with almost no impact upon the Platform's memory footprint.

If the Platform's unable to satisfy a dependency from its repository a log message is generated that details the dependency that could not be satisfied. Armed with this information you can use the SpringSource Enterprise Bundle Repository to get hold of what you need. We'd like the repository to provide as complete a set of bundles as possible: if there's a dependency that you need and it's not available then please let us know.

Adding items to the provisioning repository

So you've downloaded a dependency or two and now you want to add them to the Platform. All you need to do is copy them to the appropriate directory in the repository. For example, a new bundle would typically be added to the repository/bundles/usr directory and a new library descriptor would typically be added to the repository/libraries/usr directory.

As described above, the Platform uses an in-memory index of its provisioning repository that's populated during startup. In addition to this, the Platform will also check that its view of the repository is up-to-date whenever an application is deployed. When you want to install an application with new dependencies simply copy the dependencies to the appropriate locations in the repository and then deploy your application. During its deployment processing, the Platform will notice that the repository has been updated and will refresh its view of it. This means that you don't need to spend time restarting the Platform every time you want to install an application with new dependencies.

Sharing the provisioning repository between installations

The locations where the Platform searches for items in the provisioning repository can be easily configured to suit your needs. For example, it's possible for multiple Platform instances to share some or all of a provisioning repository so you don't need to waste effort maintaining duplicate sets of bundles between Platform installations.

The locations which are scanned by the Platform when creating its provisioning repository can be configured in the config/platform.config file. The default configuration, which is used in the absence of any specific configuration, is:

"provisioning" : {
    "searchPaths": [
        "repository/bundles/subsystems/{name}/{bundle}.jar",
        "repository/bundles/ext/{bundle}",
        "repository/bundles/usr/{bundle}",
        "repository/libraries/ext/{library}",
        "repository/libraries/usr/{library}"
    ]
}

Any relative paths are interpreted by the Platform as being relative to its installation root, with absolute paths being supported too. The entries in the search paths within curly braces are simply wildcards, e.g. the subsystems search path repository/bundles/subsystems/{name}/{bundle}.jar will find any file with a name ending in .jar in any of the subsystems directory's immediate sub-directories.

Hopefully you can see that it's a trivial change to share some or all of a provisioning repository between Platforms. For example, to make the Platform search a directory named shared-bundles in the root of the filesystem as well as in its own subsystems and ext directories, all you need to do is add the following snippet of JSON (JavaScript Object Notation) to the platform.config file:

"provisioning" : {
    "searchPaths": [
        "repository/bundles/subsystems/{name}/{bundle}.jar",
        "repository/bundles/ext/{bundle}",
        "/shared-bundles/{bundle}",
        "repository/libraries/ext/{library}",
        "repository/libraries/usr/{library}"
    ]
}

By configuring two or more Platform installations with this configuration they can be made to share the bundles in /shared-bundles. This can easily be taken one step further by configuring all of the search paths to point to shared locations so you wouldn't need to manage a per-Platform provisioning repository at all.

What's next?

We're planning to make it simpler to run multiple instances of the Platform from the same set of binaries by providing some tooling or scripts. These will do most of the work for you, providing a sensible default configuration that you can then tweak to meet your specific needs.

We also intend to combine the power of the Platform's on-demand provisioning and the SpringSource Enterprise Bundle Repository by allowing the Platform to be configured to optionally search a remote repository when it's trying to satisfy a dependency. If a dependency is found in a remote repository the Platform will handle its download and installation automatically. Hopefully this'll make developers' lives a lot easier, especially in the initial stages of an application's development as new dependencies are being added on a regular basis.

We'd love to hear your suggestions as we work on the above-described enhancements and the Platform in general: please don't hesitate to comment on this blog entry, raise a JIRA, or post on our forums.

Spring: Interface21 Team Blog

SpringSource Application Platform Deployment Options

Since we released the SpringSource Application Platform last Wednesday, numerous developers have downloaded the 1.0.0 beta and started taking the Platform for a test drive. As a result, people have begun asking, "How can I deploy my apps on the Platform, and what kind of deployment and packaging options do I have?" Moreover, developers are eagerly requesting to see working samples. In response, the S2AP team will be releasing several sample applications over the coming weeks demonstrating these features and more, but before you get your hands on these samples, I'd like to give you a high-level overview of the deployment and packaging options available in the Platform. After reading this post you'll be ready to hit the ground running with the samples as well as with your own applications.

Overview

As Rob mentioned in his post last week, Introducing the SpringSource Application Platform, the Platform supports applications packaged in the following forms:

  1. Raw OSGi Bundles
  2. Java EE WAR
  3. Web Modules
  4. Platform Archive (PAR)

When you deploy an application to the Platform, each deployment artifact (e.g., a single bundle, WAR, or PAR) passes through a deployment pipeline. This deployment pipeline supports the notion of personality-specific deployers which are responsible for processing an application with a certain personality (i.e., application type). The 1.0.0 release of the Platform natively supports personality-specific deployers analogous to each of the aforementioned packaging options. Furthermore, the deployment pipeline can be extended with additional personality deployers, and future releases of the Platform will provide support for personalities such as Batch, Web Services, etc.

Let's take a closer look now at each of the supported deployment and packaging options to explore which one is best suited for your applications.

Raw OSGi Bundles

At its core, the SpringSource Application Platform is an OSGi container. Thus any OSGi-compliant bundle can be deployed directly on the Platform unmodified. You'll typically deploy an application as a single bundle or a set of stand-alone bundles if you'd like to publish or consume services globally within the container via the OSGi Service Registry. Please note, however, that due to the scoping nature of the PAR format, stand-alone bundles will not be able to consume services across application boundaries. In other words, a stand-alone bundle can not reference the services of modules deployed within a PAR.

WAR Deployment Options

For Web Application Archives (WAR), the SpringSource Application Platform provides support for the following three formats.

  1. Standard Java EE WAR
  2. Shared Libraries WAR
  3. Shared Services WAR

Each of these formats plays a distinct role in the incremental migration path from a standard Java EE WAR to an OSGi-ified web application.

Standard WAR

As Rob has already pointed out, "Standard WAR files are supported directly in the Platform. At deployment time, the WAR file is transformed into an OSGi bundle and installed into Tomcat. All the standard WAR contracts are honoured, and your existing WAR files should just drop in and deploy without change." Support for standard, unmodified WAR files allows you to try out the SpringSource Application Platform on your existing web applications and then gradually migrate toward the Shared Libraries WAR, Shared Services WAR, and Web Module formats.

Shared Libraries WAR

If you have experience with developing and packaging web applications using the standard WAR format, you're certainly familiar with the pains of library bloat. So, unless you're installing shared libraries in a common library folder for your Servlet container, you have to pack all JARs required by your web application in /WEB-INF/lib. Prior to the release of the Platform, such library bloat has essentially been the norm for web applications, but now there is a better solution! The Shared Libraries WAR format reduces your application's deployment footprint and eradicates library bloat by allowing you to declare dependencies on libraries via standard OSGi manifest headers such as Import-Package and Require-Bundle. The Platform provides additional support for simplifying dependency management via the Import-Library and Import-Bundle manifest headers which are essentially macros that get expanded into OSGi-compliant Import-Package statements.

For detailed information on what kind of libraries you already have at your disposal, check out the SpringSource Enterprise Bundle Repository. In addition, Andy Wilkinson will be posting a blog later this week explaining how to make the most of the Bundle Repository within your applications and the SpringSource Application Platform. So stay tuned.

Shared Services WAR

Once you've begun taking advantage of declarative dependency management with a Shared Libraries WAR, you'll likely find yourself wanting to take the next step toward reaping further benefits of an OSGi container: sharing services between your OSGi-compliant bundles and your web applications. By building on the power and simplicity of Spring-DM, the Shared Services WAR format puts the OSGi Service Registry at your fingertips. As a best practice you'll typically publish services from your domain, service, and infrastructure bundles via <osgi:service … /> and then consume them in your web application's ApplicationContext via <osgi:reference … />. Doing so promotes programming to interfaces and allows you to completely decouple your web-specific deployment artifacts from your domain model, service layer, etc., and that's certainly a step in the right direction. Of the three supported WAR deployment formats, the Shared Services WAR is by far the most attractive in terms of modularity and reduced overall footprint of your web applications.

Web Modules

Above and beyond WAR-based deployment formats, the SpringSource Application Platform introduces a deployment and packaging option for OSGi-compliant web applications, the Web Module format. Web modules have a structure similar to a Shared Services WAR and can therefore take full advantage of all three WAR deployment formats. In addition, web modules benefit from reduced configuration for Spring MVC based applications via new OSGi manifest headers such as Web-DispatcherServletUrlPatterns and Web-FilterMappings. For further details on these and other Web-* manifest headers, please consult the Platform's Programmer Guide. Upcoming releases of the Platform will also support web.xml fragments as well as the aforementioned manifest headers.

If you're building a Spring MVC based web application as a web module, you won't need to worry about configuring a root WebApplicationContext or an ApplicationContext for your DispatcherServlet. Based on metadata in your web module's /META-INF/MANIFEST.MF, the Platform will auto-generate an appropriately configured web.xml for you on-the-fly, and your application will use the ApplicationContext created for your web module by Spring-DM. Future releases will add additional support to simplify configuration of Spring Web Flow based web applications as well.

Migration path from WAR to Web Module

The following diagram graphically depicts the migration path from a Standard WAR to a Web Module. As you can see, the libs move from within the deployment artifact to the Bundle Repository. Similarly, the services move from within the WAR to external bundles and are accessed via the OSGi Service Registry. In addition, the overall footprint of the deployment artifact decreases as you move towards a Web Module.

Migration path from WAR to Web Module

Platform Archives

The final piece of the puzzle is the PAR (Platform Archive) deployment format. A PAR is a standard JAR which contains all of the modules of your application (e.g., service, domain, and infrastructure bundles as well as a WAR or web module for web applications) in a single deployment unit. This allows you to deploy, refresh, and undeploy your entire application as a single entity. For those of you familiar with Java EE, a PAR can be considered a replacement for an EAR (Enterprise Archive) within the context of an OSGi container. As an added bonus, modules within a PAR can be refreshed independently and on-the-fly, for example via the SpringSource Application Platform Tool Suite (register for the beta program and check out the Eclipse tooling support).

Furthermore, PARs scope the modules of your application within the Platform. Scoping provides both a physical and logical application boundary, shielding the internals of your application from any other applications deployed within the Platform. This means your application doesn't have to worry about clashing with other running applications (e.g., in the OSGi Service Registry). You get support for load-time weaving, classpath scanning, context class loading, etc., and the Platform does the heavy lifting for you to make all this work seamlessly in an OSGi environment. If you want to take full advantage of all that the SpringSource Application Platform and OSGi have to offer, packaging and deploying your applications as a PAR is definitely the recommend choice.

Where to go from here

If you haven't already done so, I encourage you to join the beta program and take the SpringSource Application Platform for a test drive yourself.

You'll find up-to-date documentation in the user guide and programmer guide, and if you happen to run into any issues deploying your applications or have recommendations on how we can improve the Platform, please don't hesitate to create a JIRA issue.

And last but not least, be sure to check out upcoming posts on the SpringSource Team Blog to keep abreast of news regarding the Platform and to see working examples including an OSGi-ified Spring PetClinic sample application which has been modularized and packaged as a PAR.

Spring: Interface21 Team Blog

Running Spring Applications on OSGi with the SpringSource Application Platform

A lot of people have been asking what exactly the SpringSource Application Platform does for Spring applications to make them run well under OSGi, over and above what you can get out of the box with OSGi and Spring Dynamic Modules. Adrian's post yesterday highlighted some of the general issues, now lets look at a few of the details.

The three most challenging aspects of running Spring applications on OSGi are:

  • Load-time weaving
  • Classpath scanning
  • Thread context classloader management

The remaining, but less interesting, issues include: JSP support, TLD scanning, annotation matching and resource lookups. Overall, there was a decent-sized set of issues that needed to be solved to make applications deploy smoothly.

Load-time weaving

Load-time weaving was one of the most problematic features to support in a robust manner. At the basic level, it requires hooking into the Equinox ClassLoader so that standard ClassFileTransformers can be attached and used during the defineClass calls. On top of this, many uses of LTW require access to a throwaway ClassLoader that can be used to inspect types to decide what needs to happen during the weave, without affecting the real ClassLoader.

This base level of support was actually reasonably simple to achieve. The difficulty comes in when weaving is driven by classes in one bundle, but classes in another bundle need to be woven. This is pretty common in enterprise applications where one bundle contains domain entities and another contains types that use a JPA EntityManager. The Platform takes care of this complexity by ensuring that all bundles in an application can be woven with the appropriate ClassFileTransformers.

When you start propagating weaving across to other bundles, you really need to know when to stop. If you simply apply weaving to all bundles, then applications will interfere with each other. The Platform prevents this from happening by explicitly scoping weaving so that it applies only to modules in the application.

Another issue with LTW is that it complicates refresh. When a bundle is refreshed, OSGi will refresh all the bundles that depend on it. This means that, in the example I gave above, refreshing the domain bundle will cause the EntityManager bundle to be refreshed. However, refreshing the EntityManager does not refresh the domain bundle, meaning that weaving is possibly out of sync. The Platform handles this by propagating refresh to other bundles that are affected by weaving.

Classpath scanning

With classpath scanning, the main issue is that Equinox doesn't expose standard jar: and file: resources. The Platform puts an adapter in the middle so that libraries see the resource protocols that they expect. This has a nice side-effect of making a lot of third-party libraries work - it's not just a fix for classpath scanning.

Thread context classloader management

Many third-party libraries use the thread context ClassLoader to access application types and resources. Each bundle in OSGi has it's own ClassLoader, so therefore, only one bundle can be exposed as the thread context ClassLoader at any time. This means that if a third-party library needs to see types that are distributed across multiple bundles, it isn't going to work as expected.

The Platform fixes this by creating a ClassLoader that imports all the exported packages of every module in your application. This ClassLoader is then exposed as the thread context ClassLoader, enabling third-party libraries to see all the exported types in your application.

This is just a small cross-section of the issues that are addressed by the Platform but hopefully it gives you an idea of what the Platform means for Spring Framework users.

Spring: Interface21 Team Blog

Completing the picture: Spring, OSGi, and the SpringSource Application Platform

** Updated May 2nd with case study :- see the bottom of this post for details **
I'm sure most of you reading this blog will have seen the announcement of the SpringSource Application Platform yesterday. If not, be sure to check out Rob's blog post which describes some of the motivation, programming model, and roadmap.

A couple of common questions are being asked that I'd like to address straight away in this post. After that I'll describe two other exciting announcements that complement the SpringSource Application Platform itself but that didn't grab the headlines yesterday: the SpringSource Enterprise Bundle Repository and the Application Platform tools for Eclipse. Together these complete the story around OSGi-based enterprise application development with Spring.

The question I've heard several times over the last 24 hours is: what's wrong with OSGi - why can't we just use a vanilla OSGi Service Platform (such as Equinox, Felix, or Knopflerfish) instead of the SpringSource Application Platform?

There is absolutely nothing wrong with OSGi.

OSGi is a great foundation and service platform - that's why we and many others have chosen to build upon it. It's proven in a wide range of industries and applications, and underpins applications such as Eclipse and IBM's WebSphere as well as the middleware stacks of several other vendors.

Programming straight to the the OSGi specification APIs lacks some of the qualities we have come to expect for enterprise applications - such as the ability to use dependency injection and create applications that are easily unit and integration testable outside of the container. Programming straight to the OSGi specification APIs also forces you to deal at a relatively low level with the dynamics of the OSGi platform - what do you do when modules and services you depend on are stopped, started, installed, and updated at runtime? But there's no fundamental obstacle here that we weren't able to overcome with the Spring Dynamic Modules project. Applications built using Spring Dynamic Modules can run on any standard OSGi Service Platform, and we test all our builds against Equinox, Felix, and Knopflerfish. We are committed to ensuring that Spring Dynamic Modules and the Spring based programming model remain runtime neutral. That position will not change with the introduction of the SpringSource Application Platform.

There is also absolutely nothing wrong with existing enterprise libraries.

Well, ok. There are some cases that leave a little to be desired, but by and large we know how to make them work for enterprise application development needs.

So what's the problem then?

If OSGi works so well, and existing enterprise libraries are meeting our needs, then where's the problem? The difficulty comes when you try to combine an OSGi Service Platform with a set of existing enterprise libraries that weren't written with OSGi in mind. That's not the fault of OSGi, it's got a great model that provides for excellent modularity, versioning, and operational control. It's not the fault of the enterprise libraries either - they weren't written to run under OSGi. But the very things that make OSGi so attractive break assumptions that the developers of those enterprise libraries made. The modularity model of OSGi for example stops you seeing the private parts of other people's bundles. That's exactly what you want, until you realise that your enterprise library can no longer see your application types. Lots of things can break: from commons logging to jsps, tag libraries to data sources, load-time weaving to component scanning, resource loading to orm mapping. The list goes on… (Yes, you can get many of these things to work when you package your application code and all of the libraries it needs into a single bundle, but that's very much missing the point!).

This is why you see lots of people building on top of OSGi, but very few cases of passing OSGi benefits on into the application programming model (Eclipse RCP is a rare exception). When you build on top of OSGi, but don't necessarily expose that model for end user application development, you can build to the OSGi model and make things work. When you need to provide a platform on which large numbers of existing enterprise libraries can be used it's a different ball game. If we could just throw all that away and start again with libraries written explicitly for OSGi we'd be fine. We've made sure for example that the Spring Framework is fully able to run inside an OSGi Service Platform. But that's not a realistic proposition. Alternatively we could wait for the developers of existing libraries to convert them all to run under OSGi out of the box (as we have done with Spring). But what's the motivation for them to do that unless everyone else does it too? So we seem to be stuck in a chicken-and-egg situation. It's a problem that the OSGi Enterprise Expert Group has spent a lot of time discussing over the past year.
This is the problem that the SpringSource Application Platform solves :- it bootstraps enterprise application development into the world of OSGi by making standard OSGi bundles with standard OSGi semantics work with existing enterprise application libraries.

I'd also like to re-emphasize that the platform is not just about OSGi : the OSGi support is one of the features we're most excited about, but the SpringSource Application Platform is also an excellent server platform for deploying standard war files. We'll describe the benefits the platform offers in such scenarios in later postings.

Hopefully this post has helped to clear up some of the confusion surrounding exactly how the SpringSource Application Platform relates to OSGi. If you've been following along so far, you might have picked up on another lurking problem: it's all well and good to make existing enterprise libraries work under OSGi, but don't you need to turn all of their jar files into OSGi bundles in order to be able to deploy them? Yes you do. And it turns out that's a lot of work if you want to correctly version all of the imports and exports and ensure that you have correct symbolic names etc.. The good news is that for hundreds of commonly used enterprise applications libraries, we've done the hard work for you and made the OSGi-ready versions available in the SpringSource Enterprise Bundle Repository…

SpringSource Enterprise Bundle Repository

The SpringSource Enterprise Bundle Repository is both a repository that can be used from Ivy and Maven, and also an online searchable database of enterprise libraries. You'll find it at www.springsource.com/repository. You can browse for bundles by name, or just type in a search term to find bundles with matching names, exported packages, classes, or resources. You can also see the minimal (satisfying only the required dependencies) and maximal (satisfying as many of the optional dependencies as possible) transitive dependencies of any bundle.

From the FAQ:

"The SpringSource Enterprise Bundle Repository is a collection of open source libraries commonly used for developing enterprise Java applications with the Spring Framework. The repository contains jar files (bundles) and library definition (".libd") files. A library defines a collection of bundles that are often used together for some purpose (e.g. the "Spring Framework" library). There are hundreds of bundles contained in the repository."
The repository meets the following criteria:

  • Every jar file in the repository is a valid OSGi bundle. Any jar you download from the repository can be deployed as-is into an OSGi Service Platform and the SpringSource Application Platform. It can also be used as a regular jar file outside of OSGi.
  • Every bundle and library has full version information associated with it. The package export information for a bundle contains version information, and the package import information for a bundle contains full version range compatibility information.
  • The repository is transitively complete. The mandatory dependencies of any bundle are guaranteed to also be in the repository. Most of the optional dependencies of any bundle in the repository will also be present. The bundles listed in any library definition are guaranteed to be in the repository.
  • The repository is self-consistent. Before any artefact is uploaded to the repository, we verify that it can be installed, resolved, and started in an OSGi Service Platform (using the same profile as the SpringSource Application Platform) alongside all of the other bundles in the repository.
  • The repository can be used from Ivy and Maven based builds.

To maintain these guarantees we have put in place a governance model around the publishing of artefacts to the repository. There is a JIRA instance against which you can raise requests for additional libraries to be included and to report any problems (relating to OSGi manifests etc.) with existing published artefacts.

Application Development Tools:

So far we've discussed the Spring-based programming model for developing applications as OSGi bundles, the availability of enterprise libraries to deploy into an OSGi Service Platform, and a runtime (the SpringSource Application Platform) that enables these legacy libraries to work in an OSGi runtime. The missing piece of the puzzle is the developer tools that make the creation of OSGi-based applications easy.

Eclipse already has OSGi development tools built-in. Since every Eclipse plugin is also an OSGi bundle, the Eclipse PDE tools (Plugin Development Environment tools) can be used for OSGi application development. However, the fact that these tools were primarily designed for the development of Eclipse plugins shows through and there are a couple of common frustrations when using them for OSGi application development. One is that the META-INF/MANIFEST.MF file can only be placed at the root of the project - which doesn't work well with build tools such as Ivy and Maven, and the other is that you are restricted to a single target platform (collection of bundles to develop against) for your whole workspace. What *is* great about the PDE tools, and which you really need, is that they build the compilation classpath for your project from the OSGi manifest - so that you don't have differences in classpath and class visibility between compile, test, and runtimes.

Alongside the SpringSource Application Platform we've also released a set of Eclipse plugins (available from the SpringSource Application Platform download page) that makes the development of OSGi applications easier, especially applications targeted at the SpringSource Application Platform. Your META-INF/MANIFEST.MF file can be in any source directory, and the tools build the compilation classpath from the manifest entries. Instead of a single target platform though, you can associate your project with a SpringSource Application Platform server defined to Eclipse (using the WTP facilities). The classpath for your project is then derived from the import statements in your manifest, resolved against other bundle projects in your workspace and the bundles installed in the associated server. You get the exact same interpretation of your classpath and dependencies at compile time as you do at runtime. And of course, the normal "deploy to server" options work too.

Here's how the server looks when it's running inside Eclipse:

And this screenshot shows how the classpath is managed with a "Bundle Dependencies" classpath container. Notice how packages that you have not imported in your manifest file are greyed out to indicate that you can't currently access them.

Even better is how we're able to take advantage of OSGi's modularity. A set of projects (one per bundle) make up your application. When you change anything in the project, an additional incremental builder analyses the resources deltas and does a live update of the running bundle in the SpringSource Application Platform - so you're continually running with the latest code : every time, all the time. That's a great productivity boost and a great development experience.

Case Study

Matt Raible posted a blog entry about his adventures trying to get a Spring web application working under OSGi using Freemarker - without using the SpringSource Application Platform. This seemed like a good challenge application to test out what I said above about making existing enterprise libraries work. The good news is, this application runs very happily on the SpringSource Application Platform. Here are the steps I followed to make it work (total time, about 10 minutes):

  • Download the zip file from Matt's blog
  • Run 'mvn'
  • cp target/mpapp.war to the pickup directory of the Platform
  • Startup the platform: bin/startup.sh.

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: org.springframework.osgi.web.context.support; version="0.0.0"
Did you mean: 'org.springframework.osgi.context.support'?
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.

  • Go to http://www.springsource.com/repository. 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
  • Simplify the manifest to point to the new bundles and libraries on the platform. The original manifest looked like this:
Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,
org.springframework.osgi.web.context.support, org.springframework.context.support,
org.springframework.web.context, org.springframework.web.context.support,
org.springframework.web.servlet, org.springframework.web.servlet.mvc,
org.springframework.web.servlet.mvc.support, org.springframework.web.servlet.view,
org.springframework.ui, org.springframework.web.servlet.view.
freemarker, freemarker.cache,freemarker.core,freemarker.template,freemarker.ext.servlet

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 the "Bundle-Classpath" entry as the application platform will automatically detect libraries in WEB-INF/lib and add them to the bundle classpath.

  • I edited web.xml and commented out the context-param declaration since there is no need to use a custom application context type here
  • Run 'mvn' again, and copy the myapp.war into the pickup directory.
  • The Application Platform automatically redeployed the application
  • 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.

Spring: Interface21 Team Blog

Introducing the SpringSource Application Platform

After many months of feverish coding, I am pleased to announce the beta release of the SpringSource Application Platform 1.0.

At the beginning of 2007 we began discussing possible alternatives to the monolithic and heavyweight application servers with which Enterprise Java has become synonymous. Customers were looking for a platform that was lightweight, modular and flexible enough to meet their development and deployment needs.

The Spring and Tomcat pairing demonstrates that developers and operators can successfully use a lightweight platform in production. Despite the success of this combination, the lack of modularity and explicit support for non-web applications limits its applicability and flexibility.

We set about building the SpringSource Application Platform to address these requirements and remove these limitations.

At the heart of the Platform is the Dynamic Module Kernel (DMK). The DMK is an OSGi-based kernel that takes full advantage of the modularity and versioning of the OSGi platform. The DMK builds on Equinox and extends its capabilities for provisioning and library management, as well as providing core function for the Platform.

SpringSource Application Platform Architecture

To maintain a minimal runtime footprint, OSGi bundles are installed on demand by the DMK provisioning subsystem. This allows for an application to be installed into a running Platform and for its dependencies to be satisfied from an external repository. Not only does this remove the need to manually install all your application dependencies, which would be tedious, but it keeps memory usage to a minimum.

The DMK itself requires a minimal set of bundles to run, and is configured with a profile to control exactly the set of additional modules that are loaded. For example, the DMK does not require Tomcat to be present, but the default Platform profile includes Tomcat to allow web applications to be deployed. If you want to run a Platform without Tomcat, you can simply edit the profile and it won't be installed. (If you try this - remember that removing web support means that web modules will no longer deploy, so delete the contents of the pickup directory so the platform won't attempt to install the Admin and splash screen applications when it starts.) The default Platform configuration with the admin console installed takes only 15MB of memory.

One frustration I have always had with Enterprise Java is that applications are often shoe-horned into contrived silos, and that explicit support for different application types is lacking. Consider an application for an online store. This application has a web front-end, a message-driven order processing module, a batch-driven stock reordering module and a B2B web service module. Today, many applications like this would be packaged as a WAR or an EAR and the modules would look very similar, with little support for the differences in the module types. Interestingly, many people would refer to this as a web application, rather than an application with a web module.

In the SpringSource Application Platform, applications are modular and each module has a personality that describes what kind of module it is: web, batch, web service, etc. The Platform deploys modules of each personality in a personality-specific manner. For example, web modules are configured in Tomcat with web context. Each module in the application can be updated independently of the other modules whilst retaining the identity of being part of the larger application. Whatever kind of application you are building, the programming model remains standard Spring and Spring DM.

In the 1.0 Platform release we support the web and bundle personalities, which enable you to build sophisticated web applications. Future releases will include support for more personalities as detailed later.

Building Applications

The Platform supports applications packaged in three forms:

  1. Java EE WAR
  2. Raw OSGi bundles
  3. Platform Archive (PAR)

Standard WAR files are supported directly in the Platform. At deployment time, the WAR file is transformed into an OSGi bundle and installed into Tomcat. All the standard WAR contracts are honoured, and your existing WAR files should just drop in and deploy without change.

Any OSGi-compliant bundle can be deployed directly into the Platform, and can take full advantage of on-the-fly provisioning for any dependencies referred to by Import-Package and Require-Bundle.

The PAR format is the recommended approach for packaging and deploying applications for the Platform. A PAR is simply a collection of OSGi bundles (modules) grouped together in a standard JAR file, along with a name and a version that uniquely identify the application. The PAR file is deployed as a single unit into the Platform. The Platform will extract all the modules from the PAR and install them. Third-party dependencies will be installed on-the-fly as needed.

The PAR format has three main benefits over deploying the bundles directly into the Platform. Firstly, it's just easier. An average-sized enterprise application might contain 12+ bundles - deploying these by hand will be far too cumbersome. Secondly, the PAR file forms an explicit scope around all the bundles in the application which prevents applications that use overlapping types or services from clashing with each other. This scope is also used by some advanced features such as load-time weaving to ensure that weaving of one application doesn't interfere with weaving of another. Lastly, the PAR forms a logical grouping to define what modules are part of an application and what third-party dependencies the application has. This grouping is used by the management tools to provide a detailed view of the application. A typical PAR application looks like this:

PAR File Structure

Dependencies between modules in an application are typically expressed using Import-Package and Export-Package. Dependencies on third-party libraries can be expressed in the same way, but for many libraries this can be error-prone and time-consuming. When using a library such as Hibernate, you will typically have to import more packages than you initially expect. To get around this you could use Require-Bundle, but this has some semantic rough edges such as split packages where a logical package is split across two or more class loaders causing problems at runtime. The Platform introduces two new mechanisms for referring to third-party dependencies: Import-Bundle and Import-Libary. Import-Bundle is analogous to Require-Bundle except it prevents split packages and the other problems with Require-Bundle. Import-Library provides a mechanism to refer to all the packages exported by a group of bundles, for instance all bundles in the Spring Framework, in a single declaration:

Bundle-SymbolicName: com.myapp.dao.jdbc
Bundle-Version: 1.0.0
Import-Bundle: org.apache.commons.dbcp;version="1.2.2.osgi"
Import-Library: org.springframework.spring;version="2.5.4.A"

Here I have a module bundle that depends on the Commons DBCP bundle and the Spring Framework library. The Spring Framework library contains all the bundles needed to use Spring in your application.

Import-Library and Import-Bundle expand under the covers into Import-Package and are therefore consistent with standard OSGi semantics.

The Platform understands the personality of a module, and from this can infer how to configure the module's execution environment. When deploying a web module, all the servlet infrastructure needed for a typical Spring MVC application is created automatically, removing the need to recreate this boilerplate code across applications. In the 1.0 final release, more smarts will be added to the web module personality to support additional technologies such as Spring Web Flow.

Whatever packaging format you choose, the programming model is simply Spring Framework and Spring Dynamic Modules, with the other Spring Portfolio products running on top.

Serviceability

Serviceability was a critical consideration for the whole engineering team. We have spent an inordinate amount of time worrying about the format of log messages and the size of stack traces to make sure that diagnosing problems with your applications is as easy as possible. Any time we find a task that is repetitive and time-consuming we look for a way to automate it or remove it altogether.

To aid with problem diagnosis the Platform has a strong split between log and trace messages. Log messages are intended for end-user consumption and allow you to get access to the most important failure information without having to trawl through gigabytes of trace content. All application failures are displayed and coded in the log output - the codes serving as a convenient way to access knowledge base or support content. To understand why this is so useful, consider the following output from Platform startup:

[2008-04-29 12:12:01.124] main <SPKB0001I> Platform starting.
[2008-04-29 12:12:04.037] main <SPKE0000I> Boot subsystems installed.
[2008-04-29 12:12:06.013] main <SPKE0001I> Base subsystems installed.
[2008-04-29 12:12:07.396] platform-dm-1 <SPPM0000I> Installing profile 'web'.
[2008-04-29 12:12:07.674] platform-dm-1 <SPPM0001I> Installed profile 'web'.
[2008-04-29 12:12:07.721] platform-dm-14 <SPSC0000I> Creating ServletContainer on port 8080
[2008-04-29 12:12:08.036] platform-dm-10 <SPPM0002I> Platform open for business with profile 'web'.
[2008-04-29 12:12:09.405] fs-watcher <SPSC1000I> Creating web application '/admin'
[2008-04-29 12:12:09.652] async-delivery-thread-1 <SPSC1001I> Deploying web application '/admin'

Gone are the pages and pages of output detailing the inner workings of every single type in the startup call chain. Instead, you get messages that actually mean something. Of course, this doesn't mean you can't find out what every type is doing: we still maintain an extensive trace. Indeed, because we split out the most important log messages from trace, our trace can be more verbose because it is intended to be read less often.

Critical failures in the Platform generate a service dump that can be passed to support personnel to aid in the diagnosis process. This dump contains state from all the major subsystems in the Platform and is hooked in via AspectJ to make sure we pick up every possible site where an unchecked Exception can be raised.

The Platform also actively monitors for problems in the JVM and triggers a dump. In the 1.0 release this is limited to deadlock monitoring only, but will include memory, lock contention and CPU contention in future releases.

Roadmap

This beta release is only the start for the SpringSource Application Platform. We have tentatively defined a roadmap to cover the 2.0 release with a focus on five main areas: the Admin Console, middleware integration, additional personalities, clustering and DMK 2.0.

With the Admin Console we want to exploit all the application knowledge that the Platform has, and make this available to the end-user. The Admin Console will allow for detailed inspection of applications starting at the module level and running right down to the bean level. Applications will be linked to the libraries and bundles they depend on, and the Admin Console will provide the ability to upgrade these libraries dynamically. By understanding the different types of beans that an application contains, the Admin Console will provide for detailed insight into application internals and allow for dynamic reconfiguration of certain application components.

To support typical enterprise deployment scenarios, the 2.0 version of the Platform will provide explicit support for common enterprise middleware components such as Oracle, TIBCO EMS and IBM MQSeries. Integration with the Admin Console will allow for connections to these middleware providers to be established in minutes rather than hours or days. Applications will be able to access these connections using the OSGi service registry and Spring DM's <osgi:reference>.

The 2.0 release will introduce additional personalities to cover batch, web services and SOA applications.

Clustering is an important feature for the 2.0 release, with cluster-wide Single System Image (SSI) being the critical piece, and load-balancing and clustered caching being on the roadmap as well. Using the SSI support, administration and deployment operations will be propagated across the cluster. Ultimately, we want to support per-module updates across the cluster, with full cluster-rollback if the upgrade breaks a deployed application.

DMK 2.0 will include improvements to the concurrency subsystem to support large numbers of bundles that change frequently and to support larger numbers of modules with more complex interdependencies. Also included will be updates to the provisioning subsystem and integrated resource management and monitoring for memory, threads, IO and CPU.

What next?

Please download the Platform and try it out. We are keen to hear about your experiences building new applications and deploying existing ones. All feedback, positive or negative, is welcome. We are particularly interested to hear how we can make the process of building and deploying applications easier and more enjoyable.

The binary releases and forums can be found here. Both the user's guide and programmer's guide are available online. We have a JIRA instance set up here.

Spring: Interface21 Team Blog

SpringSource Application Platform Manifest Headers

The SpringSource Application Platform is constructed from OSGi bundles and supports applications which are also constructed from OSGi bundles. The Platform supports the standard features of OSGi, but it also supports some additional manifest headers. Several people have asked Why did SpringSource add proprietary headers? and What are the semantics of the new headers?, so this post explains the background motivation and the semantics of Import-Library and Import-Bundle.

Standard OSGi Bundle Support

The Platform is built on the OSGi R4.1 standard, or JSR 291 if you prefer, and uses Equinox as its OSGi implementation. The result is that you can develop standard OSGi bundles using the Platform's tooling and deploy those bundles on the Platform, as a number of users have been doing since the Platform's launch.

So OSGi savvy developers can use the Platform as a standard OSGi container and benefit from Platform features such as:

  • the ability to deploy bundles using the Admin Console or by dropping bundles in the Platform's pickup directory,
  • diagnostics such as resolution failure diagnosis, application specific trace, and automatic deadlock detection,
  • strong integration with Spring and Spring Dynamic Modules, for developers who want to use these frameworks, and
  • automatic provisioning of dependencies from a repository.

However, the Platform also aims to make it easy for enterprise application developers with little or no prior exposure to OSGi to benefit from OSGi, which places some extra requirements on the Platform.

Additional Requirements of Enterprise Applications

As Sam's recent blog on the Platform's deployment options explains, you can deploy existing monolithic WAR files on the Platform with no need to understand OSGi - the Platform takes care of everything for you. But to benefit from shared libraries, shared services and, ultimately, PAR file scoping, it is necessary to break monolithic WAR files into OSGi bundles. How hard can that be?

Well, some steps in the process are relatively easy, especially if good software engineering practices have been followed and the code has been organised into service, domain, and infrastructure components. These components can be converted into bundles and the dependencies between them expressed using standard OSGi Import-Package and Export-Package headers in META-INF/MANIFEST.MF.

A more difficult step is expressing dependencies on enterprise frameworks such as Spring and Hibernate. It is entirely possible to express these dependencies using standard OSGi Import-Package and Require-Bundle headers, and this is exactly what you should do if your aim is to create OSGi bundles which will run in other OSGi containers, but this approach has some hidden costs.

Firstly, the developer has to decide precisely which packages comprise a given framework. It isn't sufficient merely to import the packages the application code uses, as several enterprise frameworks weave further dependencies into the bytecode of the application when the application is loaded. The developer has to discover, probably by trial and error, which additional implementation packages to import to ensure correct behaviour of the woven application.

Then there is the chore of migrating from one version of a framework to the next where the precise set of packages comprising the framework has changed. The additional packages required for weaving are typically not defined by a public contract and so are subject to change.

Additionally, the resultant package imports don't properly capture the design intent, which makes maintaining or extending the application more difficult in the future.

We really don't want to impose these burdens on our users, so we created some additional SpringSource Application Platform specific manifest headers, Import-Library and Import-Bundle, as convenient ways of expressing dependencies on enterprise frameworks. As you'll see below, these headers are really just syntactic sugar which are expressed in terms of standard OSGi package imports.

Import-Library

The basic syntax is similar to that of other manifest headers:

    Import-Library: <librarySymbolicName>;version=<versionRange>

where <librarySymbolicName> is the symbolic name of the library and <versionRange> is a range of acceptable versions of the library using OSGi version range notation. A library definition specifies the library's symbolic name and version and these together uniquely identify the library to the Platform.

If you are unfamiliar with OSGi version range notation, by far the most commonly used forms are minimum version ranges such as 2, meaning version 2 or later, and half-open ranges such as [2.2.1,2.2.2), meaning any version between 2.2.1 inclusive and 2.2.2 exclusive. If version=<versionRange> is omitted, together with the semicolon delimiter of course, then the default range includes all versions.

For each library import, the Platform selects the library with the given symbolic name and the highest version in the given version range available in the Platform's repository. The Platform then replaces the library import with a set of package imports which match all the packages exported by the bundles of the library. The Platform detects the situation where a bundle imports two or more libraries which export a common package, issues an appropriate log message, and fails to install the importing bundle.

So, for example, the following header imports some version of the Spring Framework library between 2.5.4 inclusive and 2.5.5 exclusive:

    Import-Library: org.springframework.spring;version="[2.5.4,2.5.5)"

Optional Library Import

You can indicate that a library import is optional using the following syntax. Note the special separator := which indicates a directive that modifies the semantics of the manifest header, as opposed to the separator = which indicates a matching attribute, like version.

    Import-Library: <librarySymbolicName>;version=<versionRange>;resolution:=optional

If resolution is not specified, or is specified as mandatory, the bundle containing the import library header will fail to install if there is no library with the given symbolic name and a version in the given range. But if resolution:=optional is specified, the library import will be ignored if no suitable library is available.

So, for example, the following header imports some version of the Spring Framework library from 2.5 onwards, but is ignored if no suitable library is available:

    Import-Library: org.springframework.spring;version="2.5";resolution:=optional

Importing More than One Library

If you need to import more than one library, then specify a comma-separated list of library imports in a single Import-Library manifest header as in the following example:

    Import-Library: org.foo.p;version="[1,2)",org.bar.q;version="[2,3)"

Import-Bundle

Import-Bundle is a further convenience for cases where a library would consist of only a single bundle and a library definition is inconvenient to create. The syntax is very similar to that of Import-Library except that it refers to a bundle's symbolic name and version instead of those of a library.

As you would expect, for each imported bundle, the Platform selects the bundle with the given symbolic name and the highest version in the given version range available in the Platform's repository. The Platform then replaces the bundle import with a set of package imports matching the packages exported by the bundle.

So, for example, the following header imports the Hibernate Object-Relational Mapper bundle:

    Import-Bundle: com.springsource.org.hibernate;version="[3.2.6,3.2.7)"

Why not Overload Require-Bundle?

If you are familiar with OSGi, you may be asking yourself why we didn't overload Require-Bundle instead of introducing Import-Bundle.

Well, we wanted Require-Bundle to retain its standard semantics, including the ability to marry together pieces of a split package. But we wanted Import-Library and Import-Bundle to have t