Skip navigation

In the first half of April, two major projects I've been involved in during this year's first quarter were officially launched. While the first one, the redesign and re-implementation of the website for the kult.kino - an art-cinema company in Basel - was for me rather a routine Magnolia CMS based project (although there were some interesting details, too), the second one provided me an opportunity to extend my professional knowledge from pure server-side Java into the (for me) new and exciting area of Single-Page Applications (SPA).

 

Introduction

Our client - Kooperationsinitiative Museen Baselland (further KIM.bl) - is an initiative for better cooperation of the museums and other institutions caring for the cultural heritage in the Swiss canton of Basel-Landschaft. Our goal was to create a Liferay-based portal, so the individual member institutions and their employees can better cooperate, and also the particular institutions can present themselves in the public part of the portal.

My part was to implement two portlets - one to allow to display the events held by particular institutions, the other, which I want to address in this post, to provide a search in the exhibit-catalog of the participating museums.

 

Backend

The Liferay Portal, which powers the whole portal implementation, is for my two portlets just a bit more than a container. All the data are stored in an Apache Solr instance, and my portlets work as a front-end for these Solr data. As for the Liferay features, I use just the portlet configuration, Friendly-URLs, and a few delegated servlets.

 

The prototype and the move towards SPA

The initial specification had not mentioned the idea of SPA, so I implemented the prototype as a standard Liferay portlet, using the Solrj library. But when we discussed the prototype with our counterparts from KIM.bl, the need to avoid constant reloads of the page, plus the other enhancement ideas led us to the decision to drop the initial implementation and start from the scratch with an SPA implementation. I embraced this decision quite happily (but with a bit of concern, too), because it had given me a chance to use in a live project something I had been already aiming to for some time.

 

AJAX-Solr

The dropping of the Solrj library introduced a need to find out a Javascript library for communication with the Solr backend. After a brief evaluation of the available options I decided to use the AJAX-Solr library.

The two key components used in my project are Managers and Widgets. Manager is a component responsible for composition and execution of a query, while the Widgets process the result. Widgets are registered to Managers and there can be more than one widget registered, so the results of each query can be processed multiple times.

I use more independent Manager components in my application - besides the main Manager to process the search form, there are also Managers (and widgets) for facets, for loading a data of a particular exhibit, and for loading a “more like this” objects for the displayed exhibit.

 

Knockout.js

While the AJAX-Solr was - one could say - just a Javascript replacement for the Solrj Java library, I needed a library (framework?) to help me to add the dynamics to the search form processing and display of the results. I wanted something rather light-weight and easy to learn, what I could easy embed into our Liferay or Magnolia CMS based solutions. Here I need to thank to Wayne Maurer from Lambda IT, because it was him, who pointed me to the Knockout.js library during our conversation after his SPA talk in Bern in November 2014.

Knockout (KO) implements the MVVM pattern and thanks to its declarative bindings and templates is easy to understand even for team members who don’t know it yet, such as the designers that have to “polish” the developer’s outcome. The AJAX-Solr widgets processing the Solr response are simply putting the data into KO’s observable arrays, and KO handles their proper display.

 

Disclosure

As usual, when man finishes a project, he learns few (or even a lot of) things he should have known before he started it. In my case, I would do a deeper integration between the KO and AJAX-Solr (probably using the Mapping plugin) and defining a few custom KO components (or elements). Not mentioning that the current Javascript code definitely deserves some optimizations and a bit better organization.

 

Credits

I have to say that I’ve really enjoyed the work on this project. Not just because the new things I had to learn, but also, no - above all! - because of the people from both KIM.bl and our side of the project. The requests and bug reports from the KIM.bl team were always on topic, well formulated, and quite regularly pointing out the cause and/or suggesting the solution. Ralph, Gabriel - it was a pleasure to work with you! And I must not forget my brilliant colleagues, especially Yuri and Frédéric - the first managing the project and allowing me to focus on the technical side of it, the other making the incredibly good job recasting the original graphic design into the actual HTML/CSS/JS form.

 

Conclusion

So, the shift from the pure Java developer into being a bit more complex one is not so hard. Yes, there is still a lot to learn, but that’s what developers should do permanently, isn't it? And if you have a good team, and an enlightened customer, you can even enjoy it.

Just shortly today: we have hit an awkward bug in Tomcat 6.0.41 this week (is present also in 7.x and 8.x Tomcat line). When you have a JSP page that includes another JSP file, which contains an element with empty attribute, e.g. <input name="xy" value="" />, then an attempt to display such page leads to an error and a "funny" message in the log file:

 

SEVERE: Servlet.service() for servlet jsp threw exception

java.util.NoSuchElementException

        at java.util.AbstractList$Itr.next(AbstractList.java:350)

        at org.apache.jasper.compiler.Validator$ValidateVisitor.getJspAttribute(Validator.java:1330)

        at org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:737)

        at org.apache.jasper.compiler.Node$UninterpretedTag.accept(Node.java:1246)

        at org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2361)

        ...

        at org.apache.taglibs.standard.tag.common.core.ImportSupport.acquireString(ImportSupport.java:296)

        at org.apache.taglibs.standard.tag.common.core.ImportSupport.doEndTag(ImportSupport.java:161)

        at org.apache.jsp.yourpage_jsp._jspx_meth_c_005fimport_005f6(yourpage_jsp.java:713)

        ...


I have tracked it down to https://issues.apache.org/bugzilla/show_bug.cgi?id=56561 and https://issues.apache.org/bugzilla/show_bug.cgi?id=56610, but my problem was, that our hosting provider runs Debian, and there is no tomcat6 package for Debian with the newest 6.0.43 version. So I had to apply the following workaround to my JSP files (luckily, there was just few of them):

 

<c:set var="EMPTY_STRING" value="" />

...

<input name="xy" value="${EMPTY_STRING}" />


Anyway, if you are hitting this bug, too, then the best option is to upgrade your Tomcat version, if possible.

During the release on Wednesday, June 13th, 2012, the JBoss Community team has released a new feature for the Magnolia CMS - the Directory Listing paragraph. While the front-end part of the feature is well described in the above linked chapter of the Paragraph Guide, I'd like to share few details about the back-end part.

A Bit Of History

JBoss Community uses the Magnolia CMS to run the www.jboss.org and www.hibernate.org sites. Magnolia CMS is an open source Java based CMS, that runs over the JCR API. By default, it uses the Apache Jackrabbit, but after the JBoss project ModeShape sprung up, we began to play with an idea of replacing the Apache's reference implementation of the JCR API with the JBoss' one. So some 2 years ago, I've started the initial works, that resulted first into a blogpost "How To Make Magnolia CMS Shaped", and later to an official - although "experimental" - support of ModeShape in Magnolia.

Anyway, ModeShape had struggled some performance issues on big repositories back then*, so we had to abandon the idea of completely replacing the Jackrabbit with the ModeShape, and decided to use Jackrabbit and ModeShape side-by-side. The primary objective was to attach the downloads.jboss.org filesystem to Magnolia and allow the visitors to browse it on the download pages of particular projects.

Initial Conditions

The JBoss Community team uses Magnolia CMS version 4.4.x (4.4.6 at the moment), deployed into the JBoss EAP as an EAR package. This package contains the Magnolia CMS web application and a bunch of web services that provide e.g. the project navigation for project forums, documents etc. in SBS (a.k.a. community.jboss.org).

The files stored at downloads.jboss.org are served by an Apache web server from a filesystem where the total amount of data is over 320GB.

Integrating Magnolia and ModeShape

As mentioned above, we abandoned the idea of replacing the Jackrabbit completely, and decided to use both Jackrabbit and ModeShape. The first idea of putting everything together to the Magnolia's WEB-INF/lib folder led to a dead-end. The problem was, and is, that Jackrabbit is a reference implementation, and is, well, quite conservative regarding the versions of libraries it uses. ModeShape, on the other hand, is rapidly developing bleeding-edge technology, that uses as new versions as possible. So we ended up in a conflict between the Jackrabbit's version of Lucene (2.4.x) and ModeShape's one (3.x).

Thus we had to use the ModeShape repository over JNDI, so I wrote the JNDIProviderImpl class for Magnolia, and implemented a simple web application to initialize the repository and share it via JNDI. This application uses modeshape-jbossas-service to publish the ModeShape JCR engine to JNDI, as we use the JBoss EAP to run Magnolia.

A little complication occured when the testing on staging server started, because the test data we copied from the production storage contained broken symlinks, and the repository couldn't start. So I learned an useful trick how to find broken symlinks on a linux filesystem, repaired the data, and created an issue in ModeShape's JIRA. 

There has been more glitches that have shifted the expected release date, some because of my own "dexterity", others relative to the Red Hat's internal building system (we have to deploy our applications in the form of an RPM package), but finally we have achieved the goal.

How It Works

So at the moment, there is a web application that initializes ModeShape repository with a filesystem source, and places it into JNDI. It is configured to be deployed as first on the EAP start. The the EAR with Magnolia is deployed, and it loads the repository from the JNDI (besides the standard Jackrabbit-powered repositories). The Directory Listing paragraph's model class uses this repository to serve information about the files and folders.

The filesystem repository source is configured read-only (mode:updatesAllowed="false"), and there is a mode:exclusionPattern attribute set to "^[\.].*" to exclude "hidden" files and folders (whose name starts with a dot), especially the .snapshot folders.

The Future Plans

The life brings change every day, so there are already few feature requests and ideas how to improve the Directory Listing paragraph and extend the utilization of the ModeShape repository. As for the paragraph, we'd like e.g. to add the possibility of setting the default sorting, as it now supports only the standard filesystem (i.e. alphabetical) sorting that causes the latest releases to be usually displayed at the bottom of the list. And for the ModeShape repository we plan to attach e.g. the static.jboss.org filesystem to it, so we can use it more comfortably (and also move some big binaries like videos etc. out of the Magnolia's DMS).

Credits

My big thanks for helping with that projects belongs especially to Jan Haderka from the Magnolia team, Randall Hauch from the ModeShape team, and Mark Newton and the whole JBoss Community team.

 


* It was the days of ModeShape 2.4.x, and ModeShape team did a big job improving the performance with every minor release. And the new ModeShape 3.0 promises to be a giant step in that field.

Filter Blog

By date:
By tag: