Since 17 June 2005 there has been a standard, implementation-independent way to read from and write to a content repository from Java code: the JSR-170 specification, published as the Content Repository for Java Technology API in the javax.jcr package. Before that date every Enterprise Content Management (ECM) system exposed its own proprietary API, and moving an application from one repository to another meant rewriting its data-access layer. Here I look at the specification and at what it changes, in practice, for anyone building document management on free software.

Context

A content repository sits above the relational database: it manages documents, folders, metadata, versions, relationships, full-text search and fine-grained access control as native services, rather than leaving them to the application. Documentum, Microsoft SharePoint and the other commercial ECM systems have offered these services for years, each with its own data model and interface. The cost is not only the licence, it is the lock-in. Once metadata, rules and workflows end up inside a vendor’s API, switching products means migrating the whole application layer.

JSR-170 exists to break that coupling. The specification was led by David Nuescheler of Day Software within the Java Community Process: public draft in May 2004, proposed final draft in February 2005, final release in June 2005. The idea is the one JDBC brought to relational database access: one API, many implementations, portable application code.

How the specification is built

JSR-170 defines a graph of nodes (Node) and properties (Property) accessed through a Session opened on a Workspace. Each node has a type (NodeType) that constrains its allowed properties and children: this is the mechanism for modelling a “contract”, an “invoice” or a “procedure” without touching the schema of the database underneath. Properties are typed (string, date, binary, reference) and references hold the graph together.

The specification is layered. Level 1 is read-only: reading nodes and properties, traversing the graph, searching. Level 2 adds writing, moving, copying and management of extensible node types. Above the two levels sit optional feature blocks — versioning, JTA transactions, SQL query, explicit locking, observation of content events. Each implementation declares which blocks it offers; the application asks the Repository what is available rather than taking it for granted.

The layering is the part that interests me. Under the same interface live both minimal implementations — a read-only repository exposing a filesystem — and full repositories. An application using only Level 1 runs against both.

The specification is not the implementation

JSR-170 is an API, not a product. Without a free implementation it would remain a document. The reference implementation is Apache Jackrabbit, which began in the Slide codebase as the reference implementation of the specification and was renamed in September 2004, when it entered incubation at the Apache Software Foundation. Version 0.9 (incubating) was released in February 2006, and the project is becoming top-level right about now, with Roy Fielding as PMC chair.

This is where the practical value of standardisation lies. Day Software, the spec lead’s company, has its own commercial implementation; Apache Jackrabbit is the free version under the Apache 2.0 licence; other ECM systems can expose javax.jcr over their own engine. A case that seems telling to me is Alfresco, the open-source ECM released in 2005 by John Newton — a co-founder of Documentum — under a dual licence (community GPL and commercial enterprise). Alfresco rests on Lucene for search and Hibernate for persistence, and is building a JSR-170 interface over its own repository: compliance is in progress, not yet complete. The same application written against javax.jcr can, in principle, run on Jackrabbit during development and on a full ECM in production.

It is worth saying precisely what the standard guarantees and what it does not. It guarantees that code using the API compiles and works against different implementations, for the levels and blocks both of them declare. It does not guarantee that two repositories share the same semantics in the details the specification leaves open, nor that node-type models are interchangeable without a mapping. What is portable is the interface, not content already loaded.

What changes for open-source document management

The practical consequence is that the choice of implementation comes apart from the choice of API. An organisation can prototype on Jackrabbit, model the content types, write the automatic rules and workflows against javax.jcr, and then choose the production engine according to volume, support and operational requirements without rewriting the application layer. For anyone building on free software this lowers the risk of adoption: you evaluate the code in depth before committing, and you commit to a public API rather than to a vendor’s internal format.

It also changes what “open source” means for an ECM. Having the code available is not enough: if the access API is proprietary, the lock-in remains at the application layer even with open sources. A free repository that exposes a standard interface moves the point of independence from owning the code to owning the integration.

Limits

Version 1 of JSR-170 leaves a fair amount out. It does not standardise ACLs and access control beyond what the two levels need; it does not define a content-interchange format between repositories; it does not cover the federation of multiple repositories under a single session. Node-type management is powerful, but the portability of those types across implementations depends on conventions, not on the specification. And a standard API says nothing about performance: two compliant implementations can behave very differently under load.

The fact remains that, since June 2005, there is a fixed point. For document management built on free software it is the layer worth programming against, whichever repository ends up underneath.


Cover image: Historic Sun Microsystems logo: the purple “SUN” wordmark arranged as a 90-degree rotational ambigram — logo by Sun Microsystems, public domain — https://commons.wikimedia.org/wiki/File:Sun-Logo.svg