@Inject in Tomcat 7

February 10th, 2011

Dependency injection is a technique for decoupling the components of large applications. The specification JSR 330 defines a very abstract way of dependency injection in Java and is part of the Java EE 6 platform. Apache OpenWebBeans implements this specification and provides support for the Apache Tomcat 7 servlet container. This short tutorial is basically a summary, update and extension of this one ;-)

Preparing Tomcat for OpenWebBeans

First of all, we have to download Tomcat 7 and OpenWebBeans and unzip them somewhere. For integrating OWB into Tomcat we have to copy some of OWB’s JAR files to Tomcat’s lib folder:

  • api/geronimo-atinject_1.0_spec-1.0.jar
  • api/geronimo-jcdi_1.0_spec-1.0.jar
  • spi/openwebbeans-spi-1.0.0.jar
  • plugins/openwebbeans-tomcat7-1.0.0.jar

… and you also need to copy the Interceptor API to that folder. The final step is to add the ContextLifecycleListener to the Server node in Tomcat’s conf/server.xml file:

<Listener className="org.apache.webbeans.web.tomcat.ContextLifecycleListener" />

That’s it, our Tomcat now supports CDI.

beans.xml

Don’t forget to add an empty beans.xml file as a marker to every project that contributes implementations to be injected. For general projects this file has to be created in the META-INF folder, for web applications it has to be put in WEB-INF.

Maven

Here are the Maven dependencies for a JSF 2 web application using OpenWebBeans:

<dependency>
	<groupId>org.apache.openwebbeans</groupId>
	<artifactId>openwebbeans-impl</artifactId>
	<version>1.0.0</version>
</dependency>
<dependency>
	<groupId>org.apache.openwebbeans</groupId>
	<artifactId>openwebbeans-resource</artifactId>
	<version>1.0.0</version>
</dependency>
<dependency>
	<groupId>org.apache.openwebbeans</groupId>
	<artifactId>openwebbeans-jsf</artifactId>
	<version>1.0.0</version>
</dependency>
<dependency>
	<groupId>org.apache.openwebbeans</groupId>
	<artifactId>openwebbeans-web</artifactId>
	<version>1.0.0</version>
</dependency>
<dependency>
	<groupId>org.apache.openwebbeans</groupId>
	<artifactId>openwebbeans-spi</artifactId>
	<version>1.0.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.geronimo.specs</groupId>
	<artifactId>geronimo-interceptor_1.1_spec</artifactId>
	<version>1.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.geronimo.specs</groupId>
	<artifactId>geronimo-servlet_3.0_spec</artifactId>
	<version>1.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.geronimo.specs</groupId>
	<artifactId>geronimo-jcdi_1.0_spec</artifactId>
	<version>1.0</version>
	<scope>provided</scope>
</dependency>
<dependency>
	<groupId>org.apache.geronimo.specs</groupId>
	<artifactId>geronimo-atinject_1.0_spec</artifactId>
	<version>1.0</version>
	<scope>provided</scope>
</dependency>

Update (May 2011)

OpenWebBeans 1.1.0 has been released in March 2011. Unfortunately, I couldn’t get it running with a Tomcat 7.0.14. The following exception is thrown when Tomcat initializes OWB’s listener:

java.util.ServiceConfigurationError: org.apache.webbeans.spi.plugins.OpenWebBeansPlugin: Provider org.apache.webbeans.web.tomcat.TomcatWebPlugin could not be instantiated: java.lang.NoClassDefFoundError: org/apache/webbeans/exception/inject/DefinitionException
	at java.util.ServiceLoader.fail(ServiceLoader.java:207)
	at java.util.ServiceLoader.access$100(ServiceLoader.java:164)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:353)
	at java.util.ServiceLoader$1.next(ServiceLoader.java:421)
	at org.apache.webbeans.plugins.PluginLoader.startUp(PluginLoader.java:90)
	at org.apache.webbeans.lifecycle.AbstractLifeCycle.startApplication(AbstractLifeCycle.java:109)
	at org.apache.webbeans.web.lifecycle.WebContainerLifecycle.startApplication(WebContainerLifecycle.java:77)
	at org.apache.webbeans.servlet.WebBeansConfigurationListener.contextInitialized(WebBeansConfigurationListener.java:81)
	at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4723)
	at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5226)
	at org.apache.catalina.core.StandardContext$1.call(StandardContext.java:5221)
	at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
	at java.util.concurrent.FutureTask.run(FutureTask.java:138)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.NoClassDefFoundError: org/apache/webbeans/exception/inject/DefinitionException
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:247)
	at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:345)
	... 13 more
Caused by: java.lang.ClassNotFoundException: org.apache.webbeans.exception.inject.DefinitionException
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	... 16 more

MyFaces 2 + RichFaces 4 + Tomcat 7 = JSF 2

February 1st, 2011

As with most of the Java EE 6 novelties, the web application standard JSF 2 eases a lot of our troubles. So it’s time to give it a test run ;-)

Get the IDE

The Eclipse IDE for Java EE Developers (I’m using 3.6.1 aka Helios SR1) contains all the plugins necessary for building JSF 2 web applications.

Get and register a Servlet Container

First of all we need a Servlet Container to run our shiny new JSF 2 application – Apache Tomcat 7 (I’m using 7.0.6) will do that job.

In the Window > Preferences we configure the Server > Runtime Environments and Add… an Apache Tomcat v7.0. We also want to Create a new local server. On the next page we just Browse… to the directory where you’ve unzipped the Tomcat and Finish.

Get the libraries

We could skip this part by using a dependency management system like Maven and just saying that we want to use RichFaces. But Maven is another topic so to keep things simple we grab and unzip our libraries by hand.

MyFaces Core 2 (I’m using 2.0.3) will be our JSF core implementation and JBoss RichFaces 4 (I’m using 4.0.0.M5) will polish up our application with a lot of useful components. RichFaces’ readme.txt tells us that it additionally requires the following libraries:

Create User Libraries

We’re using Eclipses User Libraries mechanism to ease a bit the juggling with our libraries. For that we create a New > Project and choose the General > Project. Now we unzip all our libraries to this project. Within this project – let’s call it “libraries” – we create some file ending by “.userlibraries”. Let’s call it “libraries.userlibraries”. That file contains our library definitions and may look like the following:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<eclipse-userlibraries version="2">
    <library name="Rich Faces 4.0.0.M5" systemlibrary="false">
        <archive path="/libraries/richfaces-4.0.0.20101226-M5/artifacts/framework/richfaces-core-api-4.0.0.20101226-M5.jar" />
        <archive path="/libraries/richfaces-4.0.0.20101226-M5/artifacts/framework/richfaces-core-impl-4.0.0.20101226-M5.jar" />
        <archive path="/libraries/richfaces-4.0.0.20101226-M5/artifacts/ui/richfaces-components-api-4.0.0.20101226-M5.jar" />
        <archive path="/libraries/richfaces-4.0.0.20101226-M5/artifacts/ui/richfaces-components-ui-4.0.0.20101226-M5.jar" />
    </library>
    <library name="Rich Faces 4 Dependencies" systemlibrary="false">
        <archive path="/libraries/cssparser-0.9.5.jar" />
        <archive path="/libraries/sac-1.3/sac.jar" />
        <archive path="/libraries/guava-r07/guava-r07.jar" />
    </library>
    <library name="MyFaces Core 2.0.3" systemlibrary="false">
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/myfaces-api-2.0.3.jar" />
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/myfaces-impl-2.0.3.jar" />
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/myfaces-bundle-2.0.3.jar" />
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/commons-beanutils-1.8.3.jar" />
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/commons-codec-1.3.jar" />
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/commons-collections-3.2.jar" />
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/commons-digester-1.8.jar" />
        <archive path="/libraries/myfaces-core-2.0.3-bin/lib/commons-logging-1.1.1.jar" />
    </library>
</eclipse-userlibraries>

Now we may go to Window > Preferences, configure the Java > Build Path > User Libraries and Import… our definition file.

Create and set up your project

We create a New > Project and select the Web > Dynamic Web Project. Let’s call it example. The Target runtime is our Apache Tomcat v7.0, the Dynamic web module version is 3.0 and we use the JavaServer Faces v2.0 Project configuration.

We don’t change anything on the Java and Web Module wizard pages. On the JSF Capabilities page we chose to Disable Library Configuration and Finish the wizard.

In the project’s Properties we configure the Java Build Path, select Libraries and Add Library…. We choose the User Library and select the MyFaces and RichFaces libraries that we’ve defined.

To bring Eclipse to push our libraries to the Servlet Container we also need to go to the Deployment Assembly in the project’s properties and Add… our libraries as Java Build Path Entries.

Try it

Just create some index.xhtml page like the following within the WebContent folder…

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	xmlns:h="http://java.sun.com/jsf/html"
	xmlns:f="http://java.sun.com/jsf/core"
	xmlns:rich="http://richfaces.org/rich">
<f:view contentType="text/html">
	<h:head>
		<title>Calendar</title>
	</h:head>
	<h:body>
		<rich:calendar datePattern="dd/MM/yyyy hh:mm:ss" />
	</h:body>
</f:view>
</html>

…and deploy the project by Run As… > Run on Server. Go to http://localhost:8080/example/faces/index.xhtml to have a look at your application.

“Modeling and Planning Collaboration using Organizational Constraints” accepted for CollaborateCom 2010

August 27th, 2010

Willis Tower, Chicago
© 2008 Daniel Schwen

The paper Modeling and Planning Collaboration using Organizational Constraints that I’ve co-authored has been accepted for the 6th International Conference on Collaborative Computing (CollaborateCom 2010). It will meet from October 9th to 12th in Chicago, Illinois, USA.

Prolog in the JVM: Survey of Prolog Engines Written in Java

August 27th, 2010

I’m working on a Java project that requires some logic programming. As Prolog is best suited for such things, I’ve decided to compare some Prolog engines implemented in pure Java.

JLog

Unfortunately, you can find a lot of projects called JLog or jLog. To make things clear: we are talking about this one here. JLog was registered on SourceForge in 2007.

License

Even though the project website tells us that JLog is licensed under the GPL, it’s actually dual-licensed under the GPL and the MPL. Some people argue that these two licenses are incompatible.

Usage

jPrologAPI engine = new jPrologAPI(new FileInputStream("./einstein.pl"));
 
Hashtable bindings = engine.query("einstein(Houses, FishOwner).");
for (Object entry : bindings.entrySet()) {
	System.out.println(((Entry) entry).getKey() + " / " 
		+ ((Entry) entry).getValue());
}
 
engine.stop();

Predicate Libraries

Besides that standard predicates that make the interpreter ISO-compatible it additionally provides

  • JDBC wrapper predicates
  • file system utility predicates
  • wrappers for the Apache Bean Scripting Framework
  • wrappers for AWT to create animations

Development

JLog is developed by Glendon Holst and seems to have started as a research project at the University of British Columbia. The code now resides within a CVS repository on SourceForge. He is obviously rather a C or C++ developer than a Java developer as he steadily ignores nearly every Java coding convention out there ;-) . But as I only intend to use these interpreters for now, I don’t really mind.

Every built-in predicate is mapped to a Java class so that the predicate libraries must be packaged into a JAR together with a table of contents (TOC) file. Mapping predicates to methods and libraries to classes would have been more convenient, I think.

tuProlog (2p)

tuProlog seems to have been initiated around 2001 by the Agents, Languages & Infrastructures for Complexity Engineering (aliCE) research group at the University of Bologna.

License

tuProlog is completely licensed under the LGPL.

Usage

Prolog engine = new Prolog();
engine.setTheory(new Theory(new FileInputStream("einstein.pl")));
 
SolveInfo solution = engine.solve("einstein(Houses, FishOwner).");
if (solution.isSuccess()) {
	System.out.println(solution);
}
solution = engine.solveNext();
while (engine.hasOpenAlternatives()) {
	System.out.println(solution);
	solution = engine.solveNext();
}

Extensions

There is an interesting approach for the “seamless integration of Prolog code into Java applications” based on tuProlog. The code resulting from that project is already contained within the 2.3 branch of the tuProlog distribution.

Apart from that there are no special predicate libraries for tuProlog.

jTrolog (Java Trondheim Prolog)

jTrolog is a fork of tuProlog focussing on performance. The improvements seem to be very effective as you can see under Rough Performance Comparison. It was registered on java.net in 2008 so it’s a fairly new project. In my opinion, there must always be a good reason for forking an active project because you can’t benefit from fixes in the parent project’s code.

License

jTrolog has retained tuProlog’s license: the LGPL.

Usage

The API is almost identical to the one of tuProlog but it lacks a way to iterate over the bindings of a solution. This is bad when integrating the interpreter in a project so I’ve created a patch for that (it is issue #1 so there is obviously not much feedback on this project).

Predicate Libraries

The libraries were taken over from tuProlog apart from the Java extension (is has been forked before).

JIProlog

JIProlog is a closed source project developed by Ugo Chirico. There are two versions available:

  • a free and fully functional shareware version that pops up a notification every time you solve a goal
  • a professional version without the popup for $ 200 (or $ 150 for academic use)

That business model makes it a bad candidate for an academic project so JIProlog is only mentioned here for the sake of completeness.

Usage

The following excerpt shows how to call the interpreter synchronously:

JIPEngine engine = new JIPEngine();
engine.consultFile("./einstein.pl");
 
JIPTerm queryTerm = engine.getTermParser().parseTerm("einstein(Houses, FishOwners).");
 
JIPQuery query = engine.openSynchronousQuery(queryTerm);
while (query.hasMoreChoicePoints()) {
	System.out.println(query.nextSolution());
}

Extensions

  • XML processing (DOM-style)
  • HTML processing
  • Java reflection
  • JDBC

Rough Performance Comparison

To get a rough idea of how the implementations perform, I’ve let them solve Einstein’s Riddle on my Core i5 and measured the average execution time.

rightTo(L, R, [L,R | _]).
rightTo(L, R, [_ | Rest]) 
	:- rightTo(L, R, Rest).
 
nextTo(X, Y, List) :- 
	rightTo(X, Y, List).
nextTo(X, Y, List) :- 
	rightTo(Y, X, List).  
 
einstein(Houses, FishOwner) :-
   Houses = [[house,norwegian,_,_,_,_],_,[house,_,_,_,milk,_],_,_],
   member([house,brit,_,_,_,red], Houses),
   member([house,swede,dog,_,_,_], Houses),
   member([house,dane,_,_,tea,_], Houses),
   rightTo([house,_,_,_,_,green], [house,_,_,_,_,white], Houses),
   member([house,_,_,_,coffee,green], Houses),
   member([house,_,bird,pallmall,_,_], Houses),
   member([house,_,_,dunhill,_,yellow], Houses),
   nextTo([house,_,_,dunhill,_,_], [house,_,horse,_,_,_], Houses),
   member([house,_,_,_,milk,_],Houses),
   nextTo([house,_,_,marlboro,_,_], [house,_,cat,_,_,_], Houses),
   nextTo([house,_,_,marlboro,_,_], [house,_,_,_,water,_], Houses),
   member([house,_,_,winfield,beer,_], Houses),
   member([house,german,_,rothmans,_,_], Houses),
   nextTo([house,norwegian,_,_,_,_], [house,_,_,_,_,blue], Houses),
   member([house,FishOwner,fish,_,_,_], Houses).

The riddle is solved by calling the goal einstein(Houses, FishOwner).

Average execution times

JLog and jTrolog are almost equally as fast while tuProlog is slower. JIProlog lies between them.

But before you jump to a conclusion: tuProlog and jTrolog both always perform the occurs check. This quite expensive technique prevents the engine from running into an infinite loop when solving a goal like

f(X) = X.

JIProlog only performs the occurs check when

unify_with_occurs_check(f(X), X).

is used and would run into StackOverflowError if not.
JLog neither performs the check by default nor implements unify_with_occurs_check/2 so there is no way of preventing it from running into a StackOverflowError.

A quick look at the code reveals jTrologs improvements: it seems to be a completely stack-based implementation with some sophisticated optimizations. tuProlog is implemented rather straight forward and maps recursion in Prolog to recursive methods calls in Java.

Conclusion

jTrolog seems to offer the most advanced open source implementation. It’s really sad that they forked the project instead of contributing their improvements to tuProlog. So in the end, the decision is between a very advanced but inactive project and an inefficient but fairly active one :-( .

“ESProNa: Constraint-Based Declarative Business Process Modeling” accepted for DDBP 2010

June 20th, 2010

Instituto dos Advogados, Vitória

The paper ESProNa: Constraint-Based Declarative Business Process Modeling that I’ve co-authored has been accepted for the Third International Workshop on Dynamic and Declarative Business Processes (DDBP 2010). It’s a workshop in conjunction with the Fourteenth IEEE International EDOC Conference (EDOC 2010) from October 25th to 29th 2010 in Vitória, Espírito Santo, Brazil. Too bad they don’t offer any student travel support :-(