Ultrashort JAXB tutorial

By Confusion on Tuesday 3 February 2009 20:49 - Comments (3)
Categories: Java, Software engineering, XML, Views: 7.266

Today I had to use JAXB for XML-object binding. While searching for an introduction, I noted that most articles handling JAXB seemed to be overly long and concerned with all kinds of asides that detracted from the basics, which were all I needed. Therefore I now present: an ultrashort JAXB tutorial.

I will expect you know:
  • What XML-object binding is and why you would want to use it.
  • How to use Java and solve classpath issues and such
  • How to use Linux (or translate the instructions to Windows).
  • How to determine intermediate steps I left out (like 'extract the zip')
Requirements:
  • An XML file that you wish to 'unmarshal' into an object tree. Example:
    XML:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    
    <?xml version="1.0" encoding="UTF-8"?>
    <rootElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://some.sensible.url/foo"
        xsi:schemaLocation="http://some.sensible.url/foo foo.xsd">
    
        <subElement>
            <foo>1</foo>
            <baz>2</baz>
        </subElement>
        <subElement>
            <foo>2</foo>
            <baz>4</baz>
        </subElement>
        
    </rootElement>

  • An XML Schema description of the structure of the XML. Example:

    XML:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://some.sensible.url/foo" 
        xmlns:f="http://some.sensible.url/foo" 
        elementFormDefault="qualified">
    
        <element name="rootElement">
            <complexType>
                <sequence>
                    <element name="subElement" type="f:subElement"
     maxOccurs="unbounded" />
                </sequence>
            </complexType>
        </element>
        
        <complexType name="subElement">
            <sequence>
                <element name="foo" type="int" />
                <element name="baz" type="int" />
            </sequence>
        </complexType>
    </schema>

Tutorial
  1. Use a Java 6 SDK (which has JAXB) or download JAXB (and use a Java 5+ JDK)
  2. Generate the objects from the xml schema by issuing
    jaxb-ri/bin/xjc.sh -p com.company.app.pakkage.of.objects \
    -d /path/to/com/company/app/pakkage/of/objects \
    /path/to/xml-structure.xsd
  3. Assuming the root element of your xml is named 'rootElement' (and available as com.company.app.pakkage.of.objects.RootElement):

    Java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    package com.company.app;
    
    import java.io.File;
    import javax.xml.bind.*;
    import com.company.app.pakkage.of.objects.*;
    
    public class Example {
    
        public static void main(String[] args) throws JAXBException {
            
            final JAXBContext jaxbContext =
                JAXBContext.newInstance("com.company.app.pakkage.of.objects");
            final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            final RootElement rootElement =
                (RootElement) unmarshaller.unmarshal(new File("/path/to/xml.xml"));
        }
    }

  4. Profit.

Nicer, shorter, GWT url's

By Confusion on Wednesday 5 November 2008 12:18 - Comments (4)
Categories: Java, Software engineering, Views: 7.098

A thorn in the side of every GWT developer must be the ridiculous URLs it produces. Please, come and visit our wonderful webapp at
http://company.com/thisapp/com.company.app.module/Module.html
... very attractive... Of course, you can have http://company.com/thisapp/ redirect there, but still.

Fortunately, there is an easy way to shorten the URL, as explained in this not so aptly named thread in the Google Groups group on GWT. If you choose a decent module name, you end up with
http://company.com/module/Module.html, which is acceptable.

If you use the maven-gwt plugin to build your project, you need to modify both the compile targets and the run target to

code:
1
2
3
4
<compileTargets>
    <value>Module</value>
</compileTargets>
<runTarget>Module/Module.html</runTarget>

Converting a certificate + key to a usable Java keystore

By Confusion on Friday 31 October 2008 15:04 - Comments (2)
Categories: Java, Software engineering, Views: 6.627

Today I was researching the obstacles I would encounter while upgrading the Resin Application Server from 2.1 to 3.1. One of the things that came up was that OpenSSL support is no longer supported in the open source version: you would have to buy a license to enable the JNI bindings to OpenSSL.

However, JSSE is also supported as the SSL connection handler, so I decided to find out what was involved in switching from OpenSSL to JSSE. That proved to be quite easy, with a Java 6 JDK that already includes a configured JSSE library. The largest problem was converting the certificate + key to a Java keystore. For everyone that may one day have to solve this problem:

First put the certificate and the key in a pkcs12 keystore:

code:
1
openssl pkcs12 -export -out dev.pkcs12 -in dev.crt -inkey dev.key


then convert the keystore to a JKS keystore, using the Java keytool:

code:
1
2
keytool -importkeystore -srckeystore dev.pkcs12 -srcstoretype PKCS12
 -destkeystore dev.keystore


This example involves a self-signed certificate; if you need to include CA certificaties or certificate chains, the process is slightly more complicated, but probably not very, as you can use openssl to perform all the hard steps. If I encounter any problems when I do that, I will let you know ;).

On a sidenote: Java keystores are terrible things and I dread the moments when I discover they are once again inevitable in reaching a certain goal.

Using exceptions in Java

By Confusion on Sunday 19 October 2008 13:58 - Comments (19)
Categories: Java, Software engineering, Views: 28.532

Last week it struck me that I've never really used exceptions in Java properly, despite having written thousands of lines of Java code over the last three years. Of course I have written plenty of try-catch blocks, logged, chained and wrapped exceptions in my own custom exceptions, but ultimately, I hardly ever use them like they were intended: as a replacement for result codes and a means to easily propagate 'failures' up the stack. Instead of using exceptions, I often use result objects that simply wrap the actual result object, together with a boolean indicating whether the call was succesfull and an optional failureMessage.

The question that immediately followed is: why? Why has it taken me so long to realize the way in which exceptions are meant to be used? I think the problem is twofold:
  • The name feels wrong and
  • Nonlocal behaviour is hard to grasp
The first one is simply this: when a method fails, this often isn't exceptional. For instance, someone requests the order with ID 1529, but no order with that ID exists. The method fails and I could throw an 'OrderDoesNotExistException', but that just feels wrong, because the situation simply isn't exceptional. I think this can be mitigated by simply changing the name of such a custom Exception to 'OrderDoesNotExistFailure' or the even simpler 'OrderDoesNotExist'.

The second is a more subtle problem, which I think has to do with the fact that code is easier to understand when you handle the result of a method call immediately, even if that consists only of 'inspect the boolean in the wrapped object and branch'. When throwing an exception, the flow continues somewhere far from the original method call and this is less intuitieve. However, one can develop an intuition for it, if one properly designs the use of exceptions beforehand. And that is the ultimate problem: I've never thought deeply enough about the way one should/could use exceptions.

Running a Java 1.3.1 JDK on Debian

By Confusion on Monday 1 September 2008 09:29 - Comments (4)
Categories: Java, Software engineering, Views: 3.201

Today I needed to fix a bug in an application that runs at a number of different sites, some of which are still stuck at Java JRE 1.3.1. Therefore I downloaded the appropriate JDK from Sun and happily typed

code:
1
./build all


only to be greeted by

code:
1
2
3
/usr/local/jdk1.3.1_20/bin/i386/native_threads/java: error while loading shared
 libraries: libstdc++-libc6.1-1.so.2: cannot open shared object file: No such file
 or directory


What's wrong is that the linux version of this JDK depends on a pretty old version of libstdc++. Luckily, a compatible library is still available from the Debian archives.