Wednesday 30 May 2007

Multiple persistence.xml files and spring

Today I struggled a bit with multiple persistence.xml files using Spring, JPA (duh).

I had two jar's each containing mapped domain objects and an associated persistence.xml file.

Unfortunately the JPA specification doesn't say anything about how to handle multiple persistence.xml files hence no merging is done by default.

Some searching led me to a jira issue concerning this that Juergen Hoeller have closed for spring 2.0.4.
We have just implemented our own PersistenceUnitManager capable of collecting multiple persistence.xml files and it works great!

Java code:

package com.foobar.spring;

public class MyPersistenceUnitManager extends DefaultPersistenceUnitManager {

protected void postProcessPersistenceUnitInfo(MutablePersistenceUnitInfo pui) {
super.postProcessPersistenceUnitInfo(pui);
pui.addJarFileUrl(pui.getPersistenceUnitRootUrl());

MutablePersistenceUnitInfo oldPui = getPersistenceUnitInfo(pui.getPersistenceUnitName());
if (oldPui != null) {
List urls = oldPui.getJarFileUrls();
for (URL url : urls) {
pui.addJarFileUrl(url);
}
}
}
}
And in your spring configuration add the following (Most likely called applicationContext.xml):
<bean id="persistenceUnitManager" class="com.foobar.spring.MyPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<property name="defaultDataSource" ref="dataSource"/>
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="persistenceUnitManager" ref="persistenceUnitManager" />
...

Tapestry Bayeux 2.0.0-beta2 available from ibiblio

Tapestry Bayeux 2.0.0-beta2 (binary and sources) is now available from the central maven repository.

To use the component library just add the following dependency to your pom.xml:

<dependency>
<groupId>com.nordija.tapestry.bayeux</groupId>
<artifactId>tapestry-bayeux</artifactId>
<version>2.0.0-beta2</version>
</dependency>

2.0.0-beta2 is targetting tapestry 4.1 but because of an issue with tapestry 4.1 and java 1.4 I have mentioned before, the final release of 2.0.0 will target tapestry 4.1.1.

Tapestry Bayeux 2.0.0 is also intended to have some asset or component that integrate with JFreeChart - making it easier to stream charts.

Monday 28 May 2007

Tapestry 4.1 jdk issues - fixed in 4.1.1

Lately I have spend some time investigating a Tapestry and Java 1.4 issue.
It evolved into a jira issue and yesterday Jesse Kuhnert closed the jira as the issue is fixed in 4.1.2-snapshot.
Actually it is already fixed in 4.1.1 as I tried my little testcase against 4.1.1 this morning.

Discovering this will most likely result in Bayeux targeting tapestry 4.1.1 in the final 2.0.0 release comming up.

Also I hope the changes report will tell that the issue has been fixed when a new site is updated. At the current time of writing the changes report states that the 4.1.1 is unreleased although the binary can be downloaded from the central maven repository.

Saturday 26 May 2007

Jira issue on Tapestry 4.1 not being java 1.4 compatible

I haven't been able to find an answer my question from yesterday - whether or not Tapestry 4.1 should be java 1.4 compatible.

After writing in the tapestry mailing list I was urged to create a Jira issue.
So I did and the issue can be found in JIRA: TAPESTRY-1520.
I have also created a small sample testcase demonstrating the problem.

For those interested the sample application can be found here and a log showing what I did can be seen here:

jeyben@vilfortpark /cygdrive/c/projects/sandbox/tapestry-jira
$ echo $JAVA_HOME
C:\jdk\j2sdk1.4.2_10

jeyben@vilfortpark /cygdrive/c/projects/sandbox/tapestry-jira
$ mvn
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building Prove JDK issue
[INFO] task-segment: [install]
[INFO] ----------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] No sources to compile
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to c:\projects\sandbox\tapestry-jira\target\test-classes
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Compilation failure
c:\projects\sandbox\tapestry-jira\src\test\java\org\apache\tapestry\components\TestJdkIssue.java:[4,-1] cannot access org.apache.tapestry.engine.RequestCycle
bad class file: C:\Documents and Settings\jeyben\.m2\repository\org\apache\tapestry\tapestry-framework\4.1\tapestry-framework-4.1.jar(org/apache/tapestry/engine/RequestCycle.class)
class file has wrong version 49.0, should be 48.0



c:\projects\sandbox\tapestry-jira\src\test\java\org\apache\tapestry\components\TestJdkIssue.java:[4,-1] cannot access org.apache.tapestry.engine.RequestCycle
bad class file: C:\Documents and Settings\jeyben\.m2\repository\org\apache\tapestry\tapestry-framework\4.1\tapestry-framework-4.1.jar(org/apache/tapestry/engine/RequestCycle.class)
class file has wrong version 49.0, should be 48.0


[INFO] ------------------------------------------------------------------------
[INFO] For more information, run Maven with the -e switch
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2 seconds
[INFO] Finished at: Sat May 26 17:49:22 CEST 2007
[INFO] Final Memory: 6M/14M
[INFO] ------------------------------------------------------------------------

jeyben@vilfortpark /cygdrive/c/projects/sandbox/tapestry-jira
$ export JAVA_HOME=C:\\jdk\\jdk1.5.0_06

jeyben@vilfortpark /cygdrive/c/projects/sandbox/tapestry-jira
$ mvn
[INFO] Scanning for projects...
[INFO] ----------------------------------------------------------------------------
[INFO] Building Prove JDK issue
[INFO] task-segment: [install]
[INFO] ----------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:compile]
[INFO] No sources to compile
[INFO] [resources:testResources]
[INFO] Using default encoding to copy filtered resources.
[INFO] [compiler:testCompile]
[INFO] Compiling 1 source file to c:\projects\sandbox\tapestry-jira\target\test-classes
[INFO] [surefire:test]
[INFO] Surefire report directory: c:\projects\sandbox\tapestry-jira\target\surefire-reports

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running org.apache.tapestry.components.TestJdkIssue
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.063 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] [jar:jar]
[WARNING] JAR will be empty - no content was marked for inclusion!
[INFO] Building jar: c:\projects\sandbox\tapestry-jira\target\tapestry-jdk-issue-1.0.0-SNAPSHOT.jar
[INFO] [install:install]
[INFO] Installing c:\projects\sandbox\tapestry-jira\target\tapestry-jdk-issue-1.0.0-SNAPSHOT.jar to C:\Documents and Settings\jeyben\.m2\repository\com\nordija\tapestry\issue\tapestry-jdk-issue\1.0.0-SNAPSHOT\tapestry-jdk-issue-1.0.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3 seconds
[INFO] Finished at: Sat May 26 17:50:05 CEST 2007
[INFO] Final Memory: 8M/14M
[INFO] ------------------------------------------------------------------------

Shed light on a classloading mystery

Have you ever struggled with class loading problems like java.lang.NoClassDefFoundError or having the java compiler or jre telling you that a class signature is different than you expect it to be?
The latter is often because the class you thought was classloaded actually was loaded from another location but in a different version than you expected.

To shed light on the classloading mystery I have used the following bash command with success:

$ for i in `find . -name *.jar`; do echo $i; jar tvf $i | grep [a name of a class]; done

A quick explanation:
- for i in `find . -name *.jar`; It iterates through all found jar files in the actual directory and any subdirectory.
- echo $i; Then it echoes the path and filename for any jar file it finds.
- jar tvf $i | grep [a name of a class]; Executing a jar tvf *(testing a jar unpack) and piping it into a grep will print any line containing the text you search for.

Simple example where I locate all Tapestry BasePage classes (and sourcefiles) in my maven 2 repository:

jeyben@vilfortpark ~/.m2/repository/org/apache/tapestry
$ ls -l
total 0
drwx------+ 3 jeyben Ingen 0 May 12 20:56 tapestry-annotations
drwx------+ 3 jeyben Ingen 0 May 12 20:56 tapestry-contrib
drwx------+ 3 jeyben Ingen 0 May 12 20:57 tapestry-core
drwx------+ 4 jeyben Ingen 0 May 12 20:54 tapestry-framework
drwx------+ 3 jeyben Ingen 0 May 12 20:57 tapestry-ioc
drwx------+ 5 jeyben Ingen 0 May 12 20:57 tapestry-project

jeyben@vilfortpark ~/.m2/repository/org/apache/tapestry
$ for i in `find . -name *.jar`; do echo $i; jar tvf $i | grep BasePage; done
./tapestry-annotations/4.1.1/tapestry-annotations-4.1.1.jar
./tapestry-contrib/4.1.1/tapestry-contrib-4.1.1.jar
./tapestry-core/5.0.1/tapestry-core-5.0.1.jar
./tapestry-framework/4.1/tapestry-framework-4.1-sources.jar
1172 Fri Jul 07 02:04:04 2006 org/apache/tapestry/html/BasePage.java
./tapestry-framework/4.1/tapestry-framework-4.1.jar
540 Fri Jul 28 14:33:34 2006 org/apache/tapestry/html/BasePage.class
./tapestry-framework/4.1.1/tapestry-framework-4.1.1-sources.jar
1181 Fri Nov 10 13:26:26 2006 org/apache/tapestry/html/BasePage.java
./tapestry-framework/4.1.1/tapestry-framework-4.1.1.jar
540 Sun Dec 17 02:36:28 2006 org/apache/tapestry/html/BasePage.class

Friday 25 May 2007

Tapestry 4.1 and jdk issues

I am developing a couple of components for Tapestry 4.1. They are meant to go into the final release of Tapestry Bayeux 2.0.0.
But I am having some difficulties getting a clear answer whether or not Tapestry 4.1 is java 1.4 compatible.
Just up until now I thought it was because tapestry 4.0 was and haven't seen any notes saying different about the 4.1 release. But now I am in doubt because I am having trouble executing on of my a testcases compiled by java 1.4.
I keep getting:

java.lang.UnsupportedClassVersionError:
org/apache/tapestry/markup/MarkupFilter (Unsupported major.minor version 49.0)
The error indicate that tapestry 4.1 has been compiled using java 5 and I am trying to compile and execute my test using java 1.4.

To further strengthen my theory I stumbled across the following code in the tap 4.1 source which uses autoboxing, hence can only be compiled by java 5.
org.apache.tapestry.dojo.form.Autocompleter
from line 268:
/**
* {@inheritDoc}
*/
public boolean isAsync()
{
return Boolean.TRUE;
}
If I have to compile using tapestry 4.1, is it correct that my only solution is to go with java 5 and no longer support java 1.4 runtimes?

I did some google searching: site:tapestry.apache.org/tapestry4.1 jdk but I only managed to find the following phrase on the page describing the upgrade from 3.0 to 4.0.
"Part of the transition to Tapestry 4.0, and targetting (in a later release) a minimum JDK of 1.5,..."
A later release seems to be Tapestry 4.1!

I miss a clear statement telling what java version tapestry is compiled by and what runtimes tapestry 4.1 supports.

You are more than welcome to enlighten me if you know the answer.

Sunday 20 May 2007

ATOM vs RSS feeds - on javablogs

I recently added my blog to javablogs and provided my ATOM feed as it seems to be the new de facto "standard" for feeds.

I wondered why my blog entries only contained the header and not a small resume of my blog entries.

I switched to use my RSS as my feed and suddenly the resume was there?
To be sure I switched back to the ATOM feed format and the resume was gone again.

Knowing little about the ATOM and RSS feed formats it still seems that javablogs haven't got a proper interpretation of ATOM feeds. At least not for the ATOM feeds provided by blogger.com.

I have created this issue i JIRA.

Do you have a blog on blogger.com and encounter the same behavior, try providing your RSS feed for javablogs instead:
http://<your-blogname>.blogspot.com/rss.xml

Saturday 19 May 2007

Bayeux is now tapestry 4.1 compatible

I am a developer of Tapestry Bayeux and is proud to announce the release of Tapestry Bayeux 2.0.0-beta-2 (see: changelog).

The reason why I have decided to name the release beta-2 is because the flow component available in bayeux 1.4.0 isn't included in this release. But that is the only reason and the rest of the components is stable.

What is bayeux?
Tapestry Bayeux is a open source component library for Tapestry and was released for the first time back in 2004.

Bayeux contains various components primarily developed for use in projects that Nordija is involved in. But since our first release we have had numerous downloads and we know for sure that tapestry jumpstart 1.2 uses the "do it once" components.

Actually it was Geoff Callender - the developer of tapestry jumpstart - that inspired me to upgrade tapestry bayeux.

When we first released Bayeux, tapestry 3.0 had only been stable for about half a year.
Since then tapestry has evolved rapidly and the latest stable release at the current time of writing is 4.1.1.
In hope to fit as many active tapestry projects as possible, we have upgraded Bayeux to tapestry 4.1.

Tuesday 15 May 2007

Your past will always haunt you...

Recently I was contacted by Geoff Callender, the guy behind the Tapestry Jumpstart application.

He was working on the next Jumpstart version (1.2), that should contain a solution to the famous redirect-after-post paradigm.
As any other developer he must have used Google in his search for inspirationto such a solution and Google must have led him to Tapestry Bayeux.

Bayeux is a Tapestry Component Library containing a small set of components that a couple of my colleagues and I have developed a long time ago - back in the time were Tapestry 3 was on anybodies lips.

Geoff was interested in in the "do it once" components that prevents the user from activating more than one listener by the use of some Javascript. They should be a part of his solution to the previous mentioned redirect-after-post paradigm.

But those components was only Tap 3 compatible, so Geoff had to convert the components to Tap 4 him self if he would like to use this approach in his solution.

And so he did!
I tried to convince him to contribute the source back to Bayeux by giving him developer privileges but some how that wasn't tempting enough. :-)

So now I am "stuck" with the task of bringing Bayeux up to the latest stable version of tapestry - which is 4.1.1 at the current time of writing.
Its funny how software you developed as a part of a solution for some client back in the ages can haunt you down and for a split second make you think "why did I ever make it open-source" :-)


Just started the upgrade of Bayeux made me realize that software development has moved on since then...
CVS > SVN
Maven 1 > Maven 2
etc...

Just more work to be done... :-)

My blog is on air

After several request from my colleague Per I have started this blog.
I don't know what he expect of this blog other than some comments on software development - because that's what I can deliver.

I am primarily developing software in the Java programming language so expect this blog mainly to contain Java topics.