Frequently asked questions

What is JSR-170, aka the Java Content Repository ("JCR")?

JSR-170 is a Java Specification Request, that is, a standardized Java API for managing content in an abstract way. Every item in the repository has a path, and optionally an unique ID. It is developed under the Java Community Process, also known as JCP.

Why use JCR? Well, JCR gives you a very powerful metaphor for managing your content. Everything, including the content and any associated metadata, is treated similarly. All items in the repository are just Properties under an abstract location called a Node. For example, you could have a Node to hold your blog entries, located at a Node "/blog/entries/2008/10/24", and then have content for it, which would be located in "/blog/entries/2008/10/24/picture.jpg", and "/blog/entries/2008/10/24/blogentry.txt". These two properties would then be the children of the previous node, and you could easily access and list them. It's kinda like having your own, typed file system with workspaces, searching, observation and locking.

JCR repositories will also give optional goodies, like locking of content, or versioning it. The bigger ones will also give you clustering and scalability. Priha does not, but then again, that's not the aim.

Are there implementations of JCR available?

The most famous implementation is probably the open source Apache Jackrabbit, which also serves as the Reference Implementation of the specification. In addition, at least Day CRX (commercial), Alfresco (open source) and eXo (commercial) also implement JSR-170.

Why create another JSR-170 library? Isn't Jackrabbit enough?

JSR-170 is a fairly new specification, and there aren't that many implementations available yet. It is good for the marketplace if there is competition - and also, so far all of the JCR implementations are designed for large deployments.

Priha targets people who want to have a simple implementation to get the advantage of the JCR API, but don't want the complexity of using a library with many dependencies. It's the same reason why you would use e.g. HSQLDB instead of MySQL - simple is beautiful, and often enough.

And, because JCR is modular, you can always use whichever implementation you want, depending on your requirements for a particular application.

What license is Priha available under?

Priha is freely available under the Apache Public License, an open source license.

What does Priha support and not support?

As mentioned, Priha does not yet completely support the full JSR-170 (though it does support all the mandatory parts). Priha supports:

The support for the following is partial, to the extent which is needed to fill the JSR-170 requirements:

The following are not supported at all at the moment:

Some of this stuff will certainly get into Priha, depending on the interests of the developers. If you want to contribute, head out to the priha-dev mailing list and help us out!

Which logging library does Priha use?

To minimize dependencies, Priha uses the JDK built-in logging library (java.util.logging). All logging is done in the "org.priha" -namespace.

How well does Priha perform, and what do the numbers mean when I run 'ant perftests'?

Priha performance depends quite a lot on the underlying provider implementation. The built-in FileProvider is slow on writes, but can handle large files with ease. In general, Priha is quite fast doing random reads and large files; not so good when doing queries. You can do a rough benchmark by getting the source and saying "ant perftests". If you have Jackrabbit libraries in your classpath, also Jackrabbit numbers are included for reference.

Description of the tests:

Test Description
FirstSess Creation of a Session object from scratch, when the repository is not yet initialized.
NewSession Tests how quickly new Sessions can be created and discarded AFTER the initial session has been created.
LargeSave Stores a large number of large binary blobs into the repository in a two-level tree hierarchy.
LargeRead Reads the blobs stored in LargeSave in a random fashion and measures throughput.
LargeRemove Removes all the Nodes created in LargeSave.
Save Stores a large number of mix:referenceable Nodes into a two-level hierarchy, with Properties.
RandRead Reads a random property from the Nodes saved in the Save test.
SeqRead Reads through all of the properties of the Nodes saved in the Save test using getNodes(). This tests the sequential access speed.
getProperty Reads the same Property (using Node.getProperty()) all over again to see the raw overhead.
getItem Reads the same Property (using Session.getItem()) all over again to see the raw overhead.
propUUID Reads the same property (using Session.getNodeByUUID().getProperty()) all over again to see the raw overhead.
Update Fetches a Property from a random Node, updates it, and writes it back to the repository.
exists Performs Session.itemExists(), 50% of time fetches a random existing node, and 50% of time a non-existing node.
UUID Fetches a large number of random Nodes using Session.getNodeByUUID().
Remove Removes all the Nodes created in Save.

As a sample, here are the results for Priha (and Jackrabbit). Newer versions are probably faster, and the methodology used probably does not stand against any real scientific scrutiny, so please don't use this for any actual reference. Hardware used is a Dell server with 2 x Intel E5310 quadcore Xeons at 1.6 GHz running Ubuntu Linux and latest JDK 1.6.0.

Test results.  The number is operations/seconds - larger means faster.
Blob size 10 kB
Repository size 1000 nodes
Priha version 0.7.0-svn
Jackrabbit version 1.6.0
                                 FirstSess   LargeRead LargeRemove   LargeSave  NewSession    RandRead      Remove        Save
MemoryProvider, no cache                 2      169850     3467442        1180       19393       93403     2247833         614
FileProvider, no cache                  96       25883         452         362        5892       31198         272         254
FileProvider, with Ehcache              14       30809         537         386        2935       35736         439         324
JdbcProvider, no cache                0.05       36381         288         281        8153       49126         285         201
JdbcProvider, with Ehcache             454       34604         379         290        3345       47363         373         260
Jackrabbit                            0.26       11636         439         236        2177       15122         526         243


                                   SeqRead        UUID      Update      exists     getItem getProperty    propUUID
MemoryProvider, no cache          19599004       56721        6364      643217      493640      186773      126756
FileProvider, no cache                2163       14839        1185       34142     1849271      628239      587961
FileProvider, with Ehcache            2973       23777        1633       34199     2874278      748280      705840
JdbcProvider, no cache                2775       15994        1406       18314     2684978      737968      695660
JdbcProvider, with Ehcache            4181       24879        1765       16629     2838486      744843      702273
Jackrabbit                            2569       27752         310       21650      462022     1885147      771737

As you can see, Priha is in general on par or slightly faster than Jackrabbit. With smaller repositories, Priha is faster than Jackrabbit; whereas when the repository size grows, Jackrabbit tends to perform better.

How do I configure Priha?

Please see doc/Configuring.txt in the source repository.

How do I get a Priha Repository object?

Unfortunately, JSR-170 does not define a standard way to get to a Repository object. However, Priha does support a couple of ways to do it. First, you can use the included JNDI servlet by installing it via your web.xml:

TBD, not yet completed, please someone make org.priha.test.JNDIRegistrationServlet work...

Another way is to use the RepositoryManager interface, which just simply searches for a configuration file called priha.properties from your classpath.

...
   Repository prihaRepository = org.priha.RepositoryManager.getRepository();
...

Is there an issue tracker? (e.g. JIRA or Bugzilla?)

Yes. Please see bugs.priha.org

What does Priha mean?

"Priha" is an old Finnish word and it translates roughly as a "young man".

Who are you?

I am Janne Jalkanen, who wrote most of JSPWiki. At the moment I am working on Priha alone, but I hope to get more contributors.

Can I help you?

Absolutely. If you're interested in contributing, please join the priha-dev mailing list.