Eclipse Virgo + Snaps: Modular Web Apps, finally, Part 2

In this part I will try to create some simple Snaps, together establishing a Web Application. I assume you have read Part 1 and have thus set up Virgo itself, applied the Snaps patch and have Eclipse up and running.

Of course, the Virgo Programmers manual covers a lot of the steps nessecary. My emphasis lies on Snaps and ease of development, so lets start:
First of all, you should install the Spring Virgo Tooling from http://dist.springsource.com/release/TOOLS/update/e3.6. After that you should be able to start your installed Virgo Server from within Eclipse following the instructions from the Virgo Programmers Manual.

My first Web application bundle!

Create an Eclipse RT bundle project:
Name it org.test.host. Besides the required project natures, only one file is created: The Manifest. Open it and, in the MANIFEST.MF editor, add the following line:
Web-ContextPath: /test
Then create an index.jsp file in the src-folder with any (simple) content you like, e.g. "hello, world".

Believe it or not, but you have just created your first web application bundle, an artifact that is an OSGi-bundle as well as a web application.
Now in the Server View,  in the popup-menu of your Virgo server, choose add and remove to add the new bundle to your server (of course you could also build a jar and copy it to the pickup area). You bundle is listed as available resource. Add it to your server. The console will show how the bundle is started and bound to the context /test. Thus it is not too surprising to get the hello world message on navigating to http://localhost:8080/test/index.jsp.

My first Snap!

Beware! Things may become boring now.
Create another bundle project, just as above, but to the MANIFEST.MF file now add:
Snap-Host: org.test.host;version="[1.0, 2.0)"
Snap-ContextPath: /snap1
Even another src/index.jsp should show some different content. Project layout should now be similar to this:

Congrats, your first snap was born. After adding it to the server, this content is now served under http://localhost:8080/test/snap1/index.jsp.
Note that this snap is not a web application bundle (we did not add the Web-ContextPath header), thus it does not serve http://localhost:8080/snap1/index.jsp.

Integrating snaps

The interesting thing is, the host can be extended by snaps. And that can be done so that the user interface automatically adapts.
Insert the following code in the index.jsp of the host:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="snaps" uri="http://www.springsource.org/dmserver/snaps" %>

<snaps:snaps var="snaps">
 <c:forEach var="snap" items="${snaps}">
   <a href="<c:url value="${snap.contextPath}/index.jsp"/>">

To be able to compile this jsp, you need to import some packages into the bundle, namely

  • com.springsource.org.apache.taglibs.standard;version="[1.1.2,1.1.2]",
  • org.eclipse.virgo.snaps.api;version="[0.0.0,2.0.0]",
  • com.springsource.javax.servlet.jsp.jstl;version="[1.1.2,1.1.2]"
Pay attention to add the correct version ranges.
After redeploy (because you have changed the manifest, a simple JSP change is automatically hot deployed... great!), on http://localhost:8080/test/index.jsp, you are presented a list - ahem, well, with one item - of all snaps with a link to their respective index.jsp. This way, the application adapts to the current OSGi bundles state.

Eclipse Virgo + Snaps: Modular Web Apps, finally, Part 1

While looking for state-of-the-art technologies to build modular web apps, I stumbled over the Eclipse Virgo project. It is the Spring DM Server, donated to the Eclipse ecosystem. Using a prototype extension, Snaps (formerly called Slices), you can now compose a web app from code and resources distributed over many OSGi bundles. Modularization, finally!

Imagine a web application that provides you with a special feature called "Upload plugin". You would be able to write a plugin in eclipse, using APIs from that application delivered to you through other plugins. Then you could upload your new plugin and would immediately notice the extensions to the web application.

More important than the hot deployment is the standardized modularization API available. A plugin marketplace could evolve (yes, remember Eclipse plugins!) from which you could add functionality to your application even without coding! Now imagine this environment deployed into a cloud infrastructure: The ideal PaaS for java web development!

Installation and Test

  1. Download Virgo Web Server.
  2. Unzip it somewhere.
  3. Start bin/startup.sh.
  4. Goto http://localhost:8080.
  5. Play around with the admin console.
  6. Checkout git://git.eclipse.org/gitroot/virgo/org.eclipse.virgo.snaps.git
  7. Import all projects therein into Eclipse (use a fresh workspace).
  8. in snaps, say git submodule update --init (this creates content in ./virgo-build)
  9. Stop the virgo server (or tests will fail in the next step)
  10. in ./build-snaps, say ant clean clean-integration test package
  11. say cp target/package-expanded/snaps-1.0.0.BUILD-20101206191709/repository/usr/* somewhere/virgo-web-server-2.1.0.RELEASE/repository/usr/
  12. Start the server again, you should not notice big differences
  13. Now cd to ./org.eclipse.virgo.snaps.test/src/test/resources
  14. cp simple-host.war somewhere/virgo-web-server-2.1.0.RELEASE/pickup/
  15. Look into the server console and observe how the bundle is deployed
  16. Goto http://localhost:8080/simple-host only to get a "index" answer.
  17. Goto http://localhost:8080/simple-host/simple/index.jsp only to get a 404.
  18. cp simple-snap.jar somewhere/virgo-web-server-2.1.0.RELEASE/pickup/
  19. Goto http://localhost:8080/simple-host/simple/index.jsp and get an "OK" answer.
  20. You may now start and stop the simple-snap bundle in the admin console and watch the web resource appearing and disappearing.
Congratulations! - You just installed your very first really modularized web app!

What happened?

Let's first examing simple-host, the host webapp of our test. It is a pretty normal WAR file. Since OSGi R4 specifies a way to deploy WARs as bundles, Virgo is able to do that. Moreover, in the web.xml, you can find a filter called "host-filter" of class org.eclipse.virgo.snaps.core.SnapHostFilter.
The is the core component of snaps, re-routing requests for different contexts to different OSGi-bundles, called snaps.
simple-snap is an example of such a snap. Its web.xml could very well be empty (but isn't here - it contains several test resources).  Its MANIFEST.MF, besides usual entries, contains the following:
Snap-Host: simple.host;version="[1.0, 2.0)"
Snap-ContextPath: /simple
This way, a snap is tied to a specific host and has to declare under which (sub-) context it is serving resources.

In Part 2, I want to develop my first own snaps from scratch. Read on!