Blogs

SpringSource Blog

Modular Web Applications with SpringSource Slices

Rob Harrop

Updated: added sub module instructions for Git.

I've talked in the past about providing support for truly modular applications, and I'm pleased to announce that you can now access the early prototype code of SpringSource Slices.

Building and Installing

You can access the source code from our Git repository:

git clone git://git.springsource.org/slices/slices.git
git submodule init
git submodule update

To build a packaged version of Slices simply run ant clean jar package from the build-slices directory:

cd slices/build-slices
ant clean jar package

This will result in a zip file in target/artifacts that contains the Slices subsystem which can then be installed on top of dm Server 2.0

Installing Slices is simply a matter of adding the new subsystem to dm Server and then updating dmServer's profile to start the new subsystem. Slices should work with any recent dm Server 2.0 snapshot build. Here I'm using 2.0.0.CI-R326-B274 which I've already downloaded and unzipped on my desktop:

 unzip target/artifacts/springsource-slices-BUILD-20090622083953.zip -d ~/Desktop/springsource-dm-server-2.0.0.CI-R326-B274

Next, dm Server's kernel.properties configuration must be updated to include the new slices subsystem. Open your dm Server installation's config/kernel.properties file, and edit the Profile Configuration section to list the slices subsystem and to give the profile a suitable name (I've called it slices):

#######################
# Profile Configuration
#######################
profile.name=slices
profile.subsystems=	com.springsource.server.web,com.springsource.osgi.slices
profile.optionalSubsystems=

Save the updated file and you're ready to try the Slices sample application.

Trying out the sample application

The Slices repository contains a version of Spring 3's PetClinic sample that we're constantly enhancing and improving as we add new features to Slices.

Before using the sample, its dependencies must be added to your dm Server installation. The dependencies are listed in the sample's dependencies.txt file. Download each of the listed dependencies to the installation's repository/bundles/usr directory. Next, start dm Server using the -clean startup option:

./bin/startup.sh -clean

Now it's time to build and deploy the sample. Move into the slices/samples/slices-petclinic/com.springsource.slices.petclinic.host directory and run ant clean jar:

cd samples/slices-petclinic/com.springsource.slices.petclinic.host
ant clean jar

The host can then be deployed by copying the resulting war to dm Server's pickup directory:

 cp target/artifacts/com.springsource.slices.petclinic.host.war ~/Desktop/springsource-dm-server-2.0.0.CI-R326-B274/pickup/

The host should now be accessible from http://localhost:8080/petclinic:

petclinic-no-slices

Next, move into the slices/samples/slices-petclinic/com.springsource.slices.petclinic.appointments directory and run ant clean jar to build the appointments slice:

cd samples/slices-petclinic/com.springsource.slices.petclinic.appointments
ant clean jar

The slice can now be deployed by copying the resulting war to dm Server's pickup directory:

cp target/artifacts/com.springsource.slices.petclinic.appointments.war  ~/Desktop/springsource-dm-server-2.0.0.CI-R326-B274/pickup/

Refresh http://localhost:8080/petclinic and it will now reflect the presence of the appointments slice with a new Appointments link:

petclinic-appointments-slice

You can, if you wish, now remove the appointments war from the pickup directory to see the slice disappear again.

Anatomy of a Slices Application

Using Slices you can construct a web application from multiple OSGi bundles, each of which serves up content for a distinct sub-portion of your application's URL space. Slices applications are arranged in a parent/child structure, with each application having at most one parent, referred to as the host, and zero or more children, referred to as slices. We're working on a simple Slices sample that looks like this:

slice-anatomy

Inside the Host

The petclinic.host bundle contains all the shared content such as images and CSS, along with controllers and JSPs to serve up the home page. A host bundle is simply an RFC66-compliant web bundle that has a SliceHostFilter configured in its web.xml. The code snippet below shows the web.xml from the petclinic.host bundle:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <filter>
    	<filter-name>host-filter</filter-name>
    	<filter-class>com.springsource.osgi.slices.core.SliceHostFilter</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>host-filter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

	<!-- Enables clean URLs with JSP views e.g. /welcome instead of /app/welcome -->
	<filter>
		<filter-name>UrlRewriteFilter</filter-name>
		<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
	</filter>

	<filter-mapping>
		<filter-name>UrlRewriteFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<!-- Handles all requests into the application -->
	<servlet>
		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>
				/WEB-INF/spring/*.xml
			</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- Maps all /app requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
		<url-pattern>/app/*</url-pattern>
	</servlet-mapping>

  	<!-- Serves static resource content from the webapp root & .jar files such as spring-js.jar -->
	<servlet>
		<servlet-name>Resources Servlet</servlet-name>
		<servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
		<load-on-startup>0</load-on-startup>
	</servlet>

	<!-- Map all /resources requests to the Resource Servlet for handling -->
	<servlet-mapping>
		<servlet-name>Resources Servlet</servlet-name>
		<url-pattern>/resources/*</url-pattern>
	</servlet-mapping>	

</web-app>

As you can see, the host can have any normal servlet and filter mappings, but it needs the SliceHostFilter to be able to route requests to its slices.

Inside a Slice

A slice is a bundle that looks and functions like a standard RFC66 webbundle, expect for the fact that it doesn't have its own ServletContext. Instead, a slice runs under the ServletContext of its host.

One of the main design goals for Slices in to ensure that slice development is as similar to standard web application development as can be. To this end, you create slice web content, exactly the same way you would create web content for any application, using web.xml. Here is the web.xml from the petclinic.appointments bundle:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

	<!-- Handles all requests into the application -->
	<servlet>
		<servlet-name>appointments</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<!-- Maps all /app requests to the DispatcherServlet for handling -->
	<servlet-mapping>
		<servlet-name>appointments</servlet-name>
		<url-pattern>/app/*</url-pattern>
	</servlet-mapping>

</web-app>

The appointments slice is just delegating into the Spring DispatcherServlet. Spring MVC can be used as normal within the slice.

The slice can access resources from the host bundle by simply referencing a resource name that does not exist in the slice itself. If a slice wants to access a resource in the host, even when it has a similarly named resource itself it can use the host: prefix to do so:

ServletContext context =  getServletContext();
context.getResource("host:/WEB-INF/some.config.xml");

A slice needs to define which host it wants to attach to and does so using the Slice-Host manifest header. The Slice-ContextPath header defines which URL portion the slice handles:

Bundle-SymbolicName: petclininc.appointments
Slice-Host: petclinic.host;version="[1.0, 2.0)"
Slice-ContextPath: /appointments

Slice Lifecycle

A host can be running without any corresponding slices attached. When a Slice is installed into the server that matches a host, the slice is attached to the host. At this point, the sub-portion of the host's URL portion that matches the newly attached slice's Slice-ContextPath is routed to that slice.

When a slice is uninstalled, the portion of the URL space that was routed to the slice is now routed directly into the host. In this way, you can create content in the host to handle missing slices.

What can I do in a Slice Today?

As of the time of writing, the Slices codebase supports the following features in a Slice:

  • Servlets and servlet mappings
  • JSPs
  • Spring MVC
  • Slice-local Sessions
  • Automatic fallback to app-wide Session
  • Slice-local resources lookups via ServletContext
  • Automatic fallback to resource lookup in the host
  • Explicit host resource lookup using host:

What Next?

We're working on lots of interesting new functionality for Slices including:

  • Filters and filter mappings in slices
  • Listeners in slices
  • UI composition framework. You can see a manual approach to this in the Petclinic sample
  • Tiles 2 integration
  • Full sample application
  • SpringSource Tool Suite support

If you have any feature suggestions or you find a bug please don't hesitate to raise an issue on our JIRA.

If you want to keep a close eye on progress then you can follow our Git repository and our #dmserver Twitter tag.

Similar Posts

Share this Post
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • DZone
  • LinkedIn
  • Slashdot
  • Technorati
  • Twitter
 

56 responses


  1. This is great news Rob, team! It's been one of the gaps in the dm Server offering for many clients I spoke to in the past and this makes dm Server a compelling offering for many shops doing big webapps!

    Congrats!

    alef


  2. Hi
    first of all,Congratulations
    is using dm server a must? or may i use slice with spring-dm?
    if not , do you have plan for this? i men using slices with spring-dm without dm server,ie. plain tomcat
    i really respect and appreciate the effort behind the dm-server but we are an ISV and licensing terms for dm-server distribution with each copy of our software seems unclear to us
    Joe


  3. I second Joe's comments it would be really nice if slice can be used with spring dm sans dm server. Also can you slice hibernate/jpa based apps too?


  4. Using dm Server is a must at the moment as the Slices implementation relies upon the dm Server deployer.

    Slicing a Hibernate/JPA-based application is certainly possible. Usage of JPA is one of the things that we'll be adding to the Slices PetClinic sample over the coming weeks.


  5. This looks very promising. The ability to actually split up the view part into several slices (PARS?) opens perspectives.


  6. @Joe Re: ISV re-distribution of dm Server –
    The dm Server product page has a Licensing FAQ which I believe covers your question:
    http://www.springsource.com/products/dmserver/licensingfaq
    Also the SpringSource forum is a great place to ask these questions. You can see my answer to a similar question in this thread:
    http://forum.springsource.org/showthread.php?p=224372#post224372

    Adam FitzGerald
    SpringSource


  7. Problem building on Windows Vista after running "ant clean jar package" using ant 1.7.1:

    BUILD FAILED
    C:\usr\java\slices\spring-build\multi-bundle\artifact.xml:45: The following error occurred while executing this line:
    C:\usr\java\slices\spring-build\multi-bundle\common.xml:71: The following error occurred while executing this line:
    C:\usr\java\slices\spring-build\common\artifact.xml:28: The following error occurred while executing this line:
    C:\usr\java\slices\spring-build\common\common.xml:146: The following error occurred while executing this line:
    C:\usr\java\slices\spring-build\standard\common.xml:14: src doesn't support the "dir" attribute


  8. @Rob, I have question on web slices. Do they share the same resource bundle, template folder, images, etc?

    @Andy, Is that possible to deploy multiple persistence.xml under the same PU name for each JPA slice?


  9. the same error as above on windows xp


  10. @Scott, @bigchong, Thanks for taking the time to report the problem. This is one disadvantage of doing all our development work on Mac :) I'm looking at the Windows problem now. I'll comment again once it's fixed.


  11. reg. build failure

    I'v made a small change in spring-build\standard\common.xml. The part with <s:javac…. can be:

    this works for me.


  12. And here's the actuall change:
    <![CDATA[

    ]]>


  13. This is beginning to be a joke :-) . Alright I'll try another approach.

    I've done the following:

    1. added srcdir="@{input.dir}" to the <s:javac tag
    2. Removed <src dir="@{input.dir}" (this is part that gives an error, located on line 14)


  14. @Scott @bigchong @Anders, thanks again for the problem reports.

    The build should now work find on both Windows XP and Windows Vista. When you pull the latest code, if you've previously attempted to build it, please delete the ivy-cache directory at the root of the slices source tree before build again.


  15. @donny A slice can access resources both in the slice and in its host via its ServletContext. By default a resource lookup in a slice will first check the slice's resources and, if the resource isn't found, it'll fall back to its host. If code in a slice wishes to force the resource to be loaded from the host then it can do so by prefixing the resource path with host:.

    We're not 100% sure what form JPA will take when it's used in a slice. There are certainly some things that it probably makes sense to share between slices, e.g. the datasource, and some things that it makes a sense to define in each slice. We haven't made any decisions around the granularity of persistence units yet. All I can really say at this stage is thanks for your interest, and watch this space!


  16. @Andy I can now build on Windows Vista. Thanks!


  17. Rob and others, great stuff. As Alef already mentioned this was a missing and greatly asked for feature to have. We now have the way to really make modular (web) applications. Great, as always keep up the good work.


  18. First of all. Greate idea – at work we been thinking along the same lines, but newer got around finding a framework who got that functionality.

    I've got to questions about the future features of slices:

    1.
    Will it be posible to use the dynamic module way of exporting osgi services with slices? In dm you specify that you would like to export a service, the same thing could be done for slices.

    2.
    In the demo you retrieve a list of slices and write them on the page. The user can then click on a "slice" to activate it. Will it be possible to call a slice from a page and embed the result directly on the page? A little bit like a portal I guess.


  19. @Anders

    1. Absolutely. A slice is a Web bundle so anything you can do in a Web bundle, you can do in a slice. To make use of Spring DM in a slice, all you need to do is to configure it to create a OSGi-aware application context, for example by adding a context-param to your web.xml, that configures the contextClass to be com.springsource.server.web.dm.ServerOsgiBundleXmlWebApplicationContext. This is discussed in more detail in the dm Server programmer guide. I'd recommend grabbing a recent dm Server nightly build and referring to its documentation of this area as it's been recently updated.

    2. This isn't something we've look at in a lot of detail yet. In theory the architecture of the prototype should support something along these lines. A filter in the host is used to direct requests to a slice, by enabling this filter for request dispatcher forwards and includes, it should be possible to direct a forward or include to a slice. As I said, we haven't looked at this in a lot of detail yet so there may be some unforeseen complications but I'm hopeful that this is something that Slices will be able to support.


  20. Is there any options for adding content negotiation to slices for differetn view like xml view or json view.
    Actually I am triyng to add xml marshaller view to my dispatcher servlet of slices, but my host is not able to recognise this bundle as a slice, if I remove marshaller view then host is able to recognised as a slice. This thing I am doing for modularizing my REST API Web bundle at MiddleWare level.


  21. @Mahesh, the contents of a Slice shouldn't make a difference to the host's ability to recognise its presence. One area of the prototype that's most in need of some work is the error handling. It would be my guess that something's not quite right in your Slice's configuration but, due to the missing error handling, it's failing silently.

    I'm planning to do some work on the error handling as soon as dm Server 2.0.0.M3 has been released (should be any day now). In the meantime, if you'd like to post on the dm Server forum (http://forum.springsource.org/forumdisplay.php?f=53), or, preferrably, open a dm Server JIRA (https://issuetracker.springsource.com/browse/DMS) attaching your app, I'd be happy to take a more detailed look at your problem.


  22. Do these Slices support a Web app developed using Struts 2 MVC but deployed on the Spring DM server — since there is mention of only Spring MVC.


  23. @Sriram,

    Slices is being built to work on the raw Servlet API level. So far we've only tested basic servlet functions and Spring MVC, but I seen no reason why Struts 2 wouldn't work other than where we are missing some support for servlet features required by Struts.

    Regards,

    Rob


  24. Hi!

    I'm a computer scientist student doing his master thesis and I'm developing a web application using dmServer. I think this feature is great! In fact I think is really similar to what I have been developing so far. Where can I find more information about this new feature? I think it could be really interesting for my project.
    You can find my project here:
    http://myflit.svn.sourceforge.net/viewvc/myflit/
    I can so far load and unload a new Tab (bundle) in the TabArea (main web application). I can use the OSGi lifecycle to start/stop a component of the main web interface.
    In this scenario I think slices fits perfectly!

    Best regards,
    Victor


  25. I was wondering if there any plans to integrate spring slices in the grails framework. Also, is it possible to share session with spring slices accross disparate locations (several instances of an application server)?


  26. For some reason when I check out the code the spring-build library is empty and therefore I get and error when trying to build slices.


  27. @Anders,

    I've updated the instructions to reflect our use of git submodules.

    Rob


  28. @Chris,

    We have no concrete plans for grails integration, but it is definitely something we want to evaluate.

    Slices sessions run on standard HTTP sessions, so session distribution works as normal.

    Regards,

    Rob


  29. Does slices support Spring Webflow or will it?


  30. Hi Rob,
    Please help me out in the following scenario.

    I have Menu.jsp page in Host bundle and want to include this Menu.jsp page in my slice.

    In this article you demonstrated very nicely on how to get Host resources but I want to include Host jsp pages in slice.

    Please give me the syntax to include Host jsp pages in slic jsp page.

    I appriciate your help.

    Thanks
    Mahesh


  31. @Chuck Slices just builds upon standard Servlet semantics, with the goal being that any Web framework that works in a standard Web application will also work with Slices. We haven't done any work yet specifically with Web Flow but we're not aware of anything that would stop Web Flow from working with Slices.

    @Mahesh Have you looked at the menu-bar sample that's included in the Slices Git repository? The index.jsp pages in the two Slices do exactly what you want to do. For example https://fisheye.springsource.org/browse/slices/samples/menu-bar/cat.menu.item/src/main/webapp/index.jsp?r=HEAD

    When performing an include, the path that's specified is relative to the Slice, e.g. /index.jsp will forward to index.jsp in the root of the Slice. To access a resource in the Host, you need to move "up" a "directory", e.g. /../index.jsp will access index.jsp in the root of the Host.


  32. Thanks Andy. I am able to include Host pages into slice bundle. It's very helpful to my project.
    Thanks Again.

    Mahesh.C


  33. Thanks for the info. I will give it a try.


  34. Hi!

    Since the new SpringSource dm Server 2.0.0 milestone versions the directory structure and configuration have changed a bit. How do these changes affect the installation of SpringSource slices? The procedure described above needs some adjustments, but what? Especially the editing of config/kernel.properties which is now missing in dm Server 2.0.0.M6.


  35. This is a great project. Is there any progress? When the first official release may be available?
    Awaiting eagerly.


  36. @Sudhir Thanks! Our focus at the moment is on dm Server 2.0 which should be moving to release candidate very shortly. You can expect to see some significant progress on Slices in the new year.


  37. @Teemu You've reminded me that I need to blog about this…

    For the latest nightly builds this, in a nutshell, is what you need to do:

    Copy to Slices' artifact to repository/usr (the .jar files and the .plan file)
    Edit com.springsource.kernel.userregion.properties and edit the initialArtifacts property to add the Slices' plan:

    initialArtifacts=repository:plan/com.springsource.kernel.userregion.springdm, repository:plan/com.springsource.server.web, repository:plan/com.springsource.osgi.slices


  38. Hi Rob,

    We are very eagerly waiting for the release version of Spring dm 2.0. Could you please help us know when it will be out?

    Thanks,
    Tom


  39. @Tom, We've just planned what we hope will be our final sprint (it's a one week sprint) prior to 2.0 RC1. You should, all being well, see the RC next week subject to a few of our dependencies also being ready, e.g. Spring 3 GA.


  40. I got an error when accessing the web. Can you tell me how to fix it?

    java.lang.ClassCastException: org.eclipse.osgi.framework.internal.core.BundleContextImpl cannot be cast to org.osgi.framework.BundleContext
    com.springsource.slices.petclinic.HomeController.get(HomeController.java:26)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)


  41. Hi,

    I'm working on a project with Spring dm, Spring MVC, Hibernate, … Our main constraint is to remain platform independent and we used to test our application against Equinox, Felix, and Knopflerfish as part of our continuous integration process.

    I have recently read a lot about SpringSource Slices which is really an interesting project that addresses concrete business needs and I was wondering if there was any plan to integrate Web module with Springdm without having to use dm server and remain platform independent ?
    Thanks
    I've posted an entry in SpringSource forum : http://forum.springsource.org/showthread.php?t=82675


  42. Does the host and slice share the same http session? For example, if I want a user to login on the host web page, then can access other slices without login again. I know CAS can be used for single sign on, but maybe it is too heavy. Since slice is a modular method to develop web app.I suppose the host app and slice page can work together seamlessly just like a single war.


  43. @Alexi, yes, a host and its slices share the same HTTP session. The HTTP session is partitioned to prevent naming clashes. This means that a Slice cannot overwrite an entry that was set by its host but, in the absence of a Slice specific value having been set, a Slice will get the Host's value.


  44. @Andy, thanks for your reply. When I try to define security attributes in a slice's application context, it does not work. Here is my configuration.

    Since it is a modular framework, obviously http access control should be defined in the slices as above. Did I miss something? As you said, slices does not support listeners and filters locally. I suppose the only thing I need to configure is the above lines. I do try to add listeners and filter springSecurityFilterChain, it does not work.



  45. Obviously the blog forbid me pasting code. Here is the simple one.
    s:intercept-url pattern="/" access="isAuthenticated()


  46. By the way it is possible to define another authentication provider? It is possible that a sub module (a slice) may need to check authorities against another source.


  47. I defined http url intercept in applicationContext.xml.It works when I access directly a protected page in the slice by inputting its address in the browser's address box.

    But the security tag defined in jsp page does not work. After debugging, I find it used the root webapplicationContext instead of the slice's.


  48. How can I package slices-api.jar from the slices source dir ?
    I am getting that error as it is missing during installation of slices into spring dm.

    Thanks


  49. is the license free? lib/dm-server-license.html says it is non-redistributable


  50. As I know, slice will become a standalone spring project (not depend on osgi) since spring dm server will move to eclipse foundation. I do find the latest source code begin to support deploying slice into standard web container such as tomcat. But from the sample, I can not find modular "WEB" application. I mean a standard war as a slice which can be attached to the host webapp. It is more like a lightweight osgi container (we can define service as slice(bundle), and other slice or webapp can refer the servie).


  51. @Alexi

    You are correct that we're moving Slices from a prototype over to a proper project at the moment and during this time we've taken a step back to work on some of the interesting use-cases we identified. As you've seen we are working on bringing the concept of a 'service registry' to applications outside of OSGi, but I would hesitate to refer to it as lightweight OSGi (specifically, Slices does not address runtime modularity at all).

    Because some of the features from the prototype require base functionality like a service registry to work, they will necessarily come after the low-level infrastructure being created for Slices. Rest assured that before long modular web application behavior will return to Slices in both OSGi and non-OSGi environments. I encourage you to keep an eye on this blog as well as the Slices JIRA (https://jira.springsource.org/browse/SLICE) for details about when these features are ready.

    Thanks for your interest in the project, and I hope that you're as excited as I am to see what will come.


  52. how slices works with xsl:include and with xsl in general… would be good in case some kind of xsl tutorial provided


  53. Hello,

    it seems that the spring slice project is no longer active ?
    Am I wrong ?

    JLM.


  54. Is there any update on this project ! Is it being developed, and can we hope for a stable release !


  55. Slices was donated to the Eclipse Virgo project and renamed to "snaps" where it is still currently a prototype but is being maintained and extended. We plan to bring it out of prototype status once documentation has been written to make its features and limitations clear.

    Virgo: http://www.eclipse.org/virgo/

    Snaps git repository: http://wiki.eclipse.org/Virgo/Source

6 trackbacks

Leave a Reply