tag:blogger.com,1999:blog-78362043523695141802024-03-06T03:34:06.057+01:00Around the World in JavaHarald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.comBlogger84125tag:blogger.com,1999:blog-7836204352369514180.post-22988078339033228462014-07-07T16:40:00.000+02:002014-07-07T16:51:10.712+02:00SonarQube, FindBugs and Java 8This post describes how to patch SonarQube to make the FindBugs plugin analyze Java 8 code.<br />
<br />
<h4>Background</h4><br />
We start with an official installation of SonarQube 4.3.2 with Sonar Java 2.3. The Sonar Findbugs plugin uses findbugs 2.0.3. This version uses ASM 3.3 for byte code analysis, but Java 8 requires ASM 5.0.x.<br />
<br />
FindBugs snapshots have been using ASM 5.0.2 for a while, and a Java 8 compliant FindBugs 3.0.0 release has now been published, but the artifacts are not yet available in Maven Central or any other Maven repository.<br />
<br />
In fact, the FindBugs Maven build process is not quite clean, relying on a local snapshot of an external dependency (Apache BCEL).<br />
<br />
Thus, for patching SonarQube, we need to do a clean Maven build of FindBugs, then build sonar-findbugs with this updated dependency and finally overwrite the sonar-findbugs plugin in our SonarQube installation.<br />
<br />
Whenever patching third-party Maven artifacts, I use a project or company suffix on the version identifiers, e.g. <code>-eos-1</code>, to distinguish my patches from official releases.<br />
<br />
<h4>Building FindBugs</h4><br />
<pre class="Xml" name="code">git clone https://code.google.com/p/findbugs
cd findbugs/findbugs
mvn install:install-file -Dfile=lib/bcel-6.0-SNAPSHOT.jar -DgroupId=com.google.code.findbugs -DartifactId=bcel -Dversion=6.0-eos-1 -Dpackaging=jar
</pre><br />
Then edit <code>pom.xml</code>, setting the version to <code>3.0.0-eos-1</code> and replacing the <code>bcel</code> dependency version <code>6.0-SNAPSHOT</code> by <code>6.0-eos-1</code>.<br />
<br />
Now build and install FindBugs <code>3.0.0-eos-1</code> to your local repo:<br />
<br />
<pre class="Xml" name="code">mvn clean install
</pre><br />
<h4>Building sonar-findbugs</h4><br />
<pre class="Xml" name="code">git clone https://github.com/SonarSource/sonar-findbugs.git
cd sonar-findbugs
</pre><br />
Edit <code>pom.xml</code>, set <code>findbugs.version</code> to <code>3.0.0-eos-1</code> and <code>maxsize</code> in the <code>maven-enforcer-plugin</code> rules to 6000000.<br />
<br />
Now build and install <code>sonar-findbugs 2.4-SNAPHOT</code> in your local repository:<br />
<br />
<pre class="Xml" name="code">mvn clean install
</pre><br />
<h4>Install the patched plugin</h4><br />
<ul><li>Stop your SonarQube server.</li>
<li>Go to <code>SONARQUBE_HOME/extensions/plugins</code> and replace <code>sonar-findbugs-plugin-2.3.jar</code> by <code>sonar-findbugs-plugin-2.4-SNAPSHOT.jar</code></li>
<li>Restart your SonarQube server and run a FindBugs analysis under Java 8.</li>
</ul><br />
<h4>Download patched plugin</h4><br />
You can <a href="https://www.dropbox.com/s/jdbhkrxcc5i00ot/sonar-findbugs-plugin-2.4-SNAPSHOT.jar">download</a> the patched plugin from DropBox.<br />
<br />
<h4>Disclaimer</h4><br />
Use these instructions at your own risk.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com1tag:blogger.com,1999:blog-7836204352369514180.post-32714860452246502362013-11-05T20:41:00.000+01:002013-11-05T20:41:06.136+01:00No More Commercial Support for GlassFish - So What?<a href="http://jaxenter.com/glassfish-reduced-to-toy-product-as-commercial-offering-axed-48729.html">"GlassFish reduced to toy product"</a> and <a href="http://java.dzone.com/articles/rip-glassfish-thanks-all-fish">"R.I.P. GlassFish"</a> are some of the headlines regarding Oracle's announcement to withdraw commercial support for the application server acting as Java EE reference implementation.<br />
<br />
Oh well, I've stopped using GlassFish 3.x on a regular basis about a year ago when it became apparent that GlassFish 3.1.2.2 was a <a href="https://blogs.oracle.com/theaquarium/entry/glassfish_for_business_updates_glassfish">dead end</a> for the Java EE 6 Open Source product (see comments of the linked blog post), and I've never really started using GlassFish 4.0 except for quick demos, knowing the release policy would be just the same as for 2.x and 3.x, where the Open Source release was more of a public beta for the closed-source commercial product.<br />
<br />
It's nice to know you can get commercial support for a server if you need it and if somebody is willing to pay for it. On the other hand, lots of companies run successful businesses with applications built on Open Source web containers or application servers without any commercial support, because commercial support is not affordable in their business models. Moreover, commercial support is not a guarantee for getting a hot-fix when you need it, if the vendor's priorities happen to differ from your own.<br />
<br />
Like many others, I've turned from GlassFish to JBoss AS/WildFly (after evaluating and dismissing TomEE for lack of stability and documentation). JBoss AS 7 has surpassed GlassFish in terms of usability and reliability, and it's just a shame that RedHat has now converted JBoss AS to a Not-So-Open Source project, hiding branches and tags in a private repository and no longer publishing Community binaries. But that's another story...Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-22668213031644507532013-07-08T17:51:00.000+02:002013-07-08T17:51:10.503+02:00Browsing a Lucene 4.x index with Luke<a href="http://code.google.com/p/luke/">Luke</a> is a small desktop client for browsing Lucene indices. It is very useful for troubleshooting when you work with Lucene directly embedded in your application.<br />
<br />
While upgrading an application from Lucene 3.4 to Lucene 4.3.1, I realized that Luke is not quite up-to-date with Lucene, it is stuck somewhere in 4.0.0 alpha. <br />
<br />
But the good thing about Open Source is, if the original project owners lose time, resources or interest, others may show up and fork or continue the work.<br />
<br />
A number of people have forked or copied Luke to GitHub. <a href="https://github.com/tarzanek/luke">tarzanek/luke</a> also offers binary builds on <a href="https://java.net/projects/opengrok/downloads">java.net</a>, and this version works fine for me with Lucene 4.3.1 so far.<br />
Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-26246772947326260252012-12-11T20:23:00.002+01:002012-12-11T20:23:53.085+01:00Eclipse Juno Patch for XML Editor PerformanceEclipse Juno has a number of performance regressions compared to Indigo. Switching back and forth between XML and Java editors can be tediously slow even in Juno SR1. <br />
<br />
The patch provided for <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=394588">bug 394588</a> solves the issue or at least significantly improves the response time of the IDE.<br />
<br />
In my team, we have tested the patch successfully on Windows 32 bit and Ubuntu Linux 64 bit with Oracle Java 6 and 7.<br />
<br />
The patch can be installed from a <a href="http://download.eclipse.org/eclipse/updates/junoSR1Patch-tmp">special update site</a> via <b>Help | Install New Software</b>.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-48527867372815541082012-11-23T23:15:00.000+01:002013-01-16T19:32:05.902+01:00Logging with SLF4J and Logback in Tomcat and TomEELogging in Java would be a lot easier if every open source project out there would use SLF4J logging API, but of course this will never happen.<br />
<br />
The fact that <code>java.util.logging</code> made it into the JRE does not make it any better than it is, so there's a good reason to hide it behind a facade and never use it directly. But there is no reason for everyone to invent their own logging facades instead of simply using SLF4J.<br />
<br />
In my own applications, I always use SLF4J with Logback. Working with Tomcat, this means I'm getting an ugly mixture of log messages in different formats from my web application logging to System.out with Logback, and from Tomcat itself logging to System.err via JULI and java.util.logging, not to mention any third-party libraries contained in my application which use log4j, Apache Commons Logging or whatever.<br />
<br />
There are two independent but similar approaches of replacing the official Tomcat JULI libraries by an SLF4J or Logback adapter: <a href="http://code.google.com/p/tomcat-slf4j">tomcat-slf4j</a> and <a href="https://github.com/grgrzybek/tomcat-slf4j-logback">tomcat-slf-logback</a>. <br />
<br />
I've tried both, but in the end, I think it's easier to use nothing but the JUL-to-SLF4J bridge and other standard artifacts.<br />
<a name='more'></a><br />
<br />
<h3>Setup for Tomcat</h3><br />
Get the following artifacts from Maven Central and copy them to <code>$CATALINA_HOME/bin</code>:<br />
<ul><li>slf4j-api-1.7.2.jar</li>
<li>jul-to-slf4j-1.7.2.jar </li>
<li>logback-classic-1.0.6.jar</li>
<li>logback-core-1.0.6.jar</li>
</ul><br />
Add the following line to <code>$CATALINA_HOME/conf/logging.properties</code> or replace the entire file contents by<br />
<br />
<pre class="Xml" name="code">handlers = org.slf4j.bridge.SLF4JBridgeHandler
</pre><br />
Create a Logback configuration file in <code>$CATALINA_HOME/bin/logback-config/logback.xml</code>, e.g.<br />
<br />
<pre class="Xml" name="code"><configuration debug="false">
<contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name="LOGFILE" class="ch.qos.logback.core.FileAppender">
<file>${catalina.base}/logs/tomcat.log</file>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="LOGFILE" />
</root>
</configuration>
</pre><br />
Create or edit <code>$CATALINA_HOME/bin/setenv.sh</code>:<br />
<br />
<pre class="Xml" name="code">CLASSPATH=$CATALINA_HOME/bin/jul-to-slf4j-1.7.2.jar:\
$CATALINA_HOME/bin/slf4j-api-1.7.2.jar:\
$CATALINA_HOME/bin/logback-classic-1.0.6.jar:\
$CATALINA_HOME/bin/logback-core-1.0.6.jar:\
$CATALINA_HOME/bin/logback-config/
</pre><br />
Now start Tomcat via <br />
<br />
<pre>bin/catalina.sh run
</pre><br />
and see it logging via Logback:<br />
<br />
<h3>Setup for TomEE</h3><br />
The same procedure also works for TomEE if you delete the <code>slf4-api-*.jar</code> and <code>slf4j-jdk14-*.jar</code> libraries that come with TomEE in <code>CATALINA_HOME/lib</code> for the stand-alone distribution, or in <code>CATALINA_HOME/webapps/tomee/lib</code> for the drop-in WAR.<br />
<br />
With this approach, all log messages are redirected, not only from Tomcat itself, but also from OpenWebBeans, OpenEJB and other components bundled with TomEE. The JULI replacements mentioned above only redirect Tomcat's own messages logged via JULI, since OpenWebBeans and OpenEJB have logging facades of their own.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com8tag:blogger.com,1999:blog-7836204352369514180.post-44729046990053686452012-10-20T16:32:00.002+02:002012-10-20T16:32:59.538+02:00Using the Maven 3 API with Maven 2 ComponentsWorking on a Maven plugin, I was trying to upgrade the Maven API from 2.x to 3.0.4. After the upgrade, the plugin would no longer compile due to an unsatisfied transitive dependency of the <code>maven-archiver</code> used by the plugin: The class <code>org.apache.maven.artifact.DependencyResolutionRequiredException</code> could not be resolved.<br />
<br />
The same issue was posted on the <a href="http://maven.40175.n5.nabble.com/DependencyResolutionRequiredException-with-maven-artifact-3-0-4-and-maven-archiver-2-5-td5575779.html">Maven Users</a> list, but never answered.<br />
<br />
Solution: Add a dependency on <code>maven-core</code>, or on <code>maven-compat</code> which should handle all compatibility issues with Maven 2. <br />
<br />
Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-41960214403838730152012-08-20T22:36:00.000+02:002012-08-21T09:36:52.045+02:00New OSGi Console in Equinox 3.8.0Equinox 3.8.0, the OSGi framework running Eclipse Juno, comes with a <a href="http://help.eclipse.org/juno/topic/org.eclipse.platform.doc.isv/whatsNew/platform_isv_whatsnew.html?cp=2_2_1#Equinox">new console</a> built on top of <a href="http://felix.apache.org/site/apache-felix-gogo.html">Apache Felix Gogo Shell</a>.<br />
<br />
It is debatable whether or not this is an improvement. Veteran Equinox users are greeted with the following message when trying to activate the console:<br />
<a name='more'></a><br />
<br />
<pre class="Xml" name="code">$ java -Declipse.ignoreApp=true -jar org.eclipse.osgi_3.8.0.v20120529-1548.jar -console -consoleLog
!SESSION 2012-08-20 20:50:05.728 -----------------------------------------------
eclipse.buildId=unknown
java.version=1.7.0_06
java.vendor=Oracle Corporation
BootLoader constants: OS=linux, ARCH=x86_64, WS=gtk, NL=de_DE
Command-line arguments: -console -consoleLog
!ENTRY org.eclipse.osgi 4 0 2012-08-20 20:50:06.182
!MESSAGE Could not find bundle: org.eclipse.equinox.console
!STACK 0
org.osgi.framework.BundleException: Could not find bundle: org.eclipse.equinox.console
at org.eclipse.osgi.framework.internal.core.ConsoleManager.checkForConsoleBundle(ConsoleManager.java:211)
at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(EclipseStarter.java:297)
at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:176)
at org.eclipse.core.runtime.adaptor.EclipseStarter.main(EclipseStarter.java:151)
</pre>
And it's not only <code>org.eclipse.equinox.console</code>, the new console requires a total of four additional bundles:<br />
<pre class="Java" name="code">id State Bundle
0 ACTIVE org.eclipse.osgi_3.8.0.v20120529-1548
1 ACTIVE org.apache.felix.gogo.shell_0.8.0.v201110170705
2 ACTIVE org.eclipse.equinox.console_1.0.0.v20120522-1841
3 ACTIVE org.apache.felix.gogo.runtime_0.8.0.v201108120515
4 ACTIVE org.apache.felix.gogo.command_0.8.0.v201108120515
</pre>
<br />
It is rather sad that Equinox appears to have given up one of its most useful features: the built-in console which is an indispensable tool for debugging startup issues, unsatisfied imports or unavailable services.<br />
<br />
Actually, this is precisely the reason why I never liked working with Felix or Knopflerfish: you are totally blind without additional bundles, which are usually missing in the system you are trying to debug.<br />
<br />
The good news is, Equinox has an undocumented option to enable the built-in console:<br />
<pre class="Java" name="code">-Dosgi.console.enable.builtin=true
</pre>
It would have been so easy to mention this option in the <a href="http://help.eclipse.org/juno/topic/org.eclipse.platform.doc.isv/reference/misc/runtime-options.html?cp=2_1_3_0">reference</a> or the What's New overview...<br />
<br />
Talking about undocumented features, the Gogo Shell itself is virtually undocumented, referring to an unpublished OSGi RFC-147 draft which is only briefly mentioned in the <a href="http://wiki.osgi.org/wiki/RFC_147">OSGi community wiki</a> with a kafkaesque reference to Apache Felix Gogo...<br />
<br />
Now let's have a look at the new Equinox console, based on Gogo shell. What is the first command to try in any shell? <br />
<br />
Correct: <span style="font-family: "Courier New",Courier,monospace;">help</span> <br />
<br />
In Equinox, this command floods your screen with more than 500 lines of partially redundant<br />
<pre class="Java" name="code">sta - start the specified bundle(s)
scope: equinox
parameters:
Bundle[] bundle(s) to start
start - start the specified bundle(s)
scope: equinox
parameters:
Bundle[] bundle(s) to start
</pre>
and partially meaningless information:<br />
<pre class="Java" name="code">gosh
scope: gogo
parameters:
CommandSession
String[]
</pre>
Fortunately, all traditional Equinox console commands have been ported to Gogo and are still available. My personal survival kit of Equinox commands is:<br />
<ul>
<li>ss: short status of all bundles</li>
<li>diag: tells you why a bundle fails to resolve</li>
<li>bundle: all imports and exports and services registered or used by a bundle</li>
<li>services: list services, optionally filtered.</li>
</ul>
Now there is a whole lot of additional commands from Gogo, but I can't say there is anything I have been waiting for.<br />
<br />
The most useful features of the new console are tab completion and command history via arrow keys. Unfortunately, this only works via telnet and not from the Eclipse IDE Console View. To enable telnet access, add a port number argument to the <code>-console</code> option.<br />
<br />
There is some <a href="http://www.eclipse.org/equinox/incubator/console/user-doc.php">user</a> and <a href="http://www.eclipse.org/equinox/incubator/console/design-doc.php">design</a> documentation about the new console in the Equinox incubator. I don't know if this is up to date, and I wonder why none of this made it into the Juno release documentation.<br />
<br />
All in all, the new Equinox console is yet another example of usability impaired by featuritis.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com3tag:blogger.com,1999:blog-7836204352369514180.post-13869679869907392962012-08-08T19:38:00.000+02:002012-08-08T19:38:15.093+02:00Maven Build Info for Web Applications<h3>
Problem</h3>
* You want to include build info like build number, revision number etc. as a web resource in your web applications.<br />
* You have a multi-module Maven project with more than one WAR module and a number of JAR modules.<br />
* You want to minimize copy-and-paste configuration in your POMs.<br />
* The mechanism should not depend on a CI server.<br />
<br />
<h3>
Solution</h3>
This can be achieved using the <a href="http://mojo.codehaus.org/buildnumber-maven-plugin/">Build Number Maven Plugin</a> and the <a href="http://maven.apache.org/plugins/maven-war-plugin/overlays.html">overlay</a> feature of the Maven WAR plugin.<br />
<a name='more'></a><br />
<h4>
buildinfo Module</h4>
Create a new Maven module <code>myproject-buildinfo</code> with <code>war</code> packaging containing nothing but a <code>pom.xml</code> and a resource <code>src/main/webapp/version.txt</code> with the following contents:<br />
<br />
<pre>{
"release" : "${project.version}",
"date" : "${build.date}",
"revision" : "${buildNumber}",
"branch" : "${scmBranch}"
}
</pre>
<br />
The properties in this file shall be interpolated by Maven resource filtering. To make this work, add these definitions to <code>myproject-buildinfo/pom.xml</code>:<br />
<br />
<br />
<pre class="Xml" name="code"><properties>
<maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
<build.date>${maven.build.timestamp}</build.date>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webResources>
<resource>
<directory>src/main/webapp</directory>
<filtering>true</filtering>
</resource>
</webResources>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</pre>
<br />
The Build Number Plugin sets the <code>buildNumber</code> and <code>scmBranch</code> properties after querying your SCM system (Subversion or Git).<br />
<br />
<h4>
Web Application Configuration</h4>
<br />
To include the interpolated build info resource in your web applications, simply add your build info WAR as a dependency to each of your WAR projects:<br />
<br />
<pre class="Xml" name="code"><dependency>
<groupId>${project.groupId}</groupId>
<artifactId>myproject-buildinfo</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
</pre>Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-79733933389353781042012-07-18T23:47:00.000+02:002012-07-18T23:47:10.840+02:00OSGi and CDI Combined<a href="http://team.ops4j.org/wiki/display/PAXCDI/">Pax CDI</a> is a new OPS4J community project I've started to combine the best of OSGi and CDI.<br />
<br />
Once you've worked with CDI or with an up-to-date annotation-based flavour of Spring, the service registry API or XML-based dependency injection in the Blueprint or Declarative Services style suddenly appears rather verbose.<br />
<br />
On the other hand, even though Java EE 6 is more lightweight than ever, its monolithic nature feels rather a burden when you're used to OSGi.<br />
<br />
Why not have the best of both worlds? The idea is not new, it has been implemented to some extent both in <a href="https://github.com/mathieuancelin/weld-osgi">weld-osgi</a> and in the <a href="https://wikis.oracle.com/pages/viewpage.action?pageId=36438159">FighterFish</a> subproject of GlassFish.<br />
<br />
Unlike these two projects, Pax CDI is independent of any given CDI, Java EE or OSGi implementation. The first proof-of-concept release is based on Apache OpenWebBeans and Equinox. In contrast to weld-osgi, which required some modifications in Weld itself, Pax CDI works with an unmodified version of OpenWebBeans.<br />
<br />
Trying to do the same with Weld is one of the next goals for Pax CDI.<br />
<br />
An alpha release Pax CDI 0.1.0 is available from Maven Central.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-57085533158880424442012-06-28T22:53:00.001+02:002012-08-14T20:27:21.641+02:00Fixing Editor Tab Fonts in Eclipse JunoEclipse Juno is out! It starts a good deal faster than Indigo, shows a more colourful (but ill-proportioned) splash screen, and then opens a workbench window with oversized and truncated labels in all editor tabs.<br />
<br />
This applies to Ubuntu 12.04 with KDE and the QtCurve GTK+ theme.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggKypAaWRPOJyU5byWXiRO2QmpcgArnICjyOnn3Wv8gV9vCtU1EICjsaFeAc2YgtwQY5u6U0xgrp2gz-C8PW3bu52nAV3M1dLEW20-oF8YMUb1-MlpO36eTl3D46sQVWig3lFgCTv-ceO4/s1600/JunoUglyFonts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="472" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggKypAaWRPOJyU5byWXiRO2QmpcgArnICjyOnn3Wv8gV9vCtU1EICjsaFeAc2YgtwQY5u6U0xgrp2gz-C8PW3bu52nAV3M1dLEW20-oF8YMUb1-MlpO36eTl3D46sQVWig3lFgCTv-ceO4/s640/JunoUglyFonts.png" width="640" /></a></div>
This issue is not due to QtCurve or SWT, as I had first suspected, but to the new CSS-based widget styling of the e4 platform. There is an <a href="http://wiki.eclipse.org/Eclipse4/CSS">E4 CSS Editor</a> which is not included in Juno by default, but can be installed via the Update Manager.<br />
<br />
With this editor, you can change the <code>font-size</code> and <code>font-family</code> properties of the <code>MPartStack</code> style used by the editor tabs.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkEI9wuFezOAQsrKUQ-9xBmgoXZusi8Lqbu4fesVXcq54gSRCjmjQWd5TP_Cr3anE0dejW4HqYEURHRa6VRa32TkIwFwesDps_p0AwZIrS2MYZmmG4DCBs3-fWsMuygNaOrjDMHq4G70D7/s1600/JunoCssEditor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="540" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkEI9wuFezOAQsrKUQ-9xBmgoXZusi8Lqbu4fesVXcq54gSRCjmjQWd5TP_Cr3anE0dejW4HqYEURHRa6VRa32TkIwFwesDps_p0AwZIrS2MYZmmG4DCBs3-fWsMuygNaOrjDMHq4G70D7/s640/JunoCssEditor.png" width="640" /></a></div>
Much better!<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-cTedzK7D_rkYFi56FjA2mvt1W5Fqa2ZcALYJZMVDBXkXwGGLdoUqLaeElmP0q6Z6jF5GDKVSIvpa5K43vsU8m8v4J_ZIKUJHCoBw7BmXSb0X8IB1JOQ_FZ-C7e3IOhx-DlNUUuAEdUDg/s1600/JunoFixedFonts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br />
<img border="0" height="472" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-cTedzK7D_rkYFi56FjA2mvt1W5Fqa2ZcALYJZMVDBXkXwGGLdoUqLaeElmP0q6Z6jF5GDKVSIvpa5K43vsU8m8v4J_ZIKUJHCoBw7BmXSb0X8IB1JOQ_FZ-C7e3IOhx-DlNUUuAEdUDg/s640/JunoFixedFonts.png" width="640" /></a></div>
<br />
<b>Update 14 Aug 2012:</b> If you develop web applications and edit CSS files in Eclipse, you'd better deinstall the E4 CSS editor after customizing the workbench layout to fall back to the standard WTP CSS editor. The XText-based E4 editor does not recognize some legal syntax like unquoted URLs.<br />
<br />
Actually, you don't need any Eclipse plugin to change the CSS, you can directly edit the CSS file in your Eclipse installation at <code>plugins/org.eclipse.platform_4.2.0.v20120608140/css/e4_default_gtk.css</code>.<br />
<br />
<br />
<br />Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com8tag:blogger.com,1999:blog-7836204352369514180.post-50531547341876509292012-06-25T22:55:00.000+02:002012-06-25T22:55:23.313+02:00Pax JDBC: An OSGi JDBC Service<a href="http://team.ops4j.org/wiki/display/PAXJDBC/Pax+JDBC">Pax JDBC</a> is a new project under the OPS4J umbrella which simplifies the use of JDBC drivers in OSGi applications by providing a <a href="http://team.ops4j.org/wiki/display/PAXJDBC/Generic+Driver+Extender">generic driver extender</a> and various <a href="http://team.ops4j.org/wiki/display/PAXJDBC/Apache+Derby+Driver+Adapter">native driver adapters</a> for your favourite database.<br />
<br />
This project aims at compliance with the OSGi Enterprise Release 5.0 specification.<br />
<br />
Pax JDBC 0.1.0 is available from Maven Central, with native adapters for Apache Derby and PostgreSQL. Since this first release, support for H2 and MySQL has been added, and further contributions are always welcome.<br />
<br />Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com4tag:blogger.com,1999:blog-7836204352369514180.post-48190044531909563492012-05-24T20:25:00.000+02:002012-05-24T20:25:17.563+02:00OSGi, Java EE and CDI Integration Testing with Pax Exam 3In-container testing is an approach shared by many testing frameworks like <a href="http://team.ops4j.org/wiki/display/paxexam">Pax Exam</a>, <a href="http://code.google.com/p/jeeunit/">jeeunit</a>, <a href="http://arquillian.org/">Arquillian</a> and <a href="http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/testing.html#testcontext-tx">Spring's test context</a>.<br />
<br />
Pax Exam 2.x is a mature solution for testing OSGi bundles and applications, jeeunit was created to simplify Java EE 6 integration testing and has been extended to handle stand-alone CDI applications and non-CDI setups based on Tomcat and Spring.<br />
<br />
Taking the best of both worlds, the next major release line Pax Exam 3.x is designed to provide a unified testing experience by incorporating additional test containers for Java EE and CDI from jeeunit while staying backward compatible with Pax Exam 2.x for OSGi.<br />
<br />
The first public milestone release Pax Exam 3.0.0.M1 is now available from The Central Repository (aka Maven Central), including test containers for <b>GlassFish, OpenWebBeans and Weld</b>.<br />
<br />
While jeeunit works with Embedded GlassFish which lacks all OSGi capabilities of the GlassFish server, the Pax Exam GlassFish Container launches GlassFish 3.1.2 on top of an OSGi framework, enabling users to deploy or provision both WAR modules and OSGi bundles, thus providing a test environment for hybrid Java EE/OSGi applications.<br />
<br />
A plain old JUnit test class can be turned into an in-container integration test simply by adding a <code>@RunWith(PaxExam.class)</code> annoation and some configuration data in a properties file.<br />
<br />
See the <a href="http://team.ops4j.org/wiki/display/paxexam/2012/05/24/Pax+Exam+3.0.0.M1+Released">Pax Exam 3.0.0.M1 Release Notes</a> for more details and use the OPS4J mailing list (general@lists.ops4j.org) for feedback and support.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-31478839680633120882012-05-01T18:56:00.000+02:002012-05-01T18:56:36.796+02:00Deconstructing Spring mythsOver the past five years, I have had the pleasure of working on different Java enterprise projects based on OSGi, Java EE and Spring. Among these three platforms, Spring is the one I'm least happy with. <br />
<br />
Granted, Spring lets you build complex enterprise applications without too much pain, or else it wouldn't be so popular. In the times of J2EE 1.4, Spring must have felt like a breath of fresh air, and without the competition of Spring and Hibernate, J2EE might not have evolved into what Java EE 6 is today.<br />
<br />
But somehow the glory of Spring's founding myth of <i>killing the beast that was J2EE</i> seems to be fading. The former beast is now as manageable and easy to use as Spring ever was, or even more so. Dependency Injection in Java is no longer synonymous with Spring (and in fact never was).<br />
<br />
The Spring Framework needs a new <i>raison d'ĂȘtre</i>, and the current strategy seems to be diversification: Projects like Spring Data or Spring Social offer new features that have no equivalent in Java EE or OSGi. And of course, any Spring XYZ project requires the Spring Framework. But looking at the capabilities of the Spring Framework itself, where are the killer features?<br />
<br />
Does Spring provide solutions that are smarter or easier to use than equivalent constructs in Java EE?<br />
<br />
Here is a list of reasons why I feel more productive on Java EE 6 than on Spring 3.1.<br />
<br />
<h3>There is no Spring without Java EE</h3><br />
Most debates about Java EE vs Spring sound like an either-or question, but this is a misconception. You can build an application on Java EE without ever using a Spring API, but you can't really build an enterprise application on Spring without using a number of Java EE APIs and implementations.<br />
<br />
A typical Spring-based application includes<br />
<br />
<ul><li>a web container, usually Tomcat, which means Servlet, JSP, EL, all of which is Java EE</li>
<li>a service layer, which has the highest chance of being Spring-only, with Spring transactions and Spring dependency injection</li>
<li>some web service endpoints, most likely JAX-RS or JAX-WS, which means Java EE again</li>
<li>a persistence layer, traditionally Hibernate Native API + Spring templates, but these days there's really no reason for preferring vendor-specific APIs over JPA 2.0 </li>
<li>some messaging, e.g. with ActiveMQ, which means JMS and thus Java EE again.</li>
</ul><br />
Thus, Spring and Java EE applications mostly differ in the following areas only:<br />
<ul><li>the web framework (Spring MVC vs. JSF vs. Wicket vs. Vaadin vs. Struts vs.....)</li>
<li>Spring Beans vs. EJB</li>
<li>Spring Dependency Injection vs. CDI or Java EE 5 <code>@EJB</code> or <code>@Resource</code> injection</li>
</ul><br />
In the age of AJAX and component-oriented web frameworks, Spring MVC feels rather old-school. JSF 2.1 has a lot more to offer, and if you prefer an independent web framework like Vaadin, the underlying container does not matter anyway.<br />
<br />
Who's afraid of EJBs? All you need is a <code>@Stateless</code> annotation on your Java class, and you get a thread-safe service where all public methods are transactional by default, which is just what you need in most cases.<br />
<br />
And finally, CDI is much more powerful that Spring Dependency Injection, due to its seamless scope handling, its event model and its portable extension mechanism.<br />
<br />
<h3>API vs. Implementation</h3><br />
Spring has no clear separation of API and implementation, neither at specification level nor at code level. The Spring Reference Manual documents the one and only Spring Framework implementation. The Spring Javadocs document each and every class contained in the Spring Framework. It is not easy to distinguish API level classes from container internal classes.<br />
<br />
By contrast, Java EE is first and foremost a set of specifications, represented by a collection of thin API JARs or an all-in-one <code>javaee-api.jar</code>. There are different independent implementations by different providers. Provider specific implementation classes are not normally visible to the user.<br />
<br />
<h3>Vendor Lock-In</h3><br />
Competition is a good thing. When you are having an issue with your application running on a given Java EE server, try another server. This will give you some insight whether or not the issue is caused by your application or the server.<br />
<br />
With Spring, there's only Spring. You can't swap framework components. You can't even cherry-pick framework components. There is insufficient separation of concerns. Inherently, there is no reason why a web framework or a NoSQL persistence provider should have to be tied to a given dependency injection container. But you can't use Spring MVC or Spring Data without Spring Core, just like you can't run Microsoft SQL Server without Microsoft Windows.<br />
<br />
<h3>JAR Hell</h3><br />
Java EE means one-stop shopping for the core functionality of an enterprise software stack. <code>javaee-api.jar</code> provides the interfaces you need to start developing your own applications. All the required runtime environment is provided by the application server. <br />
<br />
Yes, the application server runtime does contain a lot of stuff you'll never need. But modern servers like GlassFish 3.x or JBoss AS7 are modular and lazily activate only the stuff you do need, so there is no runtime overhead. And even a monolithic server like Resin 4.x has a surprisingly small footprint.<br />
<br />
My current project is a Spring web application deployed on Tomcat. The final WAR has more than 100 JARs in <code>WEB-INF/lib</code>. More than 30 of these JARs are due to Spring itself, its dependencies or other Java EE components not provided by Tomcat.<br />
<br />
In other words, by moving from Spring to Java EE, I could drop a third of the dependencies of my application. And I'm not talking about saving 30 megabytes of disk space, but about the effort of maintaining these dependencies and resolving version conflicts of transitive dependencies.<br />
<br />
<h3>Configuration Hell</h3><br />
The flip side of JAR hell is configuration hell. With Spring, once you have gathered all required components, you also need to configure them. You may get away with an automatic component scan for your own application beans, but there is always a certain amount of manual plumbing for setting up framework beans, and standard features like transaction management or property substitution have to be enabled explicitly.<br />
<br />
Most Spring-based projects started before 2010 still use XML configuration which for my taste is hard to read, extremely verbose and hard to refactor. Spring 3.0 first introduced Java configuration as an alternative but left it unfinished. Spring 3.1 finally supports type-safe Java-only configurations. Unfortunately, the reference manual and Spring extensions like Spring Security still promote XML configuration and leave it to the user to figure out the Java equivalents, which can be rather challenging, especially when custom Spring XML namespaces are involved.<br />
<br />
With Java EE 6, little or no configuration is required. Transaction management works out of the box. Use an empty <code>beans.xml</code> marker file to enable CDI. Define the data sources and connections pools for your application in your application server's administration console. That's it.<br />
<br />
<h3>Thread Safety</h3><br />
Spring leaves thread safety up to you. Controllers and services have singleton scope by default, so you can't use instance variables, or you need to protect them explicitly.<br />
<br />
With Java EE, stateless EJB are pooled, concurrent requests each get served by a new beans from the pool, so your beans are thread-safe by default, unless you modify static members or global singletons.<br />
<br />
<h3>Singleton Antipattern</h3><br />
The fact that Spring beans are singletons and not thread-safe by default tends to promote a rather ugly procedural programming style. Suppose you have a service with one public method performing some non-trivial business logic, factored out into a number of private methods.<br />
<br />
In a stateless EJB, your private methods can share state in member variables <i>within the same request</i> (i.e. public method call), so in fact, the EJB is not quite as stateless as it may appear.<br />
<br />
In a Spring bean, you often see private methods with long parameters lists, since you cannot share state in member variables, so you have to pass it around in method arguments. <br />
<br />
<h3>Mixing Scopes</h3><br />
Due to these issues with singleton Spring beans, you may want to use the prototype scope, or the request scope in web applications.<br />
<br />
Now when you inject a protoype or request scope bean into a singleton bean, Spring does not by default do the right thing to ensure that the injected bean is indeed a different instance per request. You need to resort to method injection or configure a scoped proxy explicitly.<br />
<br />
CDI, on other hand, automatically proxies injected beans when needed.<br />
<br />
<h3>Transactions</h3><br />
Spring itself does not provide global transactions across multiple resources. It can delegate to a JTA transaction manager but does not provide its own implementation.<br />
<br />
Working with two or more persistence units in the same application, you need to configure a transaction manager per persistence unit and reference the correct instance in the <code>@Transactional</code> annotation of your service class or method.<br />
<br />
In Java EE, transactions are managed by the container by default. EJBs are transactional by default. The container can handle multiple persistence units without further configuration. Global transactions spanning multiple datasources work out of the box if you configure XA datasources.<br />
<br />
<h3>Load Time Weaving</h3><br />
Some persistence providers require load time weaving, also known as byte code enhancement. The JPA specification defines a hook for this purpose in <a href="http://docs.oracle.com/javaee/6/api/javax/persistence/spi/PersistenceUnitInfo.html#addTransformer%28javax.persistence.spi.ClassTransformer%29">PersistenceUnitInfo.addTransformer()</a>.<br />
<br />
With OpenJPA and GlassFish, this works like a charm. Using OpenJPA with Spring and Tomcat, the required set-up is <a href="http://www.vodori.com/blog/setting-up-openjpa2-for-junit-maven-3-and-tomcat.html">rather a nightmare</a>, so I ended up using build-time enhancement, which is a lot easier to configure, but still requires additional manual configuration.<br />
<br />
<br />
<h3>Summary</h3><br />
Spring has had its merits in giving relief to frustrated J2EE developers. But this is 2012 - compared to Spring, Java EE 6 now provides equivalent or better solutions for most standard tasks in enterprise application development.<br />
<br />
Both Java EE and Spring are <a href="http://hwellmann.blogspot.de/2010/11/java-ee-and-spring-why-i-couldnt-care.html">far from perfect</a>. All in all, Java EE is more integrated and easier to use - not by orders of magnitude, but noticeably so.<br />
<br />
And none of this is an eternal truth, tables may turn again within a few years.<br />
<br />
<br />Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com12tag:blogger.com,1999:blog-7836204352369514180.post-31888056679858646252012-04-29T20:06:00.000+02:002012-04-29T20:06:36.914+02:00Metamodel classes for OpenJPA with Maven, Eclipse and m2eMetamodel classes are a not-so-well known feature of the JPA 2.0 standard. They allow you to write typesafe criteria queries using metamodel attributes instead of plain old strings to reference entity fields. (See <a href="http://www.ibm.com/developerworks/java/library/j-typesafejpa/">this tutorial</a> for some more background.)<br />
<br />
Metamodel classes are generated by an annotation processor during the build process, but this is not enabled by default. OpenJPA logs a runtime warning when you build a criteria query and the metamodel classes cannot be found. So even if you don't use the metamodel, you may want to generate it just to get rid of this warning.<br />
<br />
This article explains how to generate the metamodel both in Maven batch builds and in the Eclipse workspace.<br />
<br />
<a name='more'></a><br />
According to the <a href="http://openjpa.apache.org/builds/2.2.0/apache-openjpa/docs/manual.html#d5e5275">OpenJPA Manual</a>, the following POM snippet should be sufficient to generate the metamodel:<br />
<br />
<pre class="Xml" name="code"><plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Aopenjpa.metamodel=true -Aopenjpa.log=TRACE</compilerArgument>
</configuration>
</plugin>
</pre><br />
Unfortunately, this does not work due to a <a href="http://jira.codehaus.org/browse/MCOMPILER-130">bug in the Maven Compiler Plugin</a>, which does not handle multiple compiler arguments correctly - the alternative configuration element <code><compilerArguments></code> (note the plural) does not work either. So make sure to use only one compiler argument without any blank spaces (the log option is not required anyway):<br />
<br />
<pre class="Xml" name="code"><compilerArgument>-Aopenjpa.metamodel=true</compilerArgument>
</pre><br />
After this change, the OpenJPA annotation processor should be triggered when running <code>mvn compile</code>.<br />
<br />
You may now hit the next problem with the following exception:<br />
<pre>java.lang.ClassCastException: com.sun.tools.javac.code.Symbol$PackageSymbol
cannot be cast to javax.lang.model.element.TypeElement
</pre><br />
which is caused by the OpenJPA annotation processor choking on a <code>package-info.java</code> file. This is a <a href="https://issues.apache.org/jira/browse/OPENJPA-1965">bug fixed in OpenJPA 2.2.0</a>, so if you see this exception, upgrade OpenJPA or delete any <code>package-info.java</code>.<br />
<br />
If you don't work with Eclipse, this is all you need to know.<br />
<br />
For Eclipse + m2e users, some more tweaking is required, as the Eclipse Java compiler does not pick up the annotation processor option automatically. The preferred solution, an m2e extension for annotation processing, is not yet available, and the best approach I've found so far is not really straightforward but nonetheless effective. It requires three steps:<br />
<br />
<ul><li>Annotation processing is performed by the <a href="http://maven-annotation-plugin.googlecode.com/svn/docs/usage.html">Maven Processor Plugin</a> in the <code>generate-sources</code> phase.</li>
<li>The directory with the generated sources is made known to the compiler with the <a href="http://mojo.codehaus.org/build-helper-maven-plugin/usage.html">Maven Build Helper Plugin</a>.</li>
<li>This directory will be picked up by the Eclipse compiler when the <b>m2e buildhelper connector</b> is installed.</li>
</ul><br />
So first of all, install the m2e buildhelper connector via <b>Window | Preferences | Maven | Discovery | Open Catalog</b>. Then <b>remove</b> the <code><compilerArgument></code> from the <code>maven-compiler-plugin</code> configuration and add the following to your POM:<br />
<br />
<pre class="Xml" name="code"><plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<version>2.0.5</version>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<processors>
<processor>org.apache.openjpa.persistence.meta.AnnotationProcessor6</processor>
</processors>
<optionMap>
<openjpa.metamodel>true</openjpa.metamodel>
</optionMap>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/apt</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</pre><br />
Then run <b>Maven | Update Project Configuration</b> from the context menu of your Eclipse project. The metamodel classes will now be generated whenever Eclipse rebuilds your project.<br />
<br />
<br />
<br />Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com7tag:blogger.com,1999:blog-7836204352369514180.post-46666635340344429112012-04-15T20:49:00.000+02:002012-04-15T20:49:16.393+02:00Multi-Instance Deployment from Eclipse to Tomcat<h3> Problem</h3><ul><li>You are developing a web application for Tomcat in Eclipse.</li>
<li>You want to deploy multiple instances of the same application with different configurations directly from your workspace.</li>
<li>Of course, you don't want to duplicate any projects in your workspace.</li>
</ul><br />
<h3>Solution</h3><br />
This scenario can be solved quite easily with the vanilla Apache Tomcat adapter of Eclipse WTP. There is no need for any additional Eclipse plugins.<br />
<a name='more'></a><br />
<h4>Background on Eclipse WTP</h4><br />
Eclipse Web Tools Platform (WTP) is an Eclipse subproject providing plugins for web application delevelopment. It is bundled with with Eclipse IDE for Java EE Developers and can be installed on top of other editions.<br />
<br />
Using Eclipse WTP, you can run and debug your project in a servlet container directly from your Eclipse workspace. Apache Tomcat is supported by WTP out of the box. For other servlet containers or full-blown application servers like GlassFish or JBoss, you need to install a server adapter plugin.<br />
<br />
If your project is built with Maven, you should also install m2e und m2e-wtp.<br />
<br />
<h4>Configuring a Tomcat Server for Eclipse</h4><br />
All Eclipse WTP server adapters require a stand-alone server installation, outside of Eclipse, e.g. <code>/opt/apache-tomcat-6.0.32</code>.<br />
<br />
In Eclipse, create a Tomcat Server via <strong>Preferences | Server | Runtime Environment | Add... | Apache Tomcat v6.0</strong>, click <strong>Next</strong> and enter your Tomcat installation directory.<br />
<br />
Opening the Servers view, you'll now see a <i>Tomcat v6.0 Server at localhost</i>. Double-click on this entry to open a form editor with additional settings.<br />
<br />
The <b>Server Locations</b> section has three different options. If none of them is activated, go to the <b>Servers</b> view, delete all modules on the server and select <b>Publish</b> from the context menu.<br />
<br />
These options define the location for web applications and Tomcat configuration files published by Eclipse WTP:<br />
<br />
<ol><li>a directory in the Eclipse workspace (something like <code>.metadata/.plugins/org.eclipse.wst.server.core/tmp0</code>)</li>
<li>directly in your local Tomcat installation</li>
<li>any other directory outside of Tomcat or Eclipse</li>
</ol>Using option 3, you are completely independent of your Tomcat installation, whereas option 2 comes with a risk of modifying some installation configuration, which comes with option 2.<br />
<br />
Under <b>Server Options</b>, make sure to check <b>Publish module contexts to separate XML files</b>. With this setting, Eclipse WTP stores each web application configuration in a separate file under <code>conf/Catalina/localhost</code>.<br />
<br />
<h4>Configuring your web applications</h4><br />
In Tomcat, a web application is usually configured by a <code>context.xml</code> configuration file located in <code>${catalina.base/conf/Catalina/localhost</code>. A web resource <code>META-INF/context.xml</code> <i>inside</i> the web application has the same effect. For a Maven project, make sure to place this file in <code>src/main/webapp/META-INF</code> and not in <code>src/main/resources/META-INF</code>.<br />
<br />
<h4>Multiple instances of a web application</h4><br />
Using Eclipse WTP, you can run multiple instances of the same web application on Tomcat directly from the workspace. Any changes to Java sources or web resources in the workspace are directly published to all running instances.<br />
<br />
For example, let's take a web project <code>myweb</code> which we'd like to run in its default configuration and in an alternative configuration as <code>myweb2</code>. We assume the server location to be <code>/opt/wtp</code> (see option 3 above).<br />
<br />
Now we simply copy the modified <code>context.xml</code> for <code>myweb2</code> to <code>/opt/wtp/conf/Catalina/localhost/myweb2.xml</code> and let the <code>docBase</code> attribute in this configuration point to the same directory as for <code>myweb</code>:<br />
<br />
<br />
<pre class="Xml" name="code"><Context docBase="/opt/wtp/wtpwebapps/myweb" reloadable="true">
...
</Context>
</pre><br />
If we now start the project <code>myweb</code> via the context menu <b>Run As | Run on Server</b>, Eclipse WTP will launch two instances of our web app under the following URLs<br />
<br />
<pre>http://localhost:8080/myweb/
http://localhost:8080/myweb2/
</pre><br />
The context path of a web application is the project name by default. If you want to change <code>myweb</code> to <code>myweb1</code>, you can set the context root under <code>Project Properties | Web Project Settings</code>. For a Maven project under <code>m2e-wtp</code>, set the property <code>m2eclipse.wtp.contextRoot</code> in your POM.<br />
<br />
The same approach can be used to launch non-workspace applications together with your workspace application in the same Tomcat instance. Simply copy the WAR to <code>/opt/wtp/webapps/foo.war</code> and the context file to <code>/opt/wtp/conf/Catalina/localhost/foo.xml</code>.<br />
<br />
<h4>See also</h4><br />
<a href="http://wiki.eclipse.org/WTP_Tomcat_FAQ">WTP Tomcat FAQ</a><br />
<a href="https://github.com/sonatype/m2eclipse-wtp/wiki/Frequently-Asked-Questions">m2e-wtp FAQ</a><br />
<br />Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-5721822365055607132012-01-25T22:17:00.000+01:002012-01-25T23:43:57.317+01:00Integration Testing for JBoss AS7, Tomcat and Weld SEInitially, the <a href="http://code.google.com/p/jeeunit/">jeeunit</a> Integration Testing framework was exclusively focused on Java EE 6, supporting GlassFish 3.x, which was the only Java EE 6 compliant server at that time. Support for Resin 4.x has been added in subsequent releases. <br />
<br />
With the current release 0.9.1, jeeunit supports JBoss AS 7, as well as alternative containers and injection methods beyond the scope of Java EE 6. You can now run jeeunit tests on Tomcat 6 and 7 and Weld SE containers.<br />
<br />
Tomcat can be combined either with Spring 3.1 or with CDI (Weld Servlet) to inject dependencies into jeeunit tests.<br />
<br />
And there's more to come: While jeeunit will continue a life of its own for a while, I'm planning to merge it step by step into <a href="http://team.ops4j.org/wiki/display/paxexam/">Pax Exam</a>, the OSGi testing framework of the <a href="http://team.ops4j.org">OPS4J</a> community.<br />
<br />
Pax Exam and jeeunit both implement an in-container testing approach - while Pax Exam focuses on OSGi alone, jeeunit now supports various other containers, but no OSGi at all. <br />
<br />
The Pax Exam/jeeunit merger opens interesting perspectives for hybrid applications, i.e. enterprise applications composed of traditional WARs and OSGi bundles. GlassFish 3.x supports this hybrid application model, implementing a subset of the OSGi Enterprise specifications. <br />
<br />
For Pax Exam, the road towards the next major release 3.0.0 will be marked by a sequence of milestone releases, each of which is to incoporate a new container adapted from jeeunit.<br />
<br />
A Pax Exam GlassFish Test Container is the goal of the first proof-of-concept milestone 3.0.0.M1. This is work in progress on a dedicated branch <a href="https://github.com/ops4j/org.ops4j.pax.exam2/tree/exam3-milestones">exam3-milestones</a> in the Pax Exam GitHub repository.<br />
<br />
Stay tuned...Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com2tag:blogger.com,1999:blog-7836204352369514180.post-15631539773807129802012-01-03T19:21:00.000+01:002012-01-03T19:24:46.871+01:00Troubleshooting VisualVM Remote ConnectionsI was trying to use VisualVM to monitor the memory usage of a build job on our build server. According to the <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/applications_remote.html">documentation</a>, this should require nothing but a <a href="http://docs.oracle.com/javase/6/docs/technotes/tools/share/jstatd.html">jstatd</a> daemon running on the remote machine. <br />
<br />
For some reason, I could not see any remote applications in my local VisualVM. It was not a port issue, all the required ports were reachable via telnet.<br />
<br />
Googling around, <a href="http://hillert.blogspot.com/2010/01/remote-profiling-of-jboss-using.html">this article</a> finally gave my the important clue: Our network does not have consistent DNS names, so I had to connect to the remote machine via IP address. Setting the <code>java.rmi.server.hostname</code> property for <code>jstatd</code> to the IP address solved the problem.<br />
<br />
<h3>Summary</h3><br />
<h4>On the remote machine</h4><b>Create policy file for jstatd</b><br />
<br />
<pre>grant codebase "file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
</pre><br />
<b>Start jstatd with this hostname file and the IP address as hostname</b><br />
<br />
<pre>jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.0.123
</pre><br />
<h4>On the local machine</h4>Start <code>jvisualvm</code> and add a Remote Host with the given IP address. A jstatd connection will be established by default. You should now see your remote applications.<br />
<br />Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com1tag:blogger.com,1999:blog-7836204352369514180.post-21660428250347681552011-12-21T11:01:00.000+01:002011-12-21T19:47:06.404+01:00Spring Integration Tests with Real TransactionsSpring's Test Context has a <code>@Transactional</code> annotation for wrapping tests in a transaction started and rolled back by the test container, to keep the tests from modifying the database. This is just what you need for deterministic, repeatable database tests.<br />
<br />
On the other hand, due to this approach, the transaction boundaries in your test system differ from the ones in your production system, which can lead to errors in production which were never noticed in your tests suites.<br />
<br />
I wouldn't go as far as saying that transactional tests should be <a href="http://www.javacodegeeks.com/2011/12/spring-pitfalls-transactional-tests.html">considered harmful</a>, but at least you should be aware of the side effects which may or may not be harmless in your specific use case.<br />
<br />
For tests with real transactions, you need to take care of cleaning up the database yourself.<br />
<br />
<a href="http://kentbeck.github.com/junit/javadoc/latest/org/junit/Rule.html">JUnit rules</a> are a neat way of doing this. Here is an example:<br />
<a name='more'></a><br />
<br />
<h3>
Using the CleanDatabaseRule</h3>
<br />
<pre class="Java" name="code">@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/META-INF/spring/test-context.xml")
public class RealTransactionTest {
@Rule
@Inject
public CleanDatabaseRule cleanDatabase;
@Inject
private UserDao userDao;
@Test
public void testFindUsers() {
userDao.createUsers("wilma", secret);
assertThat(userDao.findAllUsers().size(), is(1));
}
}
</pre>
<br />
This test class has the usual <code>@RunWith</code> and <code>@ContextConfiguration</code> annotations, to enable the Spring Test Context, but the <code>@Transactional</code> annotation is missing<br />
<br />
The <code>CleanDatabaseRule</code> is marked with <code>@Rule</code>. JUnit requires all rule members to be public. Given that our rule internally works with a persistence unit to be injected by Spring, the rule itself is configured as a singleton Spring bean to be injected into our test class.<br />
<br />
This rule takes care of deleting all database content before and after each test method.<br />
<br />
<h3>
CleanDatabaseRule Implementation</h3>
<br />
Our <code>CleanDatabaseRule</code> extends JUnit's <code>ExternalResourceRule</code> which has <code>before()</code> and <code>after()</code> methods for dealing with a given external resource (the database in our case) before and after running a test method.<br />
<br />
The level of cleanup performed by this rule is up to you: you can drop the database and create a new one, you can restore a given database dump, or simply truncate all tables, which is what I'm doing here.<br />
<br />
The following example uses MySQL syntax to disable all foreign keys before deleting the tables:<br />
<br />
<pre class="Java" name="code">public class CleanDatabaseRule extends ExternalResource {
@PersistenceUnit
private EntityManagerFactory emf;
@Override
protected void before() {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// disable foreign keys
em.createNativeQuery("SET FOREIGN_KEY_CHECKS = 0").executeUpdate();
truncateTables(em);
// reenable foreign keys
em.createNativeQuery("SET FOREIGN_KEY_CHECKS = 1").executeUpdate();
em.getTransaction().commit();
}
@Override
protected void after() {
before();
}
}
</pre>
<br />
Note that we're injecting an <code>EntityManagerFactory</code> via <code>@PersistenceUnit</code> instead of the usual <code>EntityManager</code> This is because the entity managers injected by Spring do not permit manual transactions. Using an <code>EntityManagerFactory</code>, we can create our own <code>EntityManager</code> and control or own transactions. <br />
<br />
In a database schema with lots of foreign key constraints, it is useful to disable them while cleaning up, to avoid the headache of having to delete tables in the correct order.<br />
<br />
The <code>truncateTables()</code> method is left as an exercise. :-)Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com3tag:blogger.com,1999:blog-7836204352369514180.post-72668162957082486022011-12-02T19:23:00.001+01:002011-12-02T19:42:04.586+01:00XVisitor: Visitor Pattern for JAXB<a href="http://team.ops4j.org/wiki/display/XVISITOR/">XVisitor</a> is a plugin for the <a href="http://download.oracle.com/javase/6/docs/technotes/tools/share/xjc.html">xjc</a> code generator to enrich the <a href="http://jaxb.java.net/guide/">JAXB</a> model
generated from an XML schema so that users can work with the Visitor
pattern on this model.<br />
<br />
<a name='more'></a>Working with large XML documents is a significant part of my job at the moment, and I've found that both JAXB and the Visitor pattern provide useful type-safe abstractions compared to working with DOM and XPath only. This was the motivation for creating XVisitor as an open source project with an Apache License.<br /><br />
<br />
XVisitor is hosted by the <a href="http://team.ops4j.org/wiki/display/ops4j/">OPS4J</a> community, which offers first class infrastructure for Apache-licensed Java projects, including Confluence, GitHub, Hudson, JIRA and Maven Central releases.<br />
<br />
For more details about XVisitor, check out the <a href="http://team.ops4j.org/wiki/display/XVISITOR/">wiki</a>.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-5687959381438150472011-11-16T20:51:00.001+01:002011-11-16T21:08:30.740+01:00Eclipse Performance on KDE and Ubuntu 11.10If you suffer from poor graphics performance when using Eclipse under KDE, especially when scrolling large trees, check your GTK+ Style.<br />
<br />
After changing the style from oxygen-gtk to QtCurve, my Eclipse is now running on steroids.<br />
<br />
I'm using Eclipse Indigo 3.7.1 on Kubuntu 11.10 amd64 with Oracle JDK 1.6.0_26 and an NVIDIA GeForce 8400 GS graphics adapter. I never used to have any issues on Kubuntu 10.04 LTS which is still running smoothly on another partition of my disk.<br />
<br />
I had suspected the NVIDIA drivers, tried different JREs (including 32 bit versions) and Eclipse releases, none of which made a difference.<br />
<br />
Finally, changing various configuration options by trial and error, I found out that <code>oxygen-gtk</code> seemed to be the cause.<br />
<br />
To optimize your installation, install the <code>qtcurve</code> package, and select it in <b>K Menu | System Settings | Appearance | GTK+ Appearance | Widget Style</b>. Then restart Eclipse and enjoy.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com1tag:blogger.com,1999:blog-7836204352369514180.post-87030801865424439512011-10-23T20:49:00.001+02:002011-10-24T22:34:12.125+02:00JBoss AS 7: Catching up with Java EE 6<style type="text/css">
table.content {
border-collapse: collapse;
border-width: thin;
border-style: solid;
}
table.content td, table.content th {
padding: 5px;
margin: 0px;
border-width: thin;
border-style: solid;
}
</style><br />
<br />
In my <a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison.html">Java EE 6 server comparison</a> of June 2011, JBoss AS 6.0.0 was not exactly the shining star, both in terms of performance and usability.<br />
<br />
The next major release JBoss AS 7, claiming to be <i>lightning fast</i>, was published in July 2011, followed by two maintenance updates in August and September.<br />
<br />
Time to take another look at JBoss and check if it now compares more favourably to other servers.<br />
<a name='more'></a><br />
This post is based on JBoss AS 7.0.2 (Full Profile) and the same real-world application which I had ported from Spring to Java EE 6 for the GlassFish/Resin/JBoss AS 6 comparison.<br />
<br />
With some minor modifications, I was able to deploy the same WAR on JBoss AS 7 and to repeat the measurements I did for JBoss AS 6. <br />
<br />
Compared to JBoss AS 6 which did not even offer a Getting Started Guide, the documentation of JBoss AS 7 has improved a lot, but there are still quite a few gaps to be closed. At any rate I found sufficient input for my experiments in the following two documents:<br />
<br />
<ul><li><a href="https://docs.jboss.org/author/display/AS7/Getting+Started+Developing+Applications+Guide">Getting Started Developing Applications Guide</a></li>
<li><a href="https://docs.jboss.org/author/display/AS7/How+do+I+migrate+my+application+from+AS5+or+AS6+to+AS7Getting%20Started%20Developing%20Applications%20Guide">Migration Guide</a><br />
</li>
</ul><br />
<h3>Preparing the server</h3>My application contains a JPA 2.0 persistence unit developed on Hibernate 3.6.x and MySQL 5.1, so first of all I had to configure the data source and the JDBC driver.<br />
<br />
To do so, I added this section to the main configuration file of JBoss AS 7 in <code>standalone/configuration/standalone.xml</code>:<br />
<br />
<pre class="Xml" name="code"><datasource jndi-name="jdbc/myapp" pool-name="myapp" enabled="true" jta="true" use-java-context="true" use-ccm="true">
<connection-url>
jdbc:mysql://localhost/myapp
</connection-url>
<driver-class>
com.mysql.jdbc.Driver
</driver-class>
<driver>
mysql-connector-java-5.1.13.jar
</driver>
<transaction-isolation>
TRANSACTION_READ_COMMITTED
</transaction-isolation>
<pool>
<min-pool-size>
4
</min-pool-size>
<max-pool-size>
30
</max-pool-size>
<prefill>
true
</prefill>
<use-strict-min>
false
</use-strict-min>
<flush-strategy>
FailingConnectionOnly
</flush-strategy>
</pool>
<security>
<user-name>
MYUSER
</user-name>
<password>
SECRET
</password>
</security>
</datasource>
<drivers>
<driver name="mysql-connector-java-5.1.13.jar" module="com.mysql"/>
</drivers>
</pre><br />
Then I copied both the JDBC driver <code>mysql-connector-java-5.1.13.jar</code> and my application <code>myapp.war</code> to <code>standalone/deployments/</code> and started the server via<br />
<br />
<pre name="code">bin/standalone.sh
</pre><br />
<h3>Troubleshooting</h3><br />
Of course, this did not work out of the box. The first exception I had was<br />
<br />
<pre name="code">java.lang.ClassCastException: org.dom4j.DocumentFactory cannot be cast to org.dom4j.DocumentFactory
</pre><br />
This looked like a classloader conflict for dom4j. My WAR has a dom4j.jar in its WEB-INF/lib, but dom4j is also provided by JBoss as an transitive dependency of Hibernate. To resolve the conflict, I rebuilt my WAR without dom4j.<br />
<br />
The next exception was<br />
<br />
<pre name="code">java.lang.ClassNotFoundException: com.sun.xml.bind.Locatable
</pre><br />
My original application included jaxb-impl-2.2.2.jar, which I'd had to remove for JBoss AS 6, so I re-added this dependency to my WAR and redeployed it.<br />
<br />
JBoss AS 7 marks any failed deployment with a <code>foo.war.failed</code> file in the deployment directory and will not attempt to redeploy the application until the marker file is deleted.<br />
<br />
After restarting the server, the next problem was a <br />
<br />
<pre name="code">org.jboss.weld.exceptions.DeploymentException: WELD-001408 Unsatisfied dependencies for type [MyType] with qualifiers [@Default]
at injection point [[field] @Inject private MyClient.myType]
</pre><br />
This was confusing. I had <code>beans.xml</code> files in all my application modules, and the same WAR did not cause any CDI exceptions on other servers. So I enabled DEBUG logging for Weld to find out what was going on by adding<br />
<br />
<pre class="Xml" name="code"><logger category="org.jboss.weld">
<level name="DEBUG"/>
</logger>
</pre><br />
to the logging section of <code>standalone.xml</code>. This did not have the desired effect. I also had to change the <br />
<br />
<pre class="Xml" name="code"><level name="INFO"/>
</pre><br />
child elements of the <code>console-handler</code> and the <code>periodic-rotating-file-handler</code> from <code>INFO</code> to <code>ALL</code>. (The <a href="https://docs.jboss.org/author/display/AS7/Logging+configuration">Logging Configuration</a> documentation does not mention this, but some additional information is hidden in the <a href="https://docs.jboss.org/author/display/AS7/Getting+Started+Guide">Getting Started Guide</a>, section <i>Configure Logging in JBoss Application Server 7</i>.)<br />
<br />
Now the <code>DEBUG</code> output from Weld revealed the cause of the problem:<br />
<br />
<pre name="code">17:33:39,799 DEBUG [org.jboss.weld.ClassLoading] (MSC service thread 1-8) WELD-000119 Not generating any bean definitions
from MyType because of underlying class loading error
Caused by: java.lang.NoClassDefFoundError: Lorg/dom4j/Document;
</pre><br />
Strange, dom4j had caused a classloader conflict at first, and now it was no longer visible at all? I had a closer look at <a href="https://docs.jboss.org/author/display/AS7/Class+Loading+in+AS7">Class Loading in AS7</a> to understand the background of this. <br />
<br />
In short, JBoss AS 7 has a module structure, and server modules are not visible to applications by default, unless they are imported or exported explicitly.<br />
<br />
Both dom4j and jaxb-impl are JBoss modules, so I re-deleted jaxb-impl and jaxb-api from my application and made the JBoss modules globally visible by adding the following to <code>standalone.xml</code>:<br />
<br />
<pre class="Xml" name="code"><subsystem xmlns="urn:jboss:domain:ee:1.0">
<global-modules>
<module name="org.dom4j" slot="main"/>
<module name="com.sun.xml.bind" slot="main"/>
</global-modules>
</subsystem>
</pre><br />
(Global visibility is not the best solution, of course, but for this experiment I would rather modify the server configuration than add JBoss-specific manifest headers or deployment descriptors to my application WAR.)<br />
<br />
Finally, I had another ClassNotFoundException for an internal Xerces class from the JDK required by my application. (Yes, such a dependency is bad practice, but as I said above, I'm using a real-world application for these tests...)<br />
<br />
I made this class visible to my application by adding<br />
<br />
<pre class="Xml" name="code"><path name="com/sun/org/apache/xerces/internal/impl/io"/>
</pre><br />
to <code>modules/sun/jdk/main/module.xml</code> - no idea if you are supposed to do it this way, but it works for me...<br />
<br />
Now at last I was able to deploy and run my application and take some measurements.<br />
<br />
<br />
<h3>Performance measurements</h3><br />
The following table compares some performance indicators for JBoss AS 7.0.2, JBoss AS 6.0.0 and GlassFish 3.1.1. For JBoss AS 6, I did not repeat the measurements but simply copied the results of June 2011. For GlassFish, I had been working with a pre-release build at that time, so I've now re-run my tests with the official GlassFish 3.1.1 release.<br />
<br />
<table class="content"><tbody>
<tr> <th></th> <th>JBoss AS 7.0.2</th> <th>JBoss AS 6.0.0</th> <th>GlassFish 3.1.1</th> </tr>
<tr> <td>Empty server startup time</td> <td>1.9 s</td> <td>12 s</td> <td>3.2 s</td> </tr>
<tr> <td>Empty server heap memory</td> <td>10.5 MB</td> <td>100 MB</td> <td>26.5 MB</td> </tr>
<tr> <td>Empty server PermGen memory</td> <td>36.3 MB</td> <td>70 MB</td> <td>28.4 MB</td> </tr>
<tr> <td>MyApp deployment time</td> <td>5.8 s</td> <td>47 s</td> <td>13 s</td> </tr>
<tr> <td>Server + MyApp restart time</td> <td>8 s</td> <td>30 s</td> <td>14.5 s</td> </tr>
<tr> <td>Server + MyApp heap memory</td> <td>52.8 MB</td> <td>236 MB</td> <td>55.3 MB</td> </tr>
<tr> <td>Server + MyApp PermGen memory</td> <td>80.9 MB</td> <td>175 MB</td> <td>84.5 MB</td> </tr>
<tr> <td>MyApp redeployment time</td> <td>3.5 s</td> <td>30 s</td> <td>7 s</td> </tr>
</tbody></table><br />
All in all, there is an amazing improvement of performance and memory footprint in JBoss AS 7, compared to JBoss AS 6. JBoss AS 7 is now at a competitive level with Resin and Glassfish and actually outperforms Glassfish in almost all of these tests.<br />
<br />
I don't know if this indeed qualifies as <i>lightning fast</i>, but it is now safe to say that JBoss AS 6 was blatantly fat and slow, as confirmed by its own successor.<br />
<br />
<h3>Redeployment</h3><br />
I tested redeploying my application by simply touching the WAR file in the <code>deployments</code> directory and watching the memory usage via <i>jvisualvm</i>.<br />
<br />
I could see the PermGen usage grow at a constant rate, and after a couple of redeployments, there was an OutOfMemoryError, so JBoss AS 7 appears to have a new classloader leak. (The same test did pass successfully on JBoss AS 6.)<br />
<br />
<h3>Eclipse Integration</h3><br />
In contrast to the drastic improvements of the server itself, I could find no significant progress with the Eclipse integration. I installed the JBoss AS Tools from <a href="http://download.jboss.org/jbosstools/updates/development/indigo/">JBoss Tools 3.3.0.M3</a> into a fresh copy of Eclipse Indigo 3.7.1 with m2e 1.0 and m2e-wtp 0.14.0.<br />
<br />
I was able to deploy my application directly from the workspace, but editing and saving a source file did not redeploy the application. An Incremental Publish did not help either. Only a Full Publish was sufficient to redeploy the application.<br />
<br />
This is a major productivity issue for Eclipse users. Redeploy-on-save works smoothly with the built-in Tomcat integration of Eclipse WTP, so something must be broken in JBoss AS Tools.<br />
<br />
<h3>JPA Providers</h3><br />
JBoss AS 7.0.2 comes bundled with Hibernate 4.0.0.CR2. This is a bad smell - an official product release should never contain any release candidates of upstream components, especially not for components originating from the same company. <br />
<br />
The good news is that my application which was developed on Hibernate 3.6.0 works without problems on this Hibernate 4.x release candidate.<br />
<br />
But the real bad news is that JBoss AS 7 does not currently support other persistence providers like Eclipselink, OpenJPA or DataNucleus (according to the <a href="https://docs.jboss.org/author/display/AS7/JPA+Reference+Guide">JPA Reference Guide</a>). With GlassFish and Resin, you can simply drop the JARs of your preferred provider and its dependencies in a designated folder of your server installation and edit your <code>persistence.xml</code> to override the default provider of the server. <br />
<br />
JBoss AS 7 appears to require an adapter per persistence provider, which to me looks like an unfortunate and unnecessary design decision. <br />
<br />
At any rate, this lack of flexibility is a severe restriction. In most of my projects, I had to replace Hibernate by OpenJPA due to a number of bugs related to new JPA 2.0 features.<br />
<br />
<h3>Conclusion</h3><br />
Given the drastic performance improvements in JBoss AS 7, which was released only six months and a half after JBoss AS 6, I can only wonder why RedHat and the JBoss community ever spent any resources on an AS 6 release which clearly was not competitive, instead of focusing on AS 7.<br />
<br />
Anybody looking for a production-quality Java EE 6 server in the first half of 2011 was better off with GlassFish 3.1.1 or one of its pre-releases.<br />
<br />
With AS 7, JBoss is now back in the game, it is surprisingly lean and fast, and it even has the potential to take over the lead from GlassFish. <br />
<br />
But performance is not the only factor that counts. The documentation continues to be sketchy and far below the standard of JBoss AS 5.<br />
<br />
Different projects have different needs, but for me, the top-level performance of JBoss AS 7 is more than outweighed by classloader leaks, productivity issues of the Eclipse integration and lack of support for JPA providers other than Hibernate.<br />
<br />
Each of these is currently a blocker for using JBoss AS 7 in production. GlassFish 3.x has taken more than a year to reach production quality. Let's see if JBoss AS 7.x can do the same <em>lightning fast</em>.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com9tag:blogger.com,1999:blog-7836204352369514180.post-1535408859408904952011-08-29T23:41:00.000+02:002011-08-29T23:41:12.125+02:00Eclipse Maven Integration ExtensionsFor me, the most important new feature in Eclipse 3.7.0 (Indigo) is the improved Maven Integration, formerly developed by Sonatype under the name of m2eclipse, now an official Eclipse subproject under the name of m2e.<br />
<br />
m2eclipse and Eclipse sometimes used to have different opinions on what was going on in the workspace, and <em>so we had to go through series of refresh/update dependencies/update configuration/rebuild voodoo (or "m2eclipse dance" as some called it) to get projects in a good state.</em> (Quote from the m2e Wiki).<br />
<br />
m2e has a different approach. First of all, it complains when detecting a Maven plugin in one of your POMs that it cannot handle out of the box. m2e flags your POM with an error marker that will not go away until you tell m2e what do to about the unknown plugin. The easy way out is a Quick Fix to ignore the plugin, which means you'll have to run the corresponding Maven goal manually when you need it.<br />
<br />
However, when the Maven plugin in question generates source code or post-processes byte code, this is usually not sufficient - ideally, Eclipse and m2e should pick up the required build steps from your POM automatically.<br />
<br />
This issue is addressed by <b>m2e extensions</b>, which provide the missing link between Eclipse project builders and Maven plugins. An m2e extension for a given Maven plugin not only invokes the required mojos but also informs Eclipse about new source or binary folders created by the mojos, so that Eclipse and Maven can stay in sync.<br />
<br />
My projects use a number of Maven plugins that are not supported by m2e out of the box, e.g. for <b>JAXB</b> and <b>OpenJPA</b>, so I started creating some custom extensions for these plugins, based on a <a href="https://github.com/hwellmann/m2eclipse-extras/wiki">GitHub fork</a> of the official m2e extensions from Sonatype. <br />
<br />
See the<a href="https://github.com/hwellmann/m2eclipse-extras/wiki"> wiki page</a> at GitHub for more details. The GitHub project also contains an Eclipse <a href="https://github.com/hwellmann/m2eclipse-extras/raw/master/p2/">update site</a> (aka p2 repository) for installing the plugins. Time permitting, I'll try to make these extensions available via the Eclipse marketplace.<br />
<br />
For any fixes, additions or new extensions, feel free to send my pull requests.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-82566024522501370472011-06-25T19:43:00.002+02:002011-07-10T17:54:39.127+02:00Wicket and OSGiAfter playing around with the OSGi JPA and JTA components of <a href="http://aries.apache.org/">Apache Aries</a> for a while, it was only natural to try and add a web layer to my sample projects. The Aries samples all use plain old servlets and JSPs, so I wondered if <a href="http://wicket.apache.org/">Wicket</a> would work in this context.<br />
<br />
So far, I had only ever used Wicket in standard Java EE web applications, but I had noticed the Wicket JARs come with an OSGi manifest, so someone must have tried to use Wicket in OSGi before.<br />
<br />
<a name='more'></a><br />
Then I noticed the ominous<br />
<br />
<pre>DynamicImport-Package: *
</pre><br />
manifest header, which is not the best way of interacting with client code, and what's worse, Wicket does not even import its own static dependencies like org.slf4j, but relies on the catch-all dynamic import.<br />
<br />
A <a href="http://apache-wicket.1842946.n4.nabble.com/Wicket-and-OSGi-tp3617698p3617698.html">discussion</a> on the Wicket Users mailing list confirmed my suspicion that this had to be related to Wicket's page deserialization requiring to load classes from user bundles.<br />
<br />
Anyway, I had a feeling it shouldn't be too hard to make this work without dynamic imports. In addition, it would be nice to inject OSGi services into Wicket components, just like CDI or Spring beans.<br />
<br />
So I started coding, and by now, there is a first proof-of-concept sample using Wicket on top of Aries, Jetty, OpenJPA, Derby and Equinox. The <a href="http://code.google.com/p/osgi-enterprise/source/browse/#hg/aries-pde">sample code</a> is included in my <a href="http://code.google.com/p/osgi-enterprise">OSGi Enterprise</a> sandbox project at Google Code. <a href="http://code.google.com/p/osgi-enterprise/wiki/WicketAndOsgi">More details</a> can be found in the OSGi Enterprise wiki.<br />
<br />
<b>Update 10 Jul 2011:</b> After some polishing, my Wicket/OSGi glue code has made it into the <a href="http://wicketstuff.org/">Wicketstuff</a> project - see the <a href="https://github.com/wicketstuff/core/wiki/Osgi">OSGi Integration</a> wiki page for more details. This subproject targets the Wicket 1.5 release and will automatically be integrated with the next release or release candidate of Wicketstuff.<br />
<br />
Snapshot artifacts are currently available from the <a href="https://oss.sonatype.org/content/repositories/snapshots/org/wicketstuff/wicketstuff-osgi/1.5-SNAPSHOT/">Sonatype OSS repository</a>.<br />
<br />
The first shot in the <a href="http://code.google.com/p/osgi-enterprise">OSGi Enterprise</a> project works with Wicket 1.4.x. <br />
<br />
wicket-osgi from Wicketstuff cannot be used with Wicket 1.4.x.Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com0tag:blogger.com,1999:blog-7836204352369514180.post-13090818362385805452011-06-07T18:58:00.001+02:002011-06-07T19:12:10.045+02:00Java EE 6 Server Comparison: Conclusion<h3>Lessons Learned</h3><br />
<b>Portability is not just a Java EE marketing promise.</b> My application now runs on three different Java EE 6 servers, using the same WAR file, without any compile-time configuration.<br />
<br />
<b>An application is not portable until it has been ported.</b> Of course, this is true for any specification with different implementations, not just for Java EE. Each of the three servers helped me discovering incorrect API usage in my application that just happened to work on another server.<br />
<br />
<b>Certification is not reliable.</b> My application hit at least one major specification violation in each of the three Java EE 6 certified servers. Thus, the test coverage in the Java EE TCKs must be insufficient. <br />
<br />
<a name='more'></a><br />
A certification process for an open specification should be open. Implementations of the specification may be closed source, but the test suites (TCKs) should be open source, and the user community should have the chance to contribute new test cases.<br />
<br />
The next version of the Java Community Process is moving in the right direction, but if you read the proposal carefully, you will notice a lot of half-hearted may's and should's, which is not enough. TCKs shall be open, period.<br />
<br />
(Note: Most of the JCP site is currently unavailable, due to restructuring - I read JSR 348 a few days ago. Oracle, did you ever hear about high availability and Cool URLs don't change?)<br />
<br />
<h3>And the winner is...</h3><br />
Each of the three servers has its strong points and its weaknesses. <br />
<br />
Only <b>JBoss</b> has an official release that is able to run my application (with a workaround). On the other hand, its memory footprint is enormous, the deployment speed is inacceptable and the weakest point is the lack of up-to-date documentation. The Eclipse integration is severely limited in not allowing to republish applications.<br />
<br />
<b>Resin</b> has the smallest footprint by far, clearly in terms of memory, less clearly in terms of deployment speed, where Glassfish is close up and might scale better than Resin for larger applications due to Resin's code generation during deployment. Resin needs a few more releases to mature. Its Eclipse integration is too unstable for serious use.<br />
<br />
<b>Glassfish</b> is the leader in end-to-end usability. Its ease of use and its excellent documentation are invaluable for promoting the benefits of Java EE 6, keeping the barrier low for newcomers.<br />
<br />
Its speed is excellent (though outrivalled by Resin), its memory footprint needs to be improved, but is still a lot smaller compared to JBoss. Important to note (though without any impact on my experiments) is the fact that Glassfish is the only one of the three certified for the Java EE 6 Full Profile.<br />
<br />
Compared to JBoss and Resin, Glassfish has the best Eclipse integration (but the standard Eclipse WTP Tomcat integration is still better).<br />
<br />
Glassfish needs to shift the balance from new features to stability. There has been no production quality 3.x release so far. Glassfish 3.1.1 is on its way, it has a chance of becoming the first <i>really</i> stable release, and I'd rather wait for it a little longer to make sure that all major known bugs are fixed.<br />
<br />
Glassfish would benefit from quarterly maintenance releases and more transparency in community communications.<br />
<br />
All in all, if you ask me<br />
<br />
<ul><li>Which server would you choose for an application to go live next week?</li>
<li>Which server would you choose for developing a new project to go live next year?</li>
</ul>then my answer is Glassfish for both. And if I couldn't use Glassfish, I would choose JBoss for next week and Resin for next year.<br />
<br />
<h3>Executive Summary</h3><br />
<i>Glassfish is Business Class, JBoss is Baroque, Resin is Zen.</i><br />
<br />
<h4>Read the whole story</h4><br />
<ul><li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison.html">Part 1: Introduction</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-glassfish.html">Part 2: Glassfish</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-jboss.html">Part 3: JBoss</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-resin.html">Part 4: Resin</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-conclusion.html">Part 5: Conclusion</a></li>
</ul>Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com12tag:blogger.com,1999:blog-7836204352369514180.post-82634335220600307802011-06-07T18:53:00.001+02:002011-06-07T19:11:18.426+02:00Java EE 6 Server Comparison: ResinThe first time I read about Caucho Resin 4.x was last summer, when I was looking for alternative CDI implementations, i.e. other than Weld. Resin has its own CDI implementation named CanDI, and I was bold enough to give it a try, knowing that Resin 4.x was not yet Java EE 6 certified and probably not stable enough.<br />
<br />
I didn't get very far at that time, CanDI looked ok, but the JPA API was broken and <code>@Singleton @Startup</code> beans did not work, so I left it at that and made a mental note to check back after the first stable release.<br />
<br />
<a name='more'></a><br />
Now that Resin 4.0.17 passed the Java EE 6 Web Profile certification in May 2011, it's a good time to give it another try. <br />
<br />
Considering that Caucho focuses on the Web Profile and has no intention to support the Full Profile, you'd expect Resin to be more lightweight than Glassfish or JBoss. In fact, Resin is amazingly small and easy to use, the perfect example to destroy common belief that Java Enterprise servers are heavyweight and slow.<br />
<br />
The Resin download package has 23 MB (compared to 44 MB for Glassfish Web Profile, 78 MB for Glassfish Full Profile, and 173 MB for JBoss).<br />
<br />
Resin has a very small number of third party dependencies. The largest part of Resin is a single <code>resin.jar</code> of less than 11 MB, the rest is Eclipselink (JPA), Mojarra (JSF), Java Mail and a couple of Java EE API JARs. <br />
<br />
This fact is worth mentioning, not just as an achievement of the Resin development team, but also as a benefit for the application developer: The risk of a version conflict for a library used both by the application and the server is almost zero, given that Resin has little or no external dependencies.<br />
<br />
<h3>Preparing the server</h3><br />
To configure my data source, I added the MySQL JDBC driver to Resin's lib directory and then added the following section to <code>conf/resin.xml</code>:<br />
<br />
<pre class="Xml" name="code"><database>
<jndi-name>jdbc/tcm</jndi-name>
<driver type="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
<url>jdbc:mysql://localhost/myapp</url>
<user>myuser</user>
<password>****</password>
</driver>
<prepared-statement-cache-size>8</prepared-statement-cache-size>
<max-connections>20</max-connections>
<max-idle-time>30s</max-idle-time>
</database>
</pre><br />
Then I started the server from the command line:<br />
<br />
<pre>bin/resin.sh console
</pre><br />
and copied my WAR to the <code>webapps</code> directory for deployment.<br />
<br />
<h3>Troubleshooting</h3><br />
Resin's approach to proxy creation for EJBs and CDI beans is Java code generation and compilation at deployment time. In the current release 4.0.18, the EJB code generator is broken for some use cases with generic methods.<br />
<br />
After I <a href="http://forum.caucho.com/showthread.php?t=27905">posted my problem</a> in the Resin forum, the development team advised me to use the current snapshot which solved the problem at least partially, and for the remaining cases, I temporarily removed some generic parameters in a few source files of my application.<br />
<br />
For the rest of my experiments, I used the pre-4.0.19 snaphot version labelled resin-4.0.s110531.<br />
<br />
Besides the generic methods arguments, the code generator complained about a checked exception in a <span style="font-family: "Courier New",Courier,monospace;">@PostConstruct</span> method, but it was right in doing so: the <span style="font-family: "Courier New",Courier,monospace;">PostConstruct</span> Javadoc clearly states that methods with this annotation must not throw checked exceptions, so I wrapped my checked exception in an unchecked exception, and the problem was gone. (Glassfish and JBoss did not complain about the checked exception.)<br />
<br />
The only remaining problem was a version conflict for the SLF4J API. Resin includes <code>slf4j-1.6.1.jar</code> in <code>webapp-jars</code> whereas my application requires 1.5.11. I deleted the 1.6.1 version from <code>webapp-jars</code> and added the Hibernate, Javassist and JAXB JARs I had needed to exclude from my WAR for JBoss.<br />
<br />
Other problems like EL in JSPs not working turned out to be a side effect of a broken Eclipse plugin version.<br />
<br />
<h3>Eclipse Integration</h3><br />
In fact, the Eclipse plugin was my biggest source of <a href="http://forum.caucho.com/showthread.php?t=27915">troubles</a> with Resin. The current release 4.0.16 from <a href="http://caucho.com/eclipse/">Caucho's Update Site</a> did not work at all in the default (i.e. WAR) deployment mode. After enabling directory-based deployment in the Server Runtime dialog, the plugin would deploy my application, but its update behaviour was a complete mystery to me. Sometimes it seemed to deploy out-dated versions of classes, including some classes I had already deleted.<br />
<br />
The WAR deployment has been fixed in the current 4.0.19 snapshot version of the Eclipse plugin which can be installed from the <a href="http://caucho.com/eclipse-snapshot">Snapshot Update Site</a>.<br />
<br />
After deleting the 4.0.16 version and installing the 4.0.19 snapshot, the Eclipse plugin finally started to work more or less reliably in the default mode. The directory mode continues to be broken, causing all sorts of mysterious side effects.<br />
<br />
With the default mode, there are still a number of issues:<br />
<br />
<ul><li>Editing a source file of the top-level module redeploys the application as expected, editing a source of a dependent module does not. </li>
<li>Redeploying the application causes the EJB Proxies and JSPs to be regenerated and recompiled. For some reason, this process is much slower when running under the Eclipse plugin, compared to (re)deploying an application from the command line. Increasing MaxPermSize in the server launcher did not help.</li>
<li>After two or three redeployments from Eclipse, Resin dies with a PermGen size OutOfMemoryError.</li>
</ul>From the command line, I was able to redeploy my application a couple of times without any apparent memory leaks.<br />
<br />
<h3>Performance Measurements</h3><br />
<ul><li>Empty server startup time: 3.3 s</li>
<li>Empty server memory usage: 22 MB heap, 27 MB PermGen</li>
<li> MyApp deployment time: 8 s</li>
<li>Server + MyApp restart time: 9 s</li>
<li>Server + MyApp memory usage: 44 MB heap, 58 MB PermGen</li>
<li>MyApp redeployment time: 8 s</li>
<li>Server + MyApp startup time from Eclipse: 30 s</li>
<li>Server + MyApp memory usage from Eclipse: 245 MB heap, 124 MB PermGen</li>
<li>MyApp redeployment on Eclipse save: 25 s, heap reduced to 85 MB</li>
</ul><br />
It is strange that Resin works rather smoothly from the commandline and has no memory issues at all, while slowing down on code generation, using excessive amounts of memory and throwing PermGen exceptions in combination with the Eclipse plugin.<br />
<br />
<h3>Summary</h3><br />
Resin is easy to use and incredibly lightweight. The documentation is rather terse and not always up-to-date, but all in all usable. The Resin Forum was extremely helpful, my questions were answered quickly and some of the bugs I found during this investigation have already been fixed by the Caucho team in the meantime.<br />
<br />
It would be foolish to recommend any server for production use before having worked with it in a real project for at least a couple of months, but it is safe to say that Resin looks extremely promising and is fun to work with.<br />
<br />
The sore point at the moment is the Eclipse integration, which is currently not stable enough for day-to-day development, so this is a real blocker, unless you are happy using command line tools, some other IDE, or maybe some other server for development and Resin for testing and production only.<br />
<br />
Resin 4.0.x releases have been published once a month since February 2010, and if the team can keep up this pulse rate both for the server and the Eclipse plugin, I'm quite confident that Resin will be a first class Java EE 6 Web Profile platform within a few months.<br />
<br />
<h4>Read the whole story</h4><br />
<ul><li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison.html">Part 1: Introduction</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-glassfish.html">Part 2: Glassfish</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-jboss.html">Part 3: JBoss</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-resin.html">Part 4: Resin</a></li>
<li><a href="http://hwellmann.blogspot.com/2011/06/java-ee-6-server-comparison-conclusion.html">Part 5: Conclusion</a></li>
</ul>Harald Wellmannhttp://www.blogger.com/profile/08039976160321882828noreply@blogger.com3