Email, email, tell me who’s a nice drum store


I’ll be staying in Sunnyvale next weekend after the GHOP awards ceremony, and as I need a new drumset it might be a good opportunity to shop for that.

Shipping drums from California to Switzerland is not exactly cheap, so I’m trying to find out if it’s worth buying there. Prices are usually much lower than here, especially for specials or second-hand instruments, but shipping might add up as much as $500 apparently.

I’ve been emailing a few drum stores located around Sunnyvale to find out if they arrange shipping and if they have a showroom where I could try out some drums. The replies tell me a lot about how people do business, and whether I’d want to shop there. Do they even answer? Friendly or just the bare facts and please-give-us-your-money-and-go-away? The range of replies and styles is very interesting…

In today’s world, info@ email is sometimes as important as your store front, and some businesses don’t seem to get that. Well, maybe some of them are busy enough to not care about the lone stranger passing through town, more power to them I guess.

If you read this and you have a good drum store to recommend around there, please let me know! Gelb Music in Redwood City looks good, but their website doesn’t even have a contact email - I’ll try info@.

Oxford is a beautiful city


I’ve been too lazy to take pictures of my trip to Oxford earlier this week, but Steve has them - lovely.

JCR Tools Roundup

There is a new kid on the block of (explorer-like) JCR tools: Craig Ching is currently developing a web browser-based application to visualize and edit contents of a Java Content Repository. The application is built upon the Dojo Toolkit and Apache Sling. It will probably make it into the standard Sling releases at some point (see the discussion on the mailing list).

Sling JCR Explorer is not quite ready for production use, but you can find a demo version here (today the site seems to be down, unfortunately). The nice use of Dojo's AJAX capabilities makes it indeed a worth a look.

I welcome this latest addition to the JCR tools arsenal as I do strongly believe that a good set of developer tools is essential for further adoption of JCR. In this context I have compiled a list of JCR tools for browsing repositories that I am aware of. I refrained from doing proper reviews since I am not really impartial. Please find the list below and leave a comment In case I missed a tool.

Web-based tools

CRX Explorer

The tool I spend most of my time with is Day's CRX Explorer that comes bundled with CRX and CRX Quickstart. Rumor has it that CRX Explorer might make its way into the Jackrabbit project.

JCR-Explorer

Hendrik Beck has developed a similar and feature-rich web-based application named JCR-Explorer. One particular useful feature is the ability to observe ongoing changes in the repository (leveraging JCR's observation features).

Hendrik used JSF (JBoss RichFaces) to build JCR-Explorer. It is open-sourced under the Apache License.

Eclipse-based tools

Day's Eclipse plugin

Day has provided an Eclipse plugin to connect to and manipulate Jackrabbit or CRX-based Content Repositories. The plugin can easily be installed through Eclipse's Update Manager. See the plugin's home page for instructions.

Nodes can be edited and changes be commited one by one. A full list of features is available in Eclipse's Help section once the plugion is installed (for the Catch-22 fans: there is also a section on how to install).

JCR Browser

Sandro Böhme has also written an Eclipse Plugin for viewing (but not editing) JCRs and open-sourced it under the Apache License.

In the project's own words:

Visualizes the content of a JSR 170 compliant Java content repository in Eclipse. It focuses on reliability by keeping the scope on displaying the content.

JCR Viewer

A second Eclipse Plugin focused on simply displaying nodes is Shailesh Mangal's appropriately named JCR Viewer. It seems to have been a by-product of developing the test management tool Zephyr which is based on JCR.

The binaries are available from his blog.

Others

JCR Controller

Jacco van Weert has developed a repository browser as a Java Web Start application (as such it sits somewhere inbetween web-based and Eclipse-based solutions).

JCR Controller is open sourced (LGPL license) and available at Sourceforge. To see it in action check out the project's home page.

[ANN] Day Knowledge Base

I am happy to announce Day KB, the new source of Day product information and answers to common technical questions.

KB is a Wiki space that contains questions and their answers to common issues users run into when developing or authoring with our products. The basis for the existing content came out of Daycare tickets (that were reviewed and scrubbed to remove private information). New content will be added regularly by KB moderators. Please provide your ideas for new topics and articles, plus any feedback to the Day KB moderators at kb@day.com

Go to dev.day.com/kb, for the open access CRX space. From there, Day customers can log in to the Communiqué space with their existing docs.day.com user ID and password.

Screencast Errata

Before Sling was released there was a change in the way Sling finds application files (e.g. .jst or .esp). While this made things easier it also broke the examples I presented in the screencasts here and here. So here is some update information on how to fix this:

The first screencast's code is included as an example application with CRX Quickstart. So if you just stick to the example app structure you will be fine.

For the second screencast we started out with a directory like this (leaving out the image folder):

tss
|-index.html
|-admin
  |-index.html
|-post
  |-index.html
|-thread
  |-index.html

and ended up (after the code was changed in the course of the screencast) with:

tss
|-index.jst
|-admin
  |-index.jst
|-post
  |-index.jst
|-thread
  |-index.jst

Now, in the current version the final directory structure must be:

tss
|-html.jst (this was the home page)
|-admin.jst
|-post.jst
|-thread.jst

So, for example in the first step I rename tss/admin/index.html to tss/admin/index.jst. Now, it should be renamed and moved to tss/admin.jst and so on. For clarity, I have attached the new resulting code to this post.

On Day and Open Source

Following up to my statement that Day is closely related with the open source community I have compiled some facts to support this claim in this post. Broadly speaking Day's support for open source software and open standards can be divided into four areas:

1. Day Developers are OSS Developers

Day's developers are have contributed to a wide range of open source projects (either as part of their employment, in their spare time or before joining Day). The numbers are:

2. Work at the Apache Software Foundation

Day's developers contribute to the Apache Software Foundation (ASF) in a number of ways:

  • Day's Chief Scientist Dr. Roy T. Fielding is co-founder of the ASF and its former chairman.

  • Day developer Bertrand Delacretaz has been elected as one of nine members of the ASF's Board of Directors.

  • The ASF currently has 267 formally elected members of the nonprofit foundation. Membership is by invitation only. Candidates for membership are proposed by existing members, and voted upon by the existing membership. At the moment of those 267 members ten are Day employees.

  • Officers of The Apache Software Foundation oversee the day-to-day operations of the Foundation. The V.P.s are assigned to specific projects of the ASF. Currently, there are three V.Ps. that are Day employees: Roy T. Fielding (Apache HTTP Server), Jukka Zitting (Apache Jackrabbit) and Carsten Ziegeler (Apache Excalibur)

3. Open Source Projects

Day's commercial products for content management and content infrastructure are in their core based on two open source projects: the content repository Apache Jackrabbit and the web framework Apache Sling.

Day's developers have contributed to Jackrabbit's code base and also actively take part in the community (especially on Jackrabbit's mailing lists). As a company Day offers commercial services for Jackrabbit like consulting or implementation of customer-specific features.

Apache Sling is a web framework built upon the REST architectural style. In November 2007 Sling was open sourced. Previously, it was an internal project at Day. Hence, a very large part of the code base has so far been written by Day's developers.

Although Sling is a young project it has already won an award at Jax's innovation awards. Moreover, the OSGi console for managing OSGi bundles that was developed within the Sling project has been handed over to Apache's OSGi project Felix.

4. Open Standards

Open source software and open standards are related. Therefore, Day's employees actively contribute to the specification of open standards:

  • Day's CTO David Nüscheler has led the specification JSR-170 for Java Content Repositories (JCR). JCRs have gained broad acceptance in the open source community: there are four different open source implementation of the standard already. David is currently working on the successor JSR-283.

  • Chief Scientist Roy Fielding authored the standards for URIs (RFC 3986/STD 66) and HTTP (RFC 1945, 2068, 2616), and also contributed to early HTML (RFC 1866).

In this context one should also mention Roy's work on the REST architectural style. It is not a standard in itself, but serves as a blueprint for information architectures that are based on open standards.

[LOTD] Mule, APP, JCR

Mule Galaxy 1.0 has been released 2 days ago. It is (in their own words)...

an open source governance platform with an integrated registry/repository. It includes versioning, lifecycle management, dependency management and policy enforcement features which enable you to effectively govern your applications and services

Galaxy uses JCR (Apache Jackrabbit) internally and Atom Publishing Protocol for custom integrations. As such it constitutes a nice example for JCR and APP complementing each other.

Another comment that is only slightly related: I just came across Galaxy developer Dan Diephouse's presentations on Effective RESTful services and AtomPub. Excellent stuff (and slide 40 of the first one made me lol).

Extending JCR with JRuby

Working on a JRuby script that accesses a Java Content Repository I was missing a method on javax.jcr.Node that would return the whole subtree of child nodes. Ruby and the JRuby implementation allow to re-open classes and add new code. In that way one can easily extend even core classes (or interfaces as in this case):

JavaUtilities.extend_proxy("javax.jcr.Node") do
  def getAllNodes
	all = Array.new
	children = self.getNodes
	children.each {|child| all.push(child);
	             all.push(child.getAllNodes)}
	all.flatten
  end
end

This extends regular JCR nodes with a method getAllNodes that returns a flat array of all child nodes. Speaking of fixing issues one might have with existing objects: recently, I was unhappy with the fact that repository.getDescriptor( Repository.OPTION_OBSERVATION_SUPPORTED) returns a String instead of a Boolean because it makes me write code like:

if (repository.getDescriptor(
  Repository.OPTION_OBSERVATION_SUPPORTED)
  .equals("true"))

The fix is obviously:

JavaUtilities.extend_proxy("javax.jcr.Repository") do
  def getRealDescriptor(name)
    if self.getDescriptor(name) == "true" ||
      self.getDescriptor(name) == "false"
      self.getDescriptor(name) == "true"
    else
      self.getDescriptor(name)
    end		
  end
end

(Actually I wanted to use alias_method to redefine getDescriptor instead of defining a new method, but could not figure out how to do this on an interface. If you know it, please leave a comment.)

Sling Presentation at Webtuesday

Hugo Schottmann has posted on his blog a video of David Nüscheler's presentation about Apache Sling at Webtuesday in Zurich.

Why I love unixish configs


I wrote this today while discussing configuration mechanisms with my colleagues.

I love the unixish way of configurating things because the configs are:

Discoverable
With find, xargs and grep I can (very often) find out where something
is configured in my unixish system, with minimal initial knowledge.
Commentable
It is easy to add comments to configuration items in a text-based
config, and comments are not mangled when that config is later
modified from a GUI, if that’s available.

Cloneable
Copying the right config files from one system to another allows
configs to be cloned.

Traceable
By putting my configs under subversion control, I know what happened to them.
Documentable
Processing my configs with simple tools allows me to create reports or
dashboards easily.

The opposite of this is the M$ hell of opaque configurations managed by (sometimes even more opaque) GUIs, and unfortunately Sling leans more towards that opposite at the moment. We’ll have to fix this.

[ANN] Sling Released

The first release of Apache Sling is available. Please see Carsten Ziegeler's announcement on Sling's mailing list and on TheServerSide where a little discussion emerged.

Congratulations to the developers!

Tracking Request Processing in Sling

Have you ever wondered what is going on with the client requests sent to a Sling based application and what Sling is doing in the background so that you can worry about your primary job, the Web based application you are building? Have you been tasked to find out, why your latest super Web based application suffers from performance degradation from time to time?

In case you are tempted to answer the above questions with a firm yes I think you will be happy to hear that the days of implementing a tracker over and over again in each new project has gone. With Sling you get a tracker for request processing for free and out of the box: The RequestProgressTracker.

Sling creates such a RequestProgressTracker instance for each request being processed and also uses it to track various processing steps like resource and servlet/script resolution. You may add your own logging and tracking to this instance and at the end of the request dump it either into your HTML response or have it written to the log file or to a real filesystem file or to the JCR repository or wherever you like.

Functionality of the RequestProgressTracker

First things first: What can we do with this tracker ? This is a simple question to answer. These are the API methods of the RequestProgressTracker:

  • Logging simple and formatted messages. This is mainly used to mark some state during request processing. A message added to the internal log of messages together with a time stamp.
  • Timing sections of request processing. Timing parts of request processing consists of two steps: First you start a (named) timer before the part to be timed and after that part you log the timer by the same name.
  • Get all messages. If you want to process the logged messages yourself, e.g. to write them to a file or the JCR repository.
  • Dump all messages to a java.io.PrintWriter. If you just want to add the request progress information to your generated HTML page as an HTML comment, for example.
Show Me an Example

Let's go. Let us explore a very simple example of just dumping the contents of the tracker. First launch Sling - this can be as easy as just running the Sling Standaline Application you get from the Apache Sling Downloads page.

After downloading and unpacking the Sling Standalone application, open a command shell and change to the directory of the unpacked org.apache.sling.launchpad.app-3-incubator.jar file and launch it with:

$ java -jar org.apache.sling.launchpad.app-3-incubator.jar -p 8888 -f -

The argument "-p 8888" instructs Sling to listen on port 8888. You may change this to any free port you like. The default port is 8080. The argument "-f -" causes log messages to be written to the standard output. This is very convenient for development. By default log messages go to the logs/error.log file in the Sling Home directory (sling by default). To get a list and short explanation on available command line options, use the parameter "-h".

Next connect Sling using WebDAV and create a folder /apps/sling/nonexisting and in that folder create a file GET.esp with the following contents:

<%
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");

request.requestProgressTracker.dump(response.writer);
%>

Now in your browser request a resource which you know is not existing. For example in a fresh installation of Sling, there is no resource at /missing.txt. So requesting that will give you the following response (line numbers added by the author):

 1:      0 (2008-06-18 10:18:26) Starting Request Processing
 2:      0 (2008-06-18 10:18:26) Starting ResourceResolution
 3:      0 (2008-06-18 10:18:26) URI=/missing.txt resolves to Resource=NonExistingResource, path=/missing.txt, elapsed = 0ms
 4:      0 (2008-06-18 10:18:26) Starting ServletResolution
 5:      0 (2008-06-18 10:18:26) Starting resolverServlet(NonExistingResource, path=/missing.txt)
 6:      5 (2008-06-18 10:18:26) Using Servlet /apps/sling/nonexisting/GET.esp, elapsed = 5ms
 7:      5 (2008-06-18 10:18:26) URI=/missing.txt handled by Servlet=Script /apps/sling/nonexisting/GET.esp, elapsed = 5ms
 8:      5 (2008-06-18 10:18:26) Starting /apps/sling/nonexisting/GET.esp#0
 9:     13 (2008-06-18 10:18:26) Dumping SlingRequestProgressTracker Entries, elapsed = 13ms

As you can see from this simple dump resolving the addressed resource took an unmeasurable amount of time (0 milliseconds, line 3). Next you see, that resolution of the script took another 5 milliseconds (line 7) and finally running the script from the point of the call upto the point of requesting the dump used 8 milliseconds.

Further you see normal log entries like the one on line 9 and timer related messages on the other lines: Lines 1, 2, 4, 5 and 8 marking timer starts and the other lines 3, 6 and 7 marking timing points.

You may notice that the timer "/apps/sling/nonexisting/GET.esp#0" is only dumped when started but not when terminated. The reason for this is of course, that the timer is only logged when the script has finished but we dump the log before the script has terminated. Hence this log entry has not been added yet.

This example also shows you nicely how resource resolution and script resolution work hand-in-hand: The request to /missing.txt could not be resolved to an actual JCR Node, so the resource resolver created a so-called NonExistingResource whose resource type is set to sling:nonexisting. This resource type is then used to resolve the script /apps/sling/nonexisting/GET.esp. As you can see the resource sling:nonexisting type has been converted to the (relative) path sling/nonexisting which is then used for the script resolution.

Log Dump Method
  • dump(PrintWriter writer) -- Write all log messages to the given java.io.PrintWriter.
Logging Your Own Entries

The first example above contained only messages added by Sling itself, lets add some messages of our own now into the log. To this avail we change the GET.esp script as follows:

<%
request.requestProgressTracker.log("Starting Script Execution");

request.requestProgressTracker.log("Script {0} of type {1}",
        sling.script.scriptResource.path,
        sling.script.scriptResource.getResourceType());


response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");

request.requestProgressTracker.log("End Of Script Execution");

request.requestProgressTracker.dump(response.writer);
%>

We added three logging statements: Two statements with a fixed message and a third statement with a java.text.MessageFormat format string and its associated parameters. The output of this script when requesting the /missing.txt resource again is as follows (line numbers added by the author):

 1:      0 (2008-06-18 10:22:28) Starting Request Processing
 2:      0 (2008-06-18 10:22:28) Starting ResourceResolution
 3:      1 (2008-06-18 10:22:28) URI=/missing.txt resolves to Resource=NonExistingResource, path=/missing.txt, elapsed = 1ms
 4:      1 (2008-06-18 10:22:28) Starting ServletResolution
 5:      1 (2008-06-18 10:22:28) Starting resolverServlet(NonExistingResource, path=/missing.txt)
 6:      4 (2008-06-18 10:22:28) Using Servlet /apps/sling/nonexisting/GET.esp, elapsed = 3ms
 7:      4 (2008-06-18 10:22:28) URI=/missing.txt handled by Servlet=Script /apps/sling/nonexisting/GET.esp, elapsed = 3ms
 8:      4 (2008-06-18 10:22:28) Starting /apps/sling/nonexisting/GET.esp#0
 9:     13 (2008-06-18 10:22:28) Starting Script Execution
10:     13 (2008-06-18 10:22:28) Script /apps/sling/nonexisting/GET.esp of type nt:file
11:     13 (2008-06-18 10:22:28) End Of Script Execution
12:     13 (2008-06-18 10:22:28) Dumping SlingRequestProgressTracker Entries, elapsed = 13ms

You will see the three log statements we added in the lines 9-11. Note especially the message on line 10, which formats the message by replacing the respective call parameters.

Logging Methods
  • log(String message) -- Log this exact message
  • log(String format, Object... args) -- Log a message which is constructed from applying the arguments args to the java.text.MessageFormat pattern format.
Timing Sections of the Script

Sometimes you might suspect timing issues in the scripts you have written and you want to see where all these CPU cycles are being burnt. Here comes the timer support the ResourceProgressTracker. The tracker allows for a virtually unlimited number of named timers. A timer is created or reset by calling the startTimer(String) method and the time ellapsed since the last timer start can be logged by calling any of the logTimer methods.

Let's see the timer functionality in action. Thus we adapt our GET.esp to add a timer:

<%
request.requestProgressTracker.startTimer("test");

request.requestProgressTracker.log("Script {0} of type {1}",
        sling.script.scriptResource.path,
        sling.script.scriptResource.getResourceType());


response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");

request.requestProgressTracker.logTimer("test");

request.requestProgressTracker.dump(response.writer);
%>

Here we define a timer named test and get the following output (line numbers added by the author):

 1:      0 (2008-06-18 11:11:39) Starting Request Processing
 2:      0 (2008-06-18 11:11:39) Starting ResourceResolution
 3:      1 (2008-06-18 11:11:39) URI=/missing.txt resolves to Resource=NonExistingResource, path=/missing.txt, elapsed = 1ms
 4:      1 (2008-06-18 11:11:39) Starting ServletResolution
 5:      1 (2008-06-18 11:11:39) Starting resolverServlet(NonExistingResource, path=/missing.txt)
 6:      5 (2008-06-18 11:11:39) Using Servlet /apps/sling/nonexisting/GET.esp, elapsed = 4ms
 7:      6 (2008-06-18 11:11:39) URI=/missing.txt handled by Servlet=Script /apps/sling/nonexisting/GET.esp, elapsed = 5ms
 8:      6 (2008-06-18 11:11:39) Starting /apps/sling/nonexisting/GET.esp#0
 9:     12 (2008-06-18 11:11:39) Starting test
10:     13 (2008-06-18 11:11:39) Script /apps/sling/nonexisting/GET.esp of type nt:file
11:     13 (2008-06-18 11:11:39) test, elapsed = 1ms
12:     13 (2008-06-18 11:11:39) Dumping SlingRequestProgressTracker Entries, elapsed = 13ms

In the dumped log you find the entry for the timer start in line 9 and the entry for logging the elapsed time of the named timer in line 11. In our example we used the simple method of logging by just supplying the timer name to the logTimer(String) method. You may log a more elaborate message with the logTimer(String, String, Object...) method, which is also used by Sling to log timings for the resource and script resolution

Timer Methods
  • startTimer(String timerName) -- Start a timer with the given name. If a timer with the same name already exists it is reset to zero.
  • logTimer(String timerName) -- Logs the number of milliseconds elapsed since the named timer was last started. The name of the timer is used as the log message.
  • logTimer(String timerName, String format, Object... args) -- Logs the number of milliseconds elapsed since the named timer was last started with a message constructed by applying the args parameters to the MessageFormat pattern format.

Please note that only the startTimer method resets the timer to zero. The logTimer methods just log the number of milliseconds elapsed. Therefore these latter methods may also be called multiple times to log the increase of elapsed time.

Wrap-Up

In the previous sections you have seen how easy it is to use the RequestProgressTracker provided by Sling to track the processing of any requests. In this wrap-up I want to present three more bullet points with respect to the request progress tracker.

Helper Methods
  • getMessages() -- Return all messages from the request progress tracker as an java.util.Iterator of Strings. This method may be used if you want to handle the logged messages other than just dumping them to some PrintWriter.
  • done() -- This may be called to log a terminating message. Currently this method has no other effect.
Automatic Logging of Messages

Sling includes a request filter, which dumps the request progress tracker to using a logger with name org.apache.sling.engine.impl.debug.RequestProgressTrackerLogFilter at debug level. To log the request progress tracker messages to a log file just configure this logger for the debug log level.

Beautiful words at Wordle


wordle-bd.250.jpgWordle creates beautiful word clouds from text that you supply.

Via Bruno Giussani who’s got more examples.

Speaking at Jazoon next week

If you are following dev.day.com you have probably seen it already: I will speak next Wednesday at Jazoon conference in Zürich about REST, AJAX and WebForms 2.0. If you are interested in building interactive and standards-compliant web sites and web applications, I would be happy to meet you there.

Btw. I originally planned to call this post "Ten reasons why you will hate not being in Zürich next week", but I decided one uber-catchy headline per week is enough.

[ANN] Meet us at Jazoon

The large international Java conference Jazoon is soon to start. Jazoon takes place end of June in Zurich, Switzerland. There will be six presentations given by speakers from Day. Hope to see you there:

Roy Fielding: Open Architecture

Keynote speech, Wednesday, 2008/06/25, 09:30-10:30, Arena 5

At the heart of most successful open source projects is an emphasis on open architecture -- at least one mechanism that allows the product to be utilized as a support network for unanticipated extensions and independently motivated functionality. Such extensibility mechanisms allow an open source project to decentralize its evolution and take advantage of Internet-scale collaboration. However, they can also be a source for unnecessary complexity and hidden barriers to entry.

Representational State Transfer (REST) is an architectural style that I developed to describe and redefine the World Wide Web. The essential constraints of REST are designed to promote the development of open architectures within Web-based applications, such that the resulting resources are reusable across independently developed systems (today, we call these "MashUps"). The same principles can be used to design other open architectures, though not necessarily with the same constraints. This talk will focus on applying principled design techniques to the design of open architectures, as demonstrated by various examples from successful open source projects.

Peeter Piegaze: The Next Content Repository: A sneak peek at the upcoming JCR 2.0

Technical long talk 50 min, Wednesday, 2008/06/25, 12:00 - 12:50, Arena 9

The Story So Far

  • JCR 1.0 a quick recap

  • JCR 1.0 successes

  • JCR 1.0 lessons learned

Goals of JCR 2.0
  • Expose new functionality for JCR-from-scratch repositories

  • Better expose functions of existing legacy repositories through JCR

  • Simplify complex features

Major Features and Changes
Node Identifiers
  • More flexible constraints

Metadata
  • Standardizing metadata node types

Observation
  • Two semantic levels of event reporting: state-change and method

  • Journaling

Simplified Versioning
  • Simple and full versioning options

Shareable Nodes
  • enabling multi-filing without breaking the workspace tree semantics

Query
  • Abstract Query Model allows multiple equivalent syntaxes

  • Java bindings and SQL bindings

  • XPath bindings and more

Node Type Management
  • Creating and registering node types

Access control management
  • Access control discovery

  • Access control policies

  • Access control entries

Lars Trieloff: Creating RESTful Web Applications with AJAX and Web Forms 2.0

Technical long talk 50 min, Wednesday, 2008/06/25, 16:30 - 17:20, Arena 5

The talk will have following structure: Introduce the concepts REST, AJAX and Web Forms 2.0 first, then provide hands-on-examples on building applications using these concepts. REST is a principle of creating large-scale internet applications and is seen by many developers as the way to go for creating web applications. The problem with real-world REST application however is that current web browsers only implement a subset of the HTTP specification that makes it hard to create true RESTful applications that work in a web browser. AJAX is a way of creating highly dynamic web applications that use Javascript and client-side DOM manipulations for interaction with the user and background HTTP request in XML or JSON for real-time-interaction with the browser. Combining AJAX and REST allows the creation of rich internet applications running in the browser that follow the REST principles. Web Forms 2.0 is an emerging web standard that tries to overcome some limitations with classical forms in HTML pages that are today the standard way of user interaction in web applications. Web Forms 2.0 add concepts like form field repetition, different transport encodings and validation. As long as only a small fraction of web browsers support Web Forms 2.0, implementing Web Forms 2.0 with AJAX is an elegant solution for creating standards-based web applications. In the practical part of the presentation concrete coding examples of creating RESTful web applications using Web Forms 2.0 will be given. The frameworks involved in this example session will be Apache Sling, a web-framework that combines concepts of REST, server-side scripting, OSGi and JCR and the Dojo Toolkit, a powerful collection of Javascript APIs that allow the creation of widget-based applications that run in a web browser. Apache Sling is an incubating project of the Apache Software Foundation.

David Nüscheler: Content Integration: Java(tm) Applications vs. Microsoft(R) Sharepoint

Technical long talk 50 min, Wednesday, 2008/06/25, 17:30 - 18:20, Arena 9

Most large organizations on the one hand develop Java(tm) Applications and on the other hand run Microsoft(R) Sharepoint for their business users.

This generates the crucial need for Java Applications to be able to interact with content stored in Sharepoint, be it a Java based Swing Application that would like to refer to content managed by Sharepoint or a regular Intranet WebApp or Java Portlet that needs to search and manage office content residing in Sharepoint.

This session will talk about the benefits and drawbacks of various ways of integrating Java applications and Sharepoint.

This session will also demo and showcase the integration of both J2SE and J2EE applications through a quick and easy to use standards based integration.

The goal of this session is to demonstrate in a practical fashion how to integrate with Microsoft Sharepoint at a Content Repository level using a "Content Repository API for Java(tm) Technology" (aka JSR-170) connector to build a Java application in a very agile fashion.

Expect a hands-on demo of the installation and deployment of a JSR-170 based Sharepoint Connector and the development of a simple JSR-170 based application and the use of an existing JSR-170 based application backed by content from Microsoft Sharepoint.

Agenda:
(1) Content Integration: A Business Issue
(2) Java vs. Microsoft Sharepoint
(3) Various Integration Options Pro/Cons
(4) Integration Demo using the "Content Repository API for Java(tm) Technology"
(5) Q&A

David Nüscheler and Bertrand Delacrétaz: The Revenge of the "Weblog in 15 minutes"

Technical long talk 50 min, Thursday, 2008/06/26, 12:00 - 12:50, Arena 5

Based on last years successful Jazoon session on how to build a "Weblog in 15 minutes" using AJAX and JCR, this talk is the sequel in the "AJAX meets JCR" series.

In the meantime microjax has become a legitimate part of the Apache Sling project which is at the time of this submission in incubation.

This talk will focus on the unique benefits of using a combination of AJAX and JCR (aka. JSR-170 & JSR-283) to satisfy modern Web 2.0 application requirements and allow for an extremely agile application development.

To take last years "15-minute weblog" example to the next level we will talk about how microjax effortlessly complies with the real-life requirements of Search Engine Optimization (SEO), Back-button, Deep Links, WAI, Access Control, XSS protection, etc...

This session will be interesting for an audience that works in a general J2EE environment and is eager to learn how to build Web2.0 Applications in a very efficient way without leaving the traditional heavy-weight j2ee style backend resources.

The session overview looks as follows:

(1) The JCR elevator pitch
(2) microsling - JCR and AJAX
(3) The revenge of the microjax "weblog"
(4) The real-life: SEO, WAI, Backbutton, XSS, Access Control
(5) Q&A

Thomas Mueller: Java SQL Databases

Technical short talk 20 min, Thursday, 2008/06/26, 11:00 - 11:20, Arena 3

This talk is about what persistence mechanism to chose for your Java application, and what to consider when you decided to use a SQL database as your backend. The focus of this presentation is open source Java databases. One of those, the H2 Database Engine, is developed by the speaker.

The API is one aspect of the persistence mechanism. Standardized high level APIs are the JPA (Java Persistence API), the JDBC API (Java Database Connectivity), and the JCR (Java Content Repository) API. Each API has advantages and disadvantages. Other APIs exist as well, but are less used (such as JDO) or are proprietary. Proprietary APIs will result in substantial cost when switching to another product to overcome the vendor lock-in (for example when using db4o).

If you have decided to use a SQL database as the backend, you need to think about which products fit your use case best. The main factors factors to consider are: cost, stability, security, features, performance, ease-of-use, support, and documentation. Sometimes, you will want to support multiple products: one for development and unit testing, and another (or multiple) for production.

If you already purchased a SQL database, for example Oracle or MS SQL Server, you may want to use it for production. If not, the cost of such products can be avoided by using free databases like PostgreSQL, or MySQL (which is not free in all cases). There is also a number of Java databases, most of them are free.

Some think that Java still is slow, and a fast database can not be written in Java. However Java is no longer slow. Additionally, there is no network overhead when accessing Java databases from Java applications in embedded mode. Therefore, Java databases are much faster than other database in many situations.

The main open source Java databases today are HSQLDB, Apache Derby, and H2. There are other Java databases, but some are not free (PointBase), and others not updated since a long time (McKoi, DaffodilDb/One$Db, Quadcap). HSQLDB, Derby and H2 are quite different. According to Ohloh, HSQLDB is the most popular one, followed by Derby and H2. The reason is probably that HSQLDB is the open source since a long time, Derby since 2004, and H2 since the end of 2005.

HSQLDB is based on Hypersonic SQL, which was developed by the author of H2. It is now maintained by a group of people headed by Fred Toussi in England. A commercial version of HSQLDB is available as well. HSQLDB is popular because of its speed. However it does lack a few features such as locking and transaction isolation. HSQLDB is bundled with OpenOffice Base. Many use HSQLDB for testing. However, more complex queries can be very slow in HSQLDB because the query optimizer does not consider different access strategies. There is no ODBC driver for HSQLDB.

The history of Apache Derby goes back to 1996. Cloudscape was bought by Informix in 1999, which was bought by IBM in 2001, and then contributed to Apache in 2004. IBM stopped selling Cloudscape in 2007 and will stop support in September 2008. However most Derby developers are employed by IBM. Sun offers commercial support for Java Db, which is basically Derby. Since 2007 IBM owns PointBase, the second commercial Java database. Derby offers a rich feature set. The optimizer usually chooses a good query plan. The main disadvantage is the slow performance for simple use cases (up to 10 times slower than HSQLDB or H2).

The development of H2 was started in 2004, but it was first published in December 2005. The author of H2, Thomas Mueller, is also the original developer of Hypersonic SQL. In 2001, he joined PointBase Inc. where he wrote PointBase Micro. At that point, he had to discontinue Hypersonic SQL, but then the HSQLDB Group was formed to continued to work on the Hypersonic SQL codebase. The name H2 stands for Hypersonic 2; however H2 is built from scratch. H2 is feature rich and fast. The main disadvantages are: it is relatively new, and there is no commercial support as of today.

Talking at Jazoon, Zürich, next week


jazoon.jpgI’ll be talking as a co-speaker with David Nuescheler at Jazoon next thursday, on the revenge of the weblog in 15 minutes. The talk description still mentions microjax, but that’s dead, it’s the Sling client library now. No conceptual changes though, that’s mostly a renaming.

I’m working on the Sling JST templates this week, as the code that this template engine generated was way too ugly to be shown in public. That’s getting better.

code_swarm - open source like you’ve never seen it before


httpd-video.jpgMichael Ogawa has created stunning videos showing animated commit activity for various open source projects.

Watching one where you know something about the people and history is fascinating - for me it’s obviously the one about the Apache HTTP server.

Via Sander Temme.

European Tech Summit 08

Day's European Tech Summit 08 took place in Basel a couple of days ago. If you could not make it there find some of the presentations below.


Gilles Metz: Support Initiative 08


Lars Trieloff: Getting into the Flow with CQ DAM


Lars Trieloff: Advanced Collaboration and Beyond


David Nüscheler: Non CMS Web Apps


Honwai Wong: TAR PM & Clustering


Jean-Michel Pittet: CQ WCM and Connectors


Honwai Wong: Top 2 Support - Dispatcher & Out of Memory


Seven reasons why FriendFeed sucks

Well, FriendFeed does not really suck, it has managed to convert me from a naysayer to fanboy (I think writing userscripts and user-css qualifies me as a fanboy) by giving me a communication platform that allows me to interact with my peers, but now that I have your attention, I would like to tell you five things where FriendFeed actually needs improvements. If you are on FriendFeed, feel free to like or comment this post to bring it to the attention of FriendFeed's product managers.
  1. no feed for daily, weekly and monthly toplinks: Friendfeed introduced a new feature, daily toplinks only few days ago and while it is insanely cool to have use your FriendFeed contacts as a personal attention filter and aggregator, I do not like the fact that there is no Atom or RSS feed for it. Come on, this thing is called FriendFeed, so you must be aware that there is a thing called feeds in the interwebs.
  2. no link-based aggregation: if one person posts a link twice in separate services, for instance directly on FriendFeed via Mento and later to del.icio.us, it will show up twice in the Feed, leading to clutter and noise (not the smart noise we are looking for at FriendFeed) in the feed and finally to a fragmentation of the discussion, as I have to chose which entry I like or comment. As a second example, if someone in my network posts a link that someone else posted as well, we have the same situation: two links, two discussions, two sets of likes. An easy solution would be a add a "also posted at ..., also posted by ..." line next to the list of people that liked a post. This way you could reduce clutter and join conversations that spread across multiple postings.
  3. bad recommendations for contacts: FriendFeed is a superb implementation of the "Activity feed" pattern of social networking, but its social networking capabilities are mediocre at best. Example number one: FriendFeed's recommended friends dialog suggests that I should subscribe to Dave Winer, Jason Calacanis, Leo Laporte, Loic Le Meur, Michael Arrington, Robert Scoble, Steve Rubel and some of the FriendFeed founders. While I think they are surely great people and I could learn a lot from them, it is too much information to handle (I tried to follow these suggestions, and removed them one by one later). Additionally as soon as they write something that is interesting for someone in my network, it will appear in my feed as well, which is a great feature. The only problem is: the recommended friends page does not make any sense if it is just a list of the top-users at FriendFeed. What I need are reasons to subscribe like: many of my important (measured in likes and comments) friends find them important (measured in likes and comments) as well.
  4. not notifying me when friends join: I wish everyone I know would be on FriendFeed. Unfortunately this will not happen and I will also not send an email requesting them to join yet another social network, because I know how distracting this would be for most of my contacts. However, I wish there were tools to make it a bit easier for me: If someone joins who has an e-mail address that was found in my address book before, please inform me. If someone adds a feed or a service that matches an imaginary friend that I created, please inform me. If you can read my address book, why can't you offer me to automatically create imaginary friends for my flickr, twitter, etc. contacts?
  5. bad Facebook integration: Like it or not, Facebook is popular. But FriendFeed's Facebook application is a joke. It is simply FriendFeed in an IFrame, but I cannot see which of my Facebook friends are on FriendFeed, I cannot invite them as it is possible with other social applications that offer Facebook integration. Probably the best example for this is dopplr.com which is a champion of social network interoperability. Another point in case that FriendFeed's social networking capabilities need some work.
  6. bad customer service at getsatisfaction.com: FriendFeed managed to move conversations from the blog comments to FriendFeed. Some bloggers objected, but that's the way it works. Conversations move and if you would like to take part in the conversation, you have to follow. The best place for customer care (and conversations with users of your product) today is getsatisfaction.com. There is a room for ~FriendFeed at getsatisfaction.com, but FriendFeed is not listening. As I am sure these guys know that they have to take part in the conversation where it happens, and I am also sure they know that customer service is part of the product design, it looks like they do not want to listen, because it does not matter to them.
  7. no search for URLs: Early adopters and developers are craving to integrate FriendFeed with their tools and services they use. The main integration point, the most important social object is content and content is identified by an URL in the web, yet FriendFeed's advanced search (and API) does not allow searches for URLs. This means, people looking to integrate FriendFeed with their blogs, using FriendFeed from Yahoo! Pipes or creating Mashups with FriendFeed are left out in the rain.
These are the most important changes and improvements I am looking forward at FriendFeed, not the addition of six (or sixty) more social networks. Improve the features you already have, improve search, improve social networking, improve aggregation and improve integration and I will be happy.

Groovy-JCR Object-Content-Mapping

Christian Sprecher who wrote about JCR and Groovy on dev.day.com in January has released some code for Groovy/JCR Object-Content-Mapping on Google code. It is used like this:

def myBeer = Beer.get("Ueli Bier")
myBeer.taste = "excellent"
myBeer.save()

This would persist the myBeer POGO (plain old Groovy object) in the underlying Java Content Repository. Cool (and it presumably works with other types of beer as well).

The objects that shall be persisted must have a key so that they can be retrieved again. If an object has a reference to another one it will be persisted as well:

class A {
        B myB
        def key
}

class B {
        def alsoKey
}

B b = new B(alsoKey:"I am b's key")

A a = new A(key: "I am a's key", myB: b)

a.save()
// not needed: b.save() 

The project is pre-alpha, but it is certainly promising.

Speaking of Groovy: a project has been started to optionally swap out the RDBMS backend Grails is using and plug in a JCR backend (some code is here: https://svn.codehaus.org/grails-plugins/grails-jcr/). I am looking forward to see more from that!

PS: I cannot resist the urge to point to the nice Freudian slip in the project's tag line (spotted by Dierk Koenig).

Corporate self-sabotage

CMSWatch has pointed to such an unbelievably funny classic: the OSS Simple Sabotage Manual from 1944 (OSS is the Office of Strategic Services, predecessor to the CIA). Check it out here.

You will learn how your cooperation is sabotaged:

(1) Insist on doing everything through "channels." Never permit short-cuts to be taken in order to expedite decisions.
(2) Make "speeches." Talk as frequently as possible and at great length. Illustrate your "points" by long anecdotes and accounts of personal
experiences. Never hesitate to make a few appropriate "patriotic" comments.
(3) When possible, refer all matters to committees, for "further study and consideration."
Attempt to make the committees as large as possible — never less than five.
(4) Bring up irrelevant issues as frequently as possible.
(5) Haggle over precise wordings of communications,
minutes, resolutions.
(6) Refer back to matters decided upon at the last meeting and attempt to re-open the question of the advisability of that decision.
(7) Advocate "caution." Be "reasonable" and urge your fellow-conferees to be "reasonable" and avoid haste which might result in embarrassments or difficulties later on.
(8) Be worried about the propriety of any decision — raise the question of whether such action as is contemplated lies within the jurisdiction
of the group or whether it might conflict with the policy of some higher echelon.


The document also shows quite clearly that some allied spies must still be working for Germany's train company:

(6) Transportation: Railways
(a) Passengers
(1) Make train travel as inconvenient as possible for enemy personnel. Make mistakes in issuing train tickets, leaving portions of the journey uncovered by the ticket book; issue two tickets for the same seat in the train, so that an interesting argument will result; near train time, instead of issuing printed tickets write them out slowly by hand, prolonging the process until the train is nearly ready to leave or has left the station. On station bulletin boards announcing train arrivals and departures, see that false and misleading information is given about trains bound for enemy destinations.
(2) In trains bound for enemy destinations, attendants should make life as uncomfortable as possible for passengers. See that the food is especially bad, take up tickets after midnight, call all station stops very loudly during the night, handle baggage as noisily as possible during the night, and so on.
(3) See that the luggage of enemy personnel is mislaid or unloaded at the wrong stations. Switch address labels on enemy baggage.
(4) Engineers should see that trains run slow or make unscheduled stops for plausible reasons.

Swiss open source awards 2008


ossaward2008.pngThe nominations are open on the www.ossaward.ch site, in the following categories: swissness (a project), business (a company), pioneer (a person or institution), advocacy (a person) and youth (a young person).

With my grumpy-french-speaking-minority hat on, I cannot help notice that that site is only available in german…but if I tell them I’m sure they’ll suggest that I volunteer for translating ;-)

[LOTD] JCR publications on InfoQ and TSS (updated)

Both, TheServerSide and InfoQ, have just come out with interesting publications regarding Java Content Repositories:

InfoQ founders Alexandru Popescu and Floyd Marinescu explain InfoQ's architecture and the backend. InfoQ is built upon a custom-made CMS backed by Apache Jackrabbit. Floyd and Alexandru also provide a nice overview over their views on JCR, why they chose to use it and what their content model looks like.

On TheServerSide David Dossot the author of Mule's JCR transport is discussing "Building Content Oriented Integration Solutions With Mule and JCR". We interviewed David about his views on JCR on dev.day.com.

Update (10/06/2008):
InfoQ has just published an additional item on JCR, Sling and REST: Stefan Tilkov interviews Day's CTO David Nuescheler.

Soap? Naah.

5 words on Spring

280slides’s editor - best browser-based application I’ve seen so far


280slides.jpgCheck it out yourself - seems like these guys’ Objective J might help (just a bit) in creating rich browser-based applications. The editor reproduces much of Keynote’s lush UI and functionality in a browser, with no apparent performance problems.

My two-slide presentation might not be enough to really judge the application…but that’s a start.

More on the Spring Thing

Two weeks ago I blogged about integration of Spring and Sling into Spling (btw: if you speak German check out Sandro Ruch's post on the topic). Regarding access to the repository content from a Spring-based application I wrote back then:

So integrating the content really just involves sending HTTP requests. This approach will carry you very far without having to resort to JCR connections (but it surely feels comforting that this lower level access is always there).

Of course, in the workshop described in the post we were considering only Communique 5 which is built on top of Sling. However, in Communique 4 there is no Sling so it is more likely that you end up in a situation were you want to access the repository through JCR.

It turns out that this is exactly what Shane Johnson from CityTech set out to do: Shane has written a very nice post about using Spring's JcrTemplate to access CQ4's repository.

Bertrand's Ready to Board

Day engineer Bertrand Delacretaz has been elected into Apache Software Foundation's Board of Directors. The board is responsible for

management of the corporate assets (funds, intellectual property, trademarks, and support equipment) and allocation of corporate resources to projects.

Congratulations to Bertrand.

On the board


The members meeting of the Apache Software Foundation is over, and I’ve had the pleasant surprise of being elected as a member of the board.

Thanks very much to Henning for nominating me, and to everybody who put an f in their votes.

I’m replacing Henri Yandell who decided not to run again this year, for very good family reasons as I understand. Thanks Henri for your work!

Apart from him the board is unchanged. That will probably make the transition easier than last year, when several directors were replaced at once. It feels good to be the newbie when you’re 46 years old ;-)

Am I looking forward to it? Am I crazy? I guess yes and yes…

Automating the generation of NOTICE files


ASF projects need to include the correct attributions for the dependencies that they redistribute, in NOTICE files (see the http example).

Creating those NOTICEs is a pain in a multi-module project like Sling, so considering the lazyness is a virtue principle, I decided yesterday to automate this based on the mvn dependency:resolve output.

The resulting mknotice script has been happily generating the millions (almost) of Sling NOTICE files today, and the output is much better than we we had before.

However, the mvn dependency:resolve is not always sufficient. In our dojo extensions modules, for example, the Dojo stuff is copied by Ant tasks run from Maven (which is supposed to be declarative, but that’s another story), without having a dependency at the Maven level.

Also, our Launchpad webapp copies dependencies that are embedded in the launchpad base module using the Maven dependency plugin, which only has a dependency to the launchpad base module, but not on what’s inside, obviously. Another case where the mknotice script fails to provide complete information.

For now, such cases are handled using local module.notice.txt files, to define additional notice entries.

As is often the case when one starts to quickly write a script to fix something, this has taken me much longer than expected. And the script is slow. And a Maven plugin would be better. But hey, it works ;-)

Event: Presentation of Day Technology to EU Agencies

Last Friday I had a presentation at 11th ICTAC Meeting, hosted by the European University Institute in Florence. ICTAC is a periodic meeting of ICT (Information Communication Technology) managers from European Union Agencies. My presentation was titled "Standards-Based Solutions for EDRMS".

Slides are not available as it was not a public meeting, sorry. I presented Day's products, technologies, and standards on which they are based. This product stack can be used to build a document/records management system based on a central content repository, integrated with other available systems, and extended using the open architecture of Day products. The key building blocks for this kind of system are RESTful content applications and the feature-rich JCR content repository.

The Zero Bullsh*t architecture

Coming back from our customer and tech summit in Chicago, I have to say it has been a great event, even if you do not consider the Cubs vs. Dodgers game we attended. I have met many interesting people, had great conversations with customers, partners and colleagues and we had some interesting discussions about my talk in the technical track: The Zero Bullsh*t Architecture. The slides are already up on slideshare.net

The basic idea of this talk is that you have to analyze your requirements and concepts throughoutly, that you cannot design a proper architecture on autopilot, and of course that if you are building content centric applications, you should use a content repository as the storage layer and not try to implement all the content repository features on your own spread across architectural layers.

Creating Value in Social Networking

In my second presentation I tried to be less controversial, at least in the title. In "Creating Value in Social Networking" I took the product manager's point of view to define social networking by analyzing existing popular social networks feature-by-feature. From this feature-oriented approach we took a look at some ways of monetizing social networks, which is actually much easier if you are not a pure social network, but already have valuable content that you enhance by adding social relevancy. Even better, when you already have a revenue model the social networking features can increase visitor loyalty and boost your revenues.



Flex on Rails

This week I gave two talks: The first one at the German web conference webinale in the Dynamic Language World sub section. The talk was about the integration of Flex and Rails.

The second talk was given at the RIA conference of the Internet Briefing Group. It was held in German and contained the same content as the previous one plus some bits about RIAs in social networks.

Please note that for both presentations the SlideShare preview embedded in this post really sucks. Download the files if you want to have a look.




Fixing the output of mvn eclipse:eclipse for Sling


I tend to use Eclipse only for editing/navigating code and for remote debugging, leaving the heavy lifting of building and executing stuff to the old trusted command line.

In this context, the mvn eclipse:eclipse plugin often generates too much magic for me. When working with Sling, especially, I don’t want any maven or java builders in my Eclipse projects, and for some reason the plugin generates an extra resource path based on the LICENSE, NOTICE and similar files.

If you like to work in the same way (I know many people like go further with their IDEs), here are two scripts that I use to post-process the Eclipse project files after mvn eclipse:eclipse.

This scripts “fixes” all .project and .classpath files under the current directory (uses xsltproc):

#!/bin/bash
XSLT=$(dirname $0)/fix-eclipse-maven.xsl
TMPF=/tmp/$$.tmp

find . -name .project | while read p
do
  echo "Running $(basename $XSLT) on $p..."
  xsltproc $XSLT $p > $TMPF
  rm -f $p
  mv $TMPF $p
done

EXPR="LICENSE.*DISCLAIMER"
find . -name .classpath | while read c
do
  echo "Removing lines containing $EXPR from $c)"
  grep -v $EXPR $c > $TMPF
  rm -f $c
  mv $TMPF $c
done

And uses this XSLT transform to get rid of the build commands in .project files:

<?xml version="1.0" encoding="UTF-8"?>

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>

  <xsl:template match="*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
     </xsl:copy>
  </xsl:template>

  <!-- remove all Eclipse buildCommands -->
  <xsl:template match="buildCommand"/>
</xsl:stylesheet>

Spring + Sling = Spling

One of the aspects in CMS projects that routinely pops up is the integration of the CMS-based application with some other web application. For example, consider a CMS-based brochure-style web site and an e-banking application. Typically, these are implemented in different systems, but shall be presented to the user in a unified fashion.

Many of Day's customers have a large investment in Spring-based applications which comes as no surprise as Spring is certainly the 800 pounds gorilla in the Java frameworks space these days. Thus, Day developer Alex Klimetschek and I met with Sandro Ruch and Jan Stettler of Day partner company Namics to discuss ways to integrate Communique 5 and Spring-based applications. Sandro and Jan look back to years of experience in Communique and Spring and delivered a large number of projects based on each of them.

The results of this workshop to combine CQ5/Sling-based and Spring-based applications were slightly surprising: it is just so easy. Due to the standards-based approach of Sling the integration boils down to two very simple scenarios:

Spring application in Sling

In this scenario a Spring-based application shall be used from within a Sling-based application. A typical use case would be the integration of legacy data.

The solution for this use case is based on Spring's Dynamic Modules. Dynamic Modules enable Spring application to be deployed in an OSGi container. Since Sling runs on OSGi the Spring application can be deployed into Sling and is afterwards available as an OSGi service. The service's exposed classes and methods are accessible from the Sling view's as any other service.

This integration approach allows Spring developers to develop and test application components that have no dependencies on the content management system. The OSGi-based deployment approach further decouples development cycles of the web developer and the Spring developer.

I intend to write up a little tutorial on deploying Spring apps into Sling (but if you do not want to wait give it a try, it is really easy). A post on deploying regular OSGi beans (without Spring) in Sling is already available.

Access to content from Spring application

The integration approach above is most suitable for "headless" Spring apps, i.e. for applications that consist solely of business logic and do not contain a web tier. If the Spring application is a complete web application the typical integration problem is how to access CMS-managed content from the Spring beans.

Of course, CQ5 is JCR-compliant so the content can be accessed through standard JCR connections (there is also a Spring JcrTemplate available). However, with Sling things get even simpler: the CMS can get accessed through the REST. All nodes and trees are already available in JSON and plain text format and XML will soon follow. So integrating the content really just involves sending HTTP requests. This approach will carry you very far without having to resort to JCR connections (but it surely feels comforting that this lower level access is always there).

You might have noticed it already: REST-based content integration is not confined to Spring or even Java. Sling opens up JCR-based content to any system that speaks HTTP (see also the discussion here).

Next week, I will post on integrating Sling, Spring and Swing to Splwing... Just kidding.

Sling's Request Processing Revisited