Trifork Blog

Posts by Jelmer Kuperus

Liferay sdk development best practices

May 3rd, 2012 by
(http://blog.trifork.com/2012/05/03/liferay-sdk-development-best-practices/)

Liferay logo
With liferay in action and Portlets in action out and the development guide online there is a fair amount of information on developing portlets and other types of Liferay plugins available.

However none of these resources offer much guidance on the subject of organizing a large project that consists of multiple plugins. In this post i’ll try and document some (best ?) practices that I distilled from working on a Liferay project that uses the Liferay sdk.

Now before I start, let me first say that I definitely would not recommend using the Liferay sdk for all types of projects. In fact in many cases you will be better served by the liferay maven plugin

The liferay sdk has many deficiencies such as having no support for unit testing(!) and not supporting libraries that can be shared across different plugin modules. However currently the liferay sdk is more mature than the maven plugin is, has more functionality, and most if not all available documentation references the sdk.

As a rule of thumb : if your project integrates tightly with Liferay’s built in services and your plugins are not very complex, then using the standard liferay stack : Liferay sdk / MVCPortlet / servicebuilder is a viable option. If your application is more complex then you’ll be a lot happier with a more general purpose stack like maven / spring portlet mvc / jpa

But I digress. On with the best practices
Read the rest of this entry »

Filtering specific exceptions when using log4j

August 23rd, 2011 by
(http://blog.trifork.com/2011/08/23/filtering-specific-exceptions-when-using-log4j/)

A while ago I was working on a project where a background job was being triggered every few seconds or so. This job would call a method on a service, that connected to a remote backend, that was regularly unavailable.

When the backend was down, the logs would be flooded with long stacktraces every few seconds. Making it all but impossible to spot actual errors  amid the carnage.

To solve this problem I could have disabled logging for this service completely. But in this case that seemed like a bad idea. This service was, by all means and purposes a kitchen sink. By disabling logging completely I would run the risk of also swallowing legitimate errors. What I really wanted to do was filter out only this “BackendNotAvailableException”

Fortunately there is a way to do that. Contained within Apache Extras Companion for Apache log4j there is a filter called ExpressionFilter that you can use to do exactly that. Here’s an example of how to configure it for this usecase.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">
    <appender name="CONSOLE">
        <param name="Target" value="System.out"/>
        <layout>
            <param name="ConversionPattern" value="%d %p [%c] - %m%n"/>
        </layout>
        <filter class="org.apache.log4j.filter.ExpressionFilter">
            <param name="expression" value="EXCEPTION ~= com.company.BackendNotAvailableException" />
            <param name="acceptOnMatch" value="false"/>
        </filter>
    </appender>
    <root>
        <priority value ="INFO" />
        <appender-ref ref="CONSOLE"/>
    </root>
</log4j:configuration>

There is actually a lot more you can do with this filter and i encourage you to check it out in greater detail

Debugging the dreaded “SEVERE: Error listenerStart” and “SEVERE: Error filterStart” tomcat error messages

March 18th, 2011 by
(http://blog.trifork.com/2011/03/18/debugging-the-dreaded-severe-error-listenerstart-and-severe-error-filterstart-tomcat-error-messages/)

Just a quick post that I hope might benefit others. If you have been developing web applications on tomcat for a while you have likely come the two error messages mentioned in the title.

SEVERE: Error listenerStart

Occurs when an exception is thrown in the contextInitialized method of a ServletContextListener

SEVERE: Error filterStart

Occurs when an exception is thrown in the init method of a Filter

Unfortunately by default, tomcat won’t provide you with any details about the cause of the error. Infact it wont even tell you which filter or listener is failing. This can be big problem in applications of significant size that have many filters and listeners configured. Fortunately there is a solution. In your webapplication’s WEB-INF/classes folder you can create a logging.properties file with the following contents

org.apache.catalina.core.ContainerBase.[Catalina].level = INFO
org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler

Now you will be presented with the stacktrace

Make Intellij IDEA behave properly in linux docks

January 9th, 2011 by
(http://blog.trifork.com/2011/01/09/make-intellij-idea-behave-properly-in-linux-docks/)

One of my pet peeves when working on Linux has always been that java applications do not work well with popular docks like Docky and Cairo dock. When you add a Java application as a launcher to the dock and use it to launch the application it will still create another icon in the dock, which in a way defeats the purpose of a dock. Reading the comments in following bugreport made it apparent to me, that this is not something that can be easily fixed by the dock’s authors, since the problem lies within the jdk. A workaround exists but it does not apply to all Java applications.

One of the applications the workaround does not work for, unfortunately is Intellij IDEA. The one application I use most on a day to day basis.

When you request the WM_CLASS for Intellij it will identify itself as java-lang-Thread

xprop | grep WM_CLASS | awk '{print $4}'
"java-lang-Thread"

Which is not something that can be used to identify all windows belonging to Intellij. So I decided to see if I could work around this problem, and succeeded. Here’s what you do to make Intellij behave properly

UPDATE 23-01-2010 : whoah seems my original approach had some issues with classloading. (Who needs to create new classes anyway 😉 ) So here are the new and improved instructions.

1. Download  agent.jar and copy it to Intellij’s bin folder.

I wont describe in detail what this jar does. But it’s something i created that changes the default value sun.awt.X11.XToolkit assigns to WM_CLASS. The sources are included in the jar

2. Open idea.sh  And change the line  that looks like

exec $IDEA_JDK/bin/java $JVM_ARGS $IDEA_MAIN_CLASS_NAME $*

to

exec $IDEA_JDK/bin/java -javaagent:agent.jar=Intellij_IDEA $JVM_ARGS $IDEA_MAIN_CLASS_NAME $*

3. Find the .desktop file that is used to start intellij by executing the following command from your home folder

find . -name '*.desktop' -exec grep -H idea.sh {} \;

4. Edit the file you found in step 3 and add the following line

StartupWMClass=Intellij_IDEA

Done!

Testing the database layer

July 1st, 2009 by
(http://blog.trifork.com/2009/07/01/testing-the-database-layer/)

The database is an integral part of many applications and writing queries is often hard. For that reason I have always written integration tests for the data access objects or DAO’s that I use to access the database. The way I write my DAO tests has changed a lot over the years and in this post I’d like to document the ways in which it has changed and why.

Read the rest of this entry »

Decrease the double click speed for Java Applications on Ubuntu Linux

October 13th, 2008 by
(http://blog.trifork.com/2008/10/13/descrease-the-double-click-speed-for-java-applications-on-ubuntu-linux/)

When running any Java swing application (like intellij idea) on Ubuntu the double click speed is by default set to 200ms. If like me you find this anoying you can decrease the double click speed by taking the following steps

In your home directory create a file called .Xresources and add the following line

*multiClickTime: 400

Then from the commandline execute

xrdb ~/.Xresources

to make the changes take effect

Disabling URL rewriting for the Googlebot

September 8th, 2008 by
(http://blog.trifork.com/2008/09/08/disabling-url-rewriting-for-the-googlebot/)

Http is a stateless protocol. To work around the problems caused by this, web applications have the concept of a session. When a user requests a webpage for the first time the user is assigned a unique 32 character string. This string can be send along in subsequent requests to indicate that these requests are in fact originating from the same user. The most common way to pass along this string, or session identifier, is by sending it in a cookie. But what if a user chooses to disable cookies ? In that case a servlet container will fall back on url rewriting, the session identifier is appended at the end of any links in your application. So a link to your homepage might look like this after rewriting

/index.html;jsessionid=AA922A8B781AC4F95E68F88B0AF8CCB3

When you click this link the container will parse the jsessionid value and will determine that you are the same user that made the previous request. This way even privacy conscious users may continue to use your web site. This is something that all just works as long as you use something like the jstl url tag. When it detects that the user has disabled cookies it will automatically start rewriting all the URLs in your application.

Most of the time this is what you want. However there is an unfortunate side affect to this strategy. The Google bot that constantly spiders the internet for new content does not support cookies. This means that it will see, and index, the rewritten URLs. a quick search suggests that this is a fairly common problem. The rewritten URLs will hurt your google rating because less of the URL will match a users search query. So how do you solve it ? It turned out to be fairly trivial.

I created a ServletResponseWrapper that modifies the encodeURL and encodeRedirectURL methods so it does not append the session identifier. The wrapper is created in a servlet filter that only applies the wrapper when it determines that the request originates from the Google bot. You can check this fairy easily by inspecting the user agent header send along with every request. I included the source below

SeoResponseWrapper.java
SeoFilter.java

Too many open files

January 4th, 2008 by
(http://blog.trifork.com/2008/01/04/too-many-open-files/)

Today I was asked to review a piece of code that a coworker of mine suspected was causing “Too many open files“ exceptions in a production environment The code looked innocuous enough. He was using ProcessBuilder to create and run an external application. Regardless I booted into Linux and ran some tests. Now on Linux its fairly easy to find out if a program is leaking file handles. Once a program is started you can look up the process in the /proc file system. The /proc filesystem is a virtual filesystem that resides in the kernels memory it provides you with an easy way to change the behavior of the linux kernel and allows you to view information about currently running processes.

To find out what filehandles a java process is holding onto you simply navigate to /proc/[PROCESSID]/fd There’s a file there for every open file handle.

To count all open file handles you can execute ls /proc/[PROCESSID]/fd | wc -w

Using these simple tools I quickly found out that every time the suspect code was run. 3 filehandles where created that were not being released
As it turns out you need to explicitly close the file handles allocated by Process (eg. Close inputstream, outputstream and errorstream) Process does not release them after the invoked program terminates!

This seems to be a little known fact about Process. Its not mentioned in the javadoc for the process class and just about all the authorative resources get this wrong. Eg.


http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html


http://www.ibm.com/developerworks/java/library/j-tiger09304.html

Etc

At least sun accepted a bug report for improving the documentation. However its been open since 2006..
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6462165

Now I must admit I still am kind of curious about the application my colleague is developing because i believe the max number of filehandles is 65536 on most modern linux systems 🙂

Update: you can also use lsof -p PID for this. The added benefit is that for sockets it will also cross reference the from – > to for socket connections

Spring 2.5 and Maven problems

December 1st, 2007 by
(http://blog.trifork.com/2007/12/01/spring-25-and-maven-problems/)

It looks like the spring 2.5 jars that where uploaded to the official maven repository are broken. The full spring jar is 321 kb large and only contains the spring aop classes.

Anyway I added springs own repository to my pom and then i got the correct jar and sources

<repository>
  <id>spring</id>
  <name>Spring Portfolio Repository</name>   <url>https://springframework.svn.sourceforge.net/svnroot/springframework/repos/repo</url>
</repository>

Extensibility jBPM style

October 8th, 2007 by
(http://blog.trifork.com/2007/10/08/extensibility-jbpm-style/)

Currently I am involved in a project that is moving away from a proprietary workflow solution to a JBPM based workflow solution. One of the first things I attempted to do was try and make jBPM integrate with the identity management solution used in the project. I knew that jBPM comes packaged with some sort of identity component so I started reading up on it in the userguide.

“Management of users, groups and permissions is commonly known as identity management. jBPM includes an optional identity component that can be easily replaced by a company’s own identity data store.”

Sounds good. But then I kept on reading

When you want to use your own datasource for organisational information such as your company’s user database or ldap system, you can just rip out the jBPM identity component. The only thing you need to do is make sure that you delete the line …
<mapping resource="org/jbpm/identity/User.hbm.xml"/>
<mapping resource="org/jbpm/identity/Group.hbm.xml"/>
<mapping resource="org/jbpm/identity/Membership.hbm.xml"/>

from the hibernate.cfg.xml
The ExpressionAssignmentHandler is dependent on the identity component so you will not be able to use it as is. In case you want to reuse the ExpressionAssignmentHandler and bind it to your user data store, you can extend from the ExpressionAssignmentHandler and override the method getExpressionSession.
protected ExpressionSession getExpressionSession(AssignmentContext assignmentContext);

Yikes! What more, the reference to ExpressionAssignmentHandler class is actually hardcoded. So you cannot use a class that simply extends from ExpressionAssignmentHandler. It looks like you have to physically break open the jbpm-identity jar and replace the ExpressionAssignmentHandler contained within by a modified version

This must be some new kind of easy

update: Someone already submitted a Jira issue for this