Build eclipse applications with maven 3
The tool chain for building eclipse based applications with maven becomes better and better.
Read here.
I know 2 projects using maven to build eclipse plugins:
Which project are there else?
The tool chain for building eclipse based applications with maven becomes better and better.
Read here.
I know 2 projects using maven to build eclipse plugins:
Which project are there else?
If you want disable the Backspace key in your JSF Richfaces application put this in your view:
<rich:hotKey key="backspace" handler="return false;" disableInInput="true"/>
This will register a jQuery Hotkey handler for the document. The handler is not reqistered for input elements because in input fields you need the backspace
. Tested for FF3 and IE6.
Then I found out that the following snippet doesn’t work:
<rich:hotKey key="backspace"
disableInInput="true"
handler="alert('Backspace is disabled'); return false;" />
The Browser open the alert box and go to the previous page (in background?!). But there is a fix for that:
<rich:hotKey key="backspace"
disableInInput="true"
handler="alert('Backspace is disabled'); event.stopPropagation(); event.preventDefault(); return false;" />
The event variable is available in the handler function (see org.richfaces.renderkit.html.HotKeyRenderer method doEncodeEnd).
I’m using java rebel for web development with maven.
Sometimes I would run jetty with jrebel sometimes without.
For that I’m using two simple bash functions:
# ~/.bashrc
#
# Maven options
#
export INTERNAL_MAVEN_OPTS="-Xmx512m -XX:PermSize=128m -XX:MaxPermSize=128m"
#
# Java Rebel
#
export JAVA_REBEL="-Drebel.spring_plugin=true -Drebel.log=false -noverify -javaagent:D:\tools\javarebel\jrebel.jar -Drebel.packages=de.ahoehma"
function jrebel_on() {
export MAVEN_OPTS="$INTERNAL_MAVEN_OPTS $JAVA_REBEL"
}
function jrebel_off() {
export MAVEN_OPTS="$INTERNAL_MAVEN_OPTS"
}
Now its very simple to enable
$ jrebel_on
or disable jrebel
$ jrebel_off
There is a interesting project at sourceforge called qcMylyn. The projects aims to provide a Mylyn connector for Quality Center. Support Eclipse 3.4.2, 3.5, Mylyn 3.0.5+.
I tried the released version 0.2.4 but it didn’t work because at work we are using an older version of QualityCenter (9.1). But this was no big problem I have the sourcecode (OS rocks) and I’m a programmer
I found out that a other project called QcTools4J contains the java code for manipulation a QC system. They using a com4j bridge to bind QC’s otaclient.dll.
If you have trouble with a older/newer version of QC you have to update the qctools4j.
You find a short tutorial how to update qctools4j here. (read this first) … then you will come to the point where you want create a new otaclient.jar from you local otaclient.dll. Here is my simple solution for that.
I create my own otaclient maven project with the following pom:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>otaclient</groupId>
<artifactId>otaclient</artifactId>
<version>9.1.0.4372</version>
<dependencies>
<dependency>
<groupId>org.jvnet.com4j</groupId>
<artifactId>com4j</artifactId>
<version>20080107</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.com4j</groupId>
<artifactId>maven-com4j-plugin</artifactId>
<executions>
<execution>
<id>gen-java-bridge</id>
<goals>
<goal>gen</goal>
</goals>
<configuration>
<file>src/qc/OTAClient.dll</file>
<package>com.mercury.qualitycenter.otaclient</package>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
I using the maven-com4j-plugin to generate the java layer for otaclient.
All you have to do is to extract your “qc client package” (could be download from every qc server page) into src/qc and start mvn clean package.
Then target will contain a otaclient-9.1.0.4372.jar. Copy this jar into qctools4j/lib/com.mercury.qualitycenter.otaclient-9.2.jar and rebuild qctools4j. That’s all

Then copy the qctools4j.jar into org.tszadel.qctools and rebuild the whole eclipse feature.

Try it
Yesterday I had to customize the Richfaces tree component, because my client wants a special layout. My solution is a little bit strange. I share it here for someone which is in the same situation
Here is the story …
Per default the rich:tree looks like a standard tree browser (i.e. explorer, eclipse, whatever):

But I want this look:

You see that the expand/collapse icon (
) is on the same level with the node-icon (
). That’s very hard to fix this with CSS (it’s possible but i prefer my strange solution
). The Richfaces documentation describes which parts of a tree could be customize.

We have:
I decide to move the expand/collapse icon from the handle-td to the icon-td and “simulate” the user-click with Javascript:

<rich:tree id="tree"
binding="#{treeBean.tree}"
var="item"
switchType="ajax"
ajaxSubmitSelection="true"
toggleOnClick="false"
showConnectingLines="false"
disableKeyboardNavigation="true">
<f:facet name="iconCollapsed">
<!-- no image for collapsed -->
<rich:spacer width="0" height="0" style="border: none;"/>
</f:facet>
<f:facet name="iconExpanded">
<!-- no image for expanded -->
<rich:spacer width="0" height="0" style="border: none;"/>
</f:facet>
<f:facet name="icon">
<!-- use normal node icon to toggle expand/collapse -->
<h:panelGroup>
<h:graphicImage value="#{item.isLeaf ? '/images/leaf.gif' : '/images/collapsed.gif'}"
onclick="myToggleTreeNode(this);"
rendered="#{!treeBean.isExpanded}"/>
<h:graphicImage value="#{item.isLeaf ? '/images/leaf.gif' : '/images/expanded.gif'}"
onclick="myToggleTreeNode(this);"
rendered="#{treeBean.isExpanded}"/>
</h:panelGroup>
</f:facet>
<f:facet name="iconLeaf">
<h:graphicImage value="/images/leaf.gif"/>
</f:facet>
<rich:recursiveTreeNodesAdaptor roots="#{treeBean.roots}" var="item" nodes="#{item.children}">
<rich:treeNode>
<h:outputText value="#{item.name}"/>
</rich:treeNode>
</rich:recursiveTreeNodesAdaptor>
</rich:tree>
function myToggleTreeNode(element) {
var elem = jQuery(element);
// img -> span -> td
var parent = elem.parent().parent();
var elementId = parent.attr("id");
// i.e. j_id31:tree:j__id39:18::j_id40:icon -> the td arround the icon-image
var index = elementId.lastIndexOf(":icon");
var treeNodeId = elementId.substring(0, index);
// i.e. j_id31:tree:j__id39:18::j_id40:handle -> the td arround the original expand/collapse-image
var handleId = treeNodeId+':handle';
// pure jQuery not working here
var expandElement = jQuery($(handleId));
expandElement.trigger("click");
}
.rich-tree-node-handleicon {
display: none;
}
Today I found a nice example for a “checked null pointer exception” in Ed burns blog.
@Override
public void encodeAll(FacesContext context) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String viewName, libraryName, resourceName;
try {
viewName = this.getAttributes().get("viewName").toString();
libraryName = this.getAttributes().get("libraryName").toString();
resourceName = this.getAttributes().get("resourceName").toString();
} catch (NullPointerException e) {
throw new FacesException("Must supply viewName, libraryName and resourceName attributes");
}
...
}
I have always tried to avoid NPE’s with code like this:
if (foobar == null) {
throw new IllegalArgumentException("foobar must not be null").
}
But from now I will try to use the “checked” version of a npe check above more often.
Read more about checked / unchecked exceptions here:
Ed Burns beschreibt in seinem Blog wie man in JSF 2 selbst eine ViewExpiredException’s behandeln kann.
Momentan (JSF < 2) kann die Standard-Fehlerbehandlung natürlich auch angepasst werden, z.B. durch Festlegung einer bestimmten Location pro Exception-Typ:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
...
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/pages/error/sessionexpired.xhtml</location>
</error-page>
...
In der von Ed vorgestellten Lösung wird ein eigener ViewExpiredExceptionHandler registriert, welcher den ursprünglichen Handler kapselt. In der dort überschriebenen void handle() wir eine ViewExpiredException mit einem Redirect (via Navigation-Handler) auf eine Fehlerseite beantwortet. In der Fehlerseite können Variable, die im Handler gesetzt wurden, für eine sinnvolle Fehlerbeschreibung verwendet werden.
Beim Einsatz von Richfaces kann man diese Art von Fehler auch auf der Clientseite behandeln, beschrieben wird dies im Detail hier. Das Ganze ist mit zwei Erweiterungen machbar:
1. die Funktion für den Client aktivieren
<context-param> <param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name> <param-value>true</param-value> </context-param>
2. den Javascript-Code für die Behandlung zur Verfügung stellen:
if (typeof(A4J) !== 'undefined' && typeof(A4J.AJAX) !== 'undefined'){
// richfaces is available
A4J.AJAX.onExpired = function(loc,expiredMsg) {
var confirmMsg = 'Session expired.\n\nReload?';
if (confirm(confirmMsg)) {
window.location.reload();
}
// return false to inform "link-commands", that the user doesn't want to reload the page
return false;
};
};
In my actual project i have to work in the employers office behind a firewall/proxy. The proxy requires a authentication so i have the following proxy-settings:

Since our development-team switch to eclipse 3.5. these settings don’t work anymore. We found out that the default http-client in eclipse 3.5. doesn’t support our proxy autentication. The solution was to exclude the “new” eclipse efc http-client via eclipse.ini:
-Dorg.eclipse.ecf.provider.filetransfer.excludeContributors=org.eclipse.ecf.provider.filetransfer.httpclient -Dhttp.proxyPort=8080 -Dhttp.proxyHost=proxyf.... -Dhttp.nonProxyHosts=localhost|127.0.0.1
I need (two) different maven versions in my development system, a actual maven (2.2.1) for the “normal” work and a tycho-maven for eclipse-osgi projects (i.e. m2eclipse).
The result should look like this:


The tycho maven in D:\maven-distro\maven-tycho\conf contains a settings-tycho.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>D:\maven-repos\maven-tycho</localRepository>
</settings>
and a settings.xml (this is the changed “standard” maven configuration):
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/settings/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
<profiles>
<profile>
<id>tycho-default</id>
<repositories>
<repository>
<id>forge</id>
<url> http://repository.sonatype.org/content/groups/public</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>forge</id>
<url> http://repository.sonatype.org/content/groups/public</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>true</enabled>
</releases>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
<activeProfiles>
<activeProfile>tycho-default</activeProfile>
</activeProfiles>
</settings>
The standard maven in D:\maven-distro\maven-2.2.1\conf must not be changed. So this maven will use the default settings.xml and a user-settings from $HOME/.m2/settings.xml:
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/settings-1.0.0.xsd">
<localRepository>D:\maven-repos\maven</localRepository>
</settings>
I use cygwin under windows, so i can put the maven-tycho-alias into my ~/.bashrc:
# Add maven-tycho to path alias mvnTycho="tycho -s \"d:/maven-distro/maven-tycho/conf/settings-tycho.xml\"" export PATH="/cygdrive/d/maven-distro/maven-tycho/bin":$PATH
hoehmann@foobar /bin $ mvnTycho --version Apache Maven 3.0-TYCHO-797695 (r797704; 2009-07-25 04:43:26+0200) Java version: 1.5.0_12 Java home: d:\java\jdk1.5.0_12\jre Default locale: de_DE, platform encoding: Cp1252 OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows" hoehmann@foobar /bin $ mvn --version Apache Maven 2.2.0 (r788681; 2009-06-26 15:04:01+0200) Java version: 1.5.0_12 Java home: d:\java\jdk1.5.0_12\jre Default locale: de_DE, platform encoding: Cp1252 OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"
With this i can run mvn for “normal” maven projects, this will start maven 2.2.1 from maven-distro/maven/ and the repo will be at maven-repo/maven/.
Or i can run mvnTycho for “osgi” maven projects, this will start tycho from maven-distro/maven-tycho/ and the repo will be at maven-repo/maven-tycho/.
You can do this with much more versions (2.0.1, 2.1.0, 2.2.0) and each maven will have a own repository.
Try it