Scaled Linked Image in Vaadin

In vaadin you can easily embed images either via:

Embedded logoEmbed = new Embedded("yourText",new ThemeResource("../yourtheme/img/logo.png"));
logoEmbed.setType(Embedded.TYPE_IMAGE);

or if you need a linked image do the following:

Link iconLink = new Link();
iconLink.setIcon(new ExternalResource(urlAsString));
iconLink.setResource(new ThemeResource("../yourtheme/img/logo.png"));

But how can you scale that external image? This is simple if you let the browser do it for you. In Java do:

iconLink.setStyleName("mylogo");

and then you will need to change the following style in your custom style.css to your needs:

.mylogo a img { width: 67px; }

Db4o via Maven

I couldn’t find the correct maven deps for db4o if you use transparent activation … so here you are:

<dependencies>
 <dependency>
    <groupId>com.db4o</groupId>
    <artifactId>db4o-full-java5</artifactId>
    <version>${db4o.version}</version>
 </dependency>

 <dependency>
    <groupId>com.db4o</groupId>
    <artifactId>db4o-tools-java5</artifactId>
    <version>${db4o.version}</version>
    <scope>compile</scope>
 </dependency>

 <dependency>
    <groupId>com.db4o</groupId>
    <artifactId>db4o-taj-java5</artifactId>
    <version>${db4o.version}</version>
    <scope>compile</scope>
 </dependency>

 <dependency>
    <groupId>com.db4o</groupId>
    <artifactId>db4o-instrumentation-java5</artifactId>
    <version>${db4o.version}</version>
    <scope>compile</scope>
 </dependency>

 </dependencies>

 <repositories>
    <repository>
      <id>db4o</id>
      <name>Db4o</name>
      <url>https://source.db4o.com/maven/</url>
    </repository>
 </repositories>

To use TA while build time you need the following snippet in your pom.xml:

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.3</version>
    <dependencies>
        <!-- for the regexp -->
        <dependency>
            <groupId>org.apache.ant</groupId>
            <artifactId>ant-nodeps</artifactId>
            <version>1.7.1</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
    </dependencies>
    <executions>
        <execution>
            <phase>compile</phase>
            <configuration>
                <tasks>
                    <!-- Setup the path -->
                    <!-- use maven.compile.classpath instead db4o.enhance.path -->

                    <!-- Define enhancement tasks -->
                    <typedef resource="instrumentation-def.properties"
                             classpathref="maven.compile.classpath"
                             loaderref="db4o.enhance.loader" />

                    <!-- Enhance classes which include the @Db4oPersistent annotation -->
                    <!--
                    <typedef name="annotation-filter"
                             classname="tacustom.AnnotationClassFilter"
                             classpathref="maven.compile.classpath"
                             loaderref="db4o.enhance.loader" /> -->

                    <typedef name="native-query"
                             classname="com.db4o.nativequery.main.NQAntClassEditFactory"
                             classpathref="maven.compile.classpath"
                             loaderref="db4o.enhance.loader" />

                    <!-- Instrumentation -->
                    <db4o-instrument classTargetDir="target/classes">
                        <classpath refid="maven.compile.classpath" />
                        <sources dir="target/classes">
                            <include name="**/*.class" />
                        </sources>

                        <!-- <jars refid="runtime.fileset"/> -->

                        <!-- Optimise Native Queries -->
                        <native-query-step />

                        <transparent-activation-step>
                            <!-- <annotation-filter /> -->
                            <regexp pattern="^de\.timefinder\.data" />
                            <!-- <regexp pattern="^enhancement\.model\." /> -->
                        </transparent-activation-step>
                    </db4o-instrument>
                </tasks>
            </configuration>
            <goals>
                <goal>run</goal>
            </goals>
        </execution>
    </executions>
</plugin>

And you will need to configure db4o ala

config.add(new TransparentActivationSupport());

// configure db4o to use instrumenting classloader
config.reflectWith(new JdkReflector(Db4oHelper.class.getClassLoader()));
config.diagnostic().addListener(new DiagnosticListener() {

   @Override
   public void onDiagnostic(Diagnostic dgnstc) {
      System.out.println(dgnstc.toString());
   }
});

Thanks to ptrthomas! … without his nice explanation I woudn’t got it working.

<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<dependencies>
<!– for the regexp –>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<tasks>
<!– http://ptrthomas.wordpress.com/2009/03/08/why-you-should-use-the-maven-ant-tasks-instead-of-maven-or-ivy/ –>
<!–<echo>NOW</echo>–>

<!– TODO get jar –>
<!–
<typedef resource=”org/apache/maven/artifact/ant/antlib.xml” uri=”urn:maven-artifact-ant”
classpath=”lib/maven-ant-tasks.jar”/>

<condition property=”maven.repo.local” value=”${maven.repo.local}” else=”${user.home}/.m2/repository”>
<isset property=”maven.repo.local”/>
</condition>

<artifact:localRepository id=”local.repository” path=”${maven.repo.local}”/>

<artifact:pom file=”pom.xml” id=”maven.project”/>

<artifact:dependencies pathId=”compile.classpath” filesetId=”compile.fileset” useScope=”compile”>
<pom refid=”maven.project”/>
<localRepository refid=”local.repository”/>
</artifact:dependencies>

<artifact:dependencies pathId=”runtime.classpath” filesetId=”runtime.fileset” useScope=”runtime”>
<pom refid=”maven.project”/>
<localRepository refid=”local.repository”/>
</artifact:dependencies>
–>
<!– Setup the path –>
<!– use maven.compile.classpath instead db4o.enhance.path –>

<!– Define enhancement tasks –>
<typedef resource=”instrumentation-def.properties”
classpathref=”maven.compile.classpath”
loaderref=”db4o.enhance.loader” />

<!– Enhance classes which include the @Db4oPersistent annotation –>
<!–
<typedef name=”annotation-filter”
classname=”tacustom.AnnotationClassFilter”
classpathref=”maven.compile.classpath”
loaderref=”db4o.enhance.loader” /> –>

<typedef name=”native-query”
classname=”com.db4o.nativequery.main.NQAntClassEditFactory”
classpathref=”maven.compile.classpath”
loaderref=”db4o.enhance.loader” />

<!– Instrumentation –>
<db4o-instrument classTargetDir=”target/classes” jarTargetDir=”target/”>
<classpath refid=”maven.compile.classpath” />
<sources dir=”src/main/java”>
<include name=”**/*.class” />
</sources>

<!–
TODO runtime.fileset
–>

<!– <jars refid=”runtime.fileset”/> –>

<!– Optimise Native Queries –>
<native-query-step />

<transparent-activation-step>
<!– <annotation-filter /> –>
<regexp pattern=”^de\.timefinder\.jetwick\.data” />
<!– <regexp pattern=”^enhancement\.model\.” /> –>
</transparent-activation-step>
</db4o-instrument>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<dependencies>
<!– for the regexp –>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant-nodeps</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<tasks>
<!– http://ptrthomas.wordpress.com/2009/03/08/why-you-should-use-the-maven-ant-tasks-instead-of-maven-or-ivy/ –>
<!–<echo>NOW</echo>–>

<!– TODO get jar –>
<!–
<typedef resource=”org/apache/maven/artifact/ant/antlib.xml” uri=”urn:maven-artifact-ant”
classpath=”lib/maven-ant-tasks.jar”/>

<condition property=”maven.repo.local” value=”${maven.repo.local}” else=”${user.home}/.m2/repository”>
<isset property=”maven.repo.local”/>
</condition>

<artifact:localRepository id=”local.repository” path=”${maven.repo.local}”/>

<artifact:pom file=”pom.xml” id=”maven.project”/>

<artifact:dependencies pathId=”compile.classpath” filesetId=”compile.fileset” useScope=”compile”>
<pom refid=”maven.project”/>
<localRepository refid=”local.repository”/>
</artifact:dependencies>

<artifact:dependencies pathId=”runtime.classpath” filesetId=”runtime.fileset” useScope=”runtime”>
<pom refid=”maven.project”/>
<localRepository refid=”local.repository”/>
</artifact:dependencies>
–>
<!– Setup the path –>
<!– use maven.compile.classpath instead db4o.enhance.path –>

<!– Define enhancement tasks –>
<typedef resource=”instrumentation-def.properties”
classpathref=”maven.compile.classpath”
loaderref=”db4o.enhance.loader” />

<!– Enhance classes which include the @Db4oPersistent annotation –>
<!–
<typedef name=”annotation-filter”
classname=”tacustom.AnnotationClassFilter”
classpathref=”maven.compile.classpath”
loaderref=”db4o.enhance.loader” /> –>

<typedef name=”native-query”
classname=”com.db4o.nativequery.main.NQAntClassEditFactory”
classpathref=”maven.compile.classpath”
loaderref=”db4o.enhance.loader” />

<!– Instrumentation –>
<db4o-instrument classTargetDir=”target/classes” jarTargetDir=”target/”>
<classpath refid=”maven.compile.classpath” />
<sources dir=”src/main/java”>
<include name=”**/*.class” />
</sources>

<!–
TODO runtime.fileset
–>

<!– <jars refid=”runtime.fileset”/> –>

<!– Optimise Native Queries –>
<native-query-step />

<transparent-activation-step>
<!– <annotation-filter /> –>
<regexp pattern=”^de\.timefinder\.jetwick\.data” />
<!– <regexp pattern=”^enhancement\.model\.” /> –>
</transparent-activation-step>
</db4o-instrument>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>   </plugin>

Memory Efficient XML Processing not only with DOM

How can I efficiently parse large xml files which can be several GB large? With SAX? Hmmh, well, yes: you can! But this is somewhat ugly. If you prefer a better maintable approach you should definitely try joost which does not load the entire xml file into memory but is quite similar to xslt.

But how can I do this with DOM or even better dom4j, if you only have 50 MB or even less RAM? Well, this is not always possible, but under some circumstances you can do this with a small helper class. Read on!

E.g.you have the xml file

<products>
  <product id="1"> CONTENT1 .. </product>
  <product id="2"> CONTENT2 .. </product>
  <product id="3"> CONTENT3 .. </product>
  ...
</products>

Then you can parse it product by product via:

List<String> idList = new ArrayList<String>();
ContentHandler productHandler =
         new GenericXDOMHandler("/products/product") {
  public void writeDocument(String localName, Element element)
        throws Exception {
    // use DOM here
    String id = element.getAttribute("id");
    idList.add(id)
  }
}
GenericXDOMHandler.execute(new File(inputFile), productHandler);

How does this work? Every time the SAX handler detects the <product> element it will read the product tree (which is quite small) into RAM and call the writeDocument function. Technically we have added a listener to all the product elements with that and are waiting for ‘events’ from our GenericXDOMHandler. The code was developed for my xvantage project but is also used in production code on big files:


import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

/**
 * License: http://en.wikipedia.org/wiki/Public_domain
 * This software comes without WARRANTY about anything! Use it at your own risk!
 *
 * Reads an xml via sax and creates an Element object per document.
 *
 * @author Peter Karich, peathal 'at' yahoo 'dot' de
 */
public abstract class GenericXDOMHandler extends DefaultHandler {

 private Document factory;
 private Element current;
 private List<String> rootPath;
 private int depth = 0;

 public GenericXDOMHandler(String forEachDocument) {
  rootPath = new ArrayList<String>();
  for (String str : forEachDocument.split("/")) {
    str = str.trim();
    if (str.length() > 0)
    rootPath.add(str);
  }

  if (rootPath.size() < 2)
    throw new UnsupportedOperationException("forEachDocument"+
       +" must have at least one sub element in it."
       + "E.g. /root/subPath but it was:" + rootPath);
 }

 @Override
 public void startDocument() throws SAXException {
  try {
    factory = DocumentBuilderFactory.newInstance().
         newDocumentBuilder().newDocument();
  } catch (Exception e) {
    throw new RuntimeException("can't get DOM factory", e);
  }
 }

 @Override
 public void startElement(String uri, String local,
      String qName, Attributes attrs) throws SAXException {

  // go further only if we add something to our sub tree (defined by rootPath)
  if (depth + 1 < rootPath.size()) {
    current = null;
    if (rootPath.get(depth).equals(local))
      depth++;

    return;
  } else if (depth + 1 == rootPath.size()) {
    if (!rootPath.get(depth).equals(local))
      return;
  }

  if (current == null) {
    // start a new subtree
    current = factory.createElement(local);
  } else {
    Element childElement = factory.createElement(local);
    current.appendChild(childElement);
    current = childElement;
  }

  depth++;

  // Add every attribute.
  for (int i = 0; i < attrs.getLength(); ++i) {
    String nsUri = attrs.getURI(i);
    String qname = attrs.getQName(i);
    String value = attrs.getValue(i);
    Attr attr = factory.createAttributeNS(nsUri, qname);
    attr.setValue(value);
    current.setAttributeNodeNS(attr);
  }
 }

 @Override
 public void endElement(String uri, String localName,
     String qName) throws SAXException {

  if (current == null)
    return;

  Node parent = current.getParentNode();

  // leaf of subtree
  if (parent == null)
    current.normalize();

  if (depth == rootPath.size()) {
    try {
      writeDocument(localName, current);
    } catch (Exception ex) {
      throw new RuntimeException("Exception"+
        +" while writing one element of path:" + rootPath, ex);
    }
  }

  // climb up one level
  current = (Element) parent;
  depth--;
 }

 @Override
 public void characters(char buf[], int offset, int length)
       throws SAXException {
  if (current != null)
    current.appendChild(factory.createTextNode(
       new String(buf, offset, length)));
 }

 public abstract void writeDocument(String localName, Element element)
 throws Exception {
 }

 public static void execute(File inputFile,
     ContentHandler handler)
     throws SAXException, FileNotFoundException, IOException {

   execute(new FileInputStream(inputFile), handler);
 }

 public static void execute(InputStream input,
     ContentHandler handler)
     throws SAXException, FileNotFoundException, IOException {

   XMLReader xr = XMLReaderFactory.createXMLReader();
   xr.setContentHandler(handler);
   InputSource iSource = new InputSource(new InputStreamReader(input, "UTF-8"));
   xr.parse(iSource);
 }
}

PS: It should be simple to adapt this class to your needs; e.g. using dom4j instead of DOM. You could even register several paths and not only one rootPath via a BindingTree. For an implementation of this look at my xvantage project .

PPS: If you want to process xpath expressions in the writeDocument method be sure that this is not a performance bottleneck with the ordinary xpath engine! Because the method could be called several times. In my case I had several thousand documents, but jaxen solved this problem!

PPPS: If you want to handle xml writing and reading (‘xml serialization’) from Java classes check this list out!

Constant Complexity For Reversing of a List

I am reading this question on stack overflow and it was irritating for me that the most people say: reversing a linked list is possible only in O(n). Okay, this is true for a single linked lists, but not for double linked lists like I will show you with my quick and dirty CarouselList:

The key point is the incrementer/decrementer:

static class Incrementer<T> {

 Node<T> getNext(Node<T> node) {
   return node.next;
 }

 Node<T> getStart(Node<T> head) {
   return head;
 }
}

static class Decrementer<T> extends Incrementer<T> {

 @Override
 Node<T> getNext(Node<T> node) {
   return node.previous;
 }

 @Override
 Node<T> getStart(Node<T> head) {
   return head.next;
 }
}

This way the ‘iteration order’ can be easily switched in O(1). Of course this comes to the cost of a bit more expensive iteration but this is another issue …

If the implementation could use an ArrayList (not a linked list) it would be more simple: return different iterators based on a ‘reverse’ attribute. Then either return an iterator with counter++ or return one with counter– if reverse == true

Fast O(n) Integer Sorting Algorithm!

Update: This post was reposted @ dzone with lots of upvotes – Thanks!

Yesterday I learned that there is an O(n) integer sort algorithm (I should have read this before in a basic algorithm book :-/).

Now I wondered: is this necessary in real applications? E.g. somewhere in Java? Today I have taken the counting sort and I can argue: yes, you should use integer sort especially for large arrays!

And when in detail should you apply the fast integer sort? Apply it if

  • you have positive integer values to sort. The requirement ‘positive’ and ‘integer’ is necessary for the listed O(n) algorithm, but not if you implement your own possible better solution.
  • you have a limited interval for the integer values (preferable min and max=M should be known before you sort)
    E.g. if you know the maximum integer number in your array will be M=10^7 then you should use the integer sort if the array length n is roughly greater than M/2500 = 40000. This linear equation should hold true (for some values ;-)), because quick sort is nearly independent of M and the time-offset for integer sort increases nearly linear with M as you can see in the graph

Now take a look at the graph where y=time in seconds for 10 runs and x=array length:

Conclusion

I would apply this sorting algorithm only for n>10^7 where the difference between quicksort and integer sort could lay in the range of seconds. The memory consumption was not measured but should be ~twice times higher for the fast integer sort.

Java Sourcecode

//class LinearSort
public static void main(String[] args) {

 // init jvm
 new LinearSort().start(1000, 10000, 10000);
 new LinearSort().start(1000, 10000, 10000);

 // run performance comparison
 for (int maxInteger = 1000; maxInteger < 100000000; maxInteger *= 3) {
  for (int arrLength = 1000; arrLength < 100000000; arrLength *= 3) {
   System.gc();
   new LinearSort().start(arrLength, maxInteger, 10);
  }
 }
}

 private Random rand = new Random();

 // stop watch for integer sort with *unknown* range. marked as Lin in the plot
 private SimpleTimer linearStopWatch = new SimpleTimer();</pre>

 // stop watch for integer sort with known range. marked as Lin' in the plot
 private SimpleTimer linearKnownStopWatch = new SimpleTimer();

 private SimpleTimer qSortStopWatch = new SimpleTimer();

 private void start(int arrLength, int maxInteger, int times) {
 for (int count = 0; count < times; count++) {
   int[] list1 = new int[arrLength];
   for (int i = 0; i < arrLength; i++) {
     // do only allow positive integers until the specified 'max'-value
     list1[i] = Math.abs(rand.nextInt(maxInteger));
   }
   linearStopWatch.start();
   LinearSort.sort(list1);
   linearStopWatch.pause();

   int[] list2 = Arrays.copyOf(list1, arrLength);
   qSortStopWatch.start();
   Arrays.sort(list2);
   qSortStopWatch.pause();

   list2 = Arrays.copyOf(list1, arrLength);
   linearKnownStopWatch.start();
   LinearSort.sort(list2, 0, maxInteger);
   linearKnownStopWatch.pause();
 }

 System.out.println(maxInteger + ";" + arrLength + ";" + linearStopWatch
 + ";" + linearKnownStopWatch
 + ";" + qSortStopWatch); // + ";" + qSortListStopWatch);
}

 static int[] sort(int[] array, int min, int max) {
   //the range is useful to minmize the memory usage
   //countIntegers holds the number of each integer
   int[] countIntegers = new int[max - min + 1];

   for (int i = 0; i < array.length; i++) {
     countIntegers[array[i] - min]++;
   }

   int insertPosition = 0;
   //fill array in sorted order
   for (int i = min; i <= max; i++) {
     for (int j = 0; j < countIntegers[i - min]; j++) {
       array[insertPosition++] = i;
     }
   }
   return array;
 }

 static int[] sort(int[] array) {
   int min, max = min = array[0];
   //determine the max and min in the array
   for (int i = 1; i < array.length; i++) {
     if (array[i] < min)
       min = array[i];

     if (array[i] > max)
       max = array[i];
   }
   return sort(array, min, max);
 }

 //class SimpleTimer

 private long lastStart = -1;
 private long time;

 public void start() {
   if (lastStart != -1)
     throw new IllegalStateException("Call stop before!");

   lastStart = System.currentTimeMillis();
 }

 public void pause() {
   if (lastStart < 0)
     throw new IllegalStateException("Call start before!");

   time = time + (System.currentTimeMillis() - lastStart);
   lastStart = -1;
 }

 public String toString() {
   return time / 1000f + "";
 }

Internetmusic with Java

A small group on twitter started a funny (or stupid?) mem #internetmusiker (which is internet-musician in English). The initial idea came from FR31H31T. The task was to slightly change a name of a musician, band or song and get a phrase which sounds like an internet- or computer-technical phrase. The results were sometimes very funny and my favourite examples are:

Nine inch Mails, Modem Talking, Deftunes, Wii valdi oder iValdi and Sudo Lindenberg

Look here for the full list!

Now I wanted to know which phrases were the most retweeted once and I wrote a small Java application which uses the twitter4j API to do this task.


Twitter twitter = new Twitter(login, pw);
for (int page = 1; page < 1500; page++) {
 Query query = new Query("internetmusiker");
 query.setPage(page);
 query.setRpp(50);

 try {
   QueryResult res = twitter.search(query);
   if (res.getTweets().size() == 0) {
     log("No more tweets found");
     break;
   }
   log("page:" + page + " found " + res.getTweets().size() + " tweets");
   for (Tweet twe : res.getTweets()) {
      allTweets.add(twe);
   }
 } catch (TwitterException ex) {
   log("End of search reached", ex);
   break;
 }
}

To avoid a full search for the next time I saved the results via my small helper object StoreableTweet to a text file and used ‘query.setSinceId(maxId);’ while querying.

To calculate the retweets there is no API provided (or am I wrong?) so I needed to parse for a ‘RT @name text’ and look up the text within all the tweets. For that I created a hash map with the text content as keys.


 Map<String, StorableTweet> mappedTweets = new HashMap();

 for (StorableTweet stw : allTweets) {
   String key = stw.getTextToRetweet();
   if (mappedTweets.containsKey(key))
     log("Mapped tweets collection already contains tweet:"
         + stw.toPersistentString());

   mappedTweets.put(key, stw);
 }

 for (StorableTweet stw : allTweets) {
   if (stw.getOrigRetweetedText().length() > 0) {
     StorableTweet retweet = mappedTweets.get(
       stw.getOrigRetweetedText());
     if (retweet == null)
       log("Skip retweet: cannot find retweet "
          + stw.toPersistentString());
     else
       retweet.addRetweet(stw);
   }
 }

Again you can look here for the resulting html file. So start your own with #internetmusiker oder even #internetmusician?

Where is UML for NetBeans 6.8?

Flattr this to let me do an update for NetBeans 7.0!

————————————————————————

Recently I wanted the good and fancy UML editor for NetBeans 6.8 to display the class diagram of our twitter search jetwick, but I couldn’t find it in the update center.

The  solution seems is simple. I clicked here and got the zip called netbeans-6.8-200912091457-ml-uml.zip which needs to be extracted into your NetBeans installation. After this I was able to create an UML project from the project menu:

I created a project to reverse-engineer my java project where even maven (jar or war) was possible. Look here:

But at the time of NetBeans 6.5 the packages were filled with content! Now they are empty and no class diagrams can be easily generated from source code 😦

The import of the java files seems to work, because if I right click the project I could create a model report with all my classes and its dependencies.

Do you know my mistake? I just wanted to create a class diagramm from my project.

Update: There seems to be no solution for NetBeans 6.8. See StackOverflow.

Update2: No, wait. Read this.

Hidden Features of Java

This is a nice ‘question’ on StackOverflow: What are hidden features in Java?

I didn’t read about this nice one:


Integer integ1_a = 1;
Integer integ1_b = 1;
Integer integ1_c = new Integer(1);
Integer integ1_d = new Integer(1);

Integer integ128_a = 128;
Integer integ128_b = 128;

assertTrue (integ1_a   == integ1_b);   // again: this is true!
assertFalse(integ128_a == integ128_b); // again: this is false!
assertFalse(integ1_c   == integ1_d);   // again: this is false!

Read more about this issue by searching java’s pool of integer (internal ‘cache’ from -128 to 127 for autoboxing) or look into Integer.valueOf

Of course you can vote for my comment on stack overflow 😉

CRUD with Wicket + Guice + Db4o / NeoDatis

The journey began with a search for a database for my desktop application TimeFinder. It turned out that there are at least 3 candidates if I would choose a simple and only one tier architecture:

  1. GORM
  2. NeoDatis
  3. Db4o

One tier applications would only make sense for some special uses cases like in my case for high schools with one timetable admin. But it would be a lot better if I could use sth. like remote GORM, remote object persistence or even an ajaxified web application. Yes. Why not? What, if I rewrite the UI from scratch and move from ‘Swing Desktop’ to web? But then again: which web framework and which persistent architecture?

A lot of people would recommend Grails (myself included) if I need a simple CRUD web framework, but for me Grails is a bit heavy weight (~ 20 MB) and I will have to live with at least 6 languages: GSP, JS, HTML, ‘Spring-XML’, Java and Groovy. I will need Java at least for the performance critical part: the timetabling algorithm.

Okay. Then, why not GWT or Eclipse RAP? GWT has Javascript compilation, which I am not a big fan of and Eclipse RAP requires pure Eclipse development, I guess. So what else? There are a lot of Java web frameworks (with Ajax) as I discovered earlier. My choice now was simple: Wicket, which is Swing for the web. But what if you don’t like Swing? Then you will love the ‘Swing for the web’ 😉 !

Wicket Features

From what I learned in the last days and from blog posts; Wicket is outstanding in the following areas:

  • Separation of UI and code. You only have
    • pure HTML no new syntax required ala JSP, JSF, GSP, velocity, … the latter one was the reason for not choosing click. No Javascript hassle … if there are some, then I trust the wicket community to fix them in wicket itself
    • and pure Java. This is very good if you’ll someday refactor your code. And you’ll.
  • You can create your own components easy and fast. You can even create ajax components without xml and js… only Java.
  • A strong community (even a German book)
  • No route file necessary. (This can be a disaster for manually managed JSF apps)

Okay. And the persistent layer? That was the reason for this journey … hmmh, there are already several different persistent ‘technics’ for Wicket available:

Hmmh, but I only need a very simple persistent layer. No complex queries etc. As I mentioned earlier I can even live with xml (for datastorage). I decided to look into db4o again (used it in gstpl which is the antecessor of TimeFinder) and into the more commercial friendly (LGPL) object oriented database NeoDatis. The latter one has an option to export to xml and import the same, this would be great so that I don’t have to think about database migrations (some refactorings will be applied automatically. see 1.10 in the PDF docs). Migration in db4o should be easy too.

While I was thinking about that, I asked on the Apache Wicket mailing list for such simple persistent solution. Jeremy Thomerson pointed out that there are even some maven archetypes at jweekend which generates a simple Wicket app with persistence for me. I chose the Wicket+Guice+JPA template and updated this to use Guice 2.0 and the latest warp-persist according to this post. After that I needed to make db4o or NeoDatis working. For the latter one I needed warp-persist-neodatis and for the first one I only needed some minor changes, but they took a bit longer.

Resources

For those who want to see the results, here are the 2 independent maven projects (Apache License 2.0) within my subversion repository (revision 781):

To try the examples just type ‘mvn install’ and run ‘mvn jetty:run’. The resulting war file is amazing small: under 6 MB!

Now point your firefox or opera to http://localhost:8080/timefinderwicket/

And here is the screenshot:

As you can see the localized warning messages are already provided and shown instead of “Please enter a value into the field ‘location'”.

To work with wicket is a great experience! In another project it took me about 10 minutes to convert a normal submit into an ajax one which updates only selected components. And then, in the NeoDatis project I initiallly developed my EventDataView against a completely different data item and moved the source nearly unchanged to the db4o project with the Event class! That is nice component oriented development. Okay, I did copy and paste rather then creating a maven submodule for the pageable list, but that wouldn’t be that difficult with wicket. Then as a third example I overwrote the navigation panel, which was easy too: Now instead of

<< < 1 2 ... > >>

it will be shown

First Prev 1 2 ... Next Last.

without touching the UI. You can even provide ‘properties’ files to apply easy I18n.

Coming Home

Wicket is like coming home ‘to desktop’ after some years of web development, especially in the UI layer. And guice perfectly meets my dependency injection requirements: pure Java.

To get all things right I had to tweek the initial example of jweekend a lot, but all necessary changes were logically and does not smell like a hack. As a first step I updated the versions of the artifacts and then I added a DataView from the repeater examples. The developed CRUD example is now built with dependency injection instead of the original locator pattern (ala DatabaseLocator.getDb()):

@Inject
Provider<ObjectContainer> oc;

Then the update mechanism and some other exception must be solved, but you only need to check out the sources and see what is possible!

As a side note

please keep in mind that there is a NetBeans Plugin for Wicket 1.4.x and an IntelliJ plugin for the same. For all NetBeans guys which are interested in ‘deploy on save’ feature you only need to enable ‘Compile on Save’ and then you can change code or HTML in Wicket, if you are running the application via jetty:run (jetty configuration is already done in the pom). Currently this works only with db4o as a standalone server. To my knowledge this way of UI prototyping can be even faster than with Grails, where it could take some seconds to be recompiled.

Conclusion

Dive into the world of Wicket right now!