My mum keeps telling me I used to be gifted child. Of course I don't remember everything I did at the age of three, but I seem to have signed up for the java.net forums at that time. Quite impressive!
Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts
26 June 2010
14 May 2010
Java XML Binding with Property Change Support
In an earlier post, I was talking about generating Java classes with xjc with property change support which is not enabled by default. This post explains the details, an in fact the Maven build explained below is a lot a easier than my original approch with Ant which required some downloads to set things up.
The general idea is same as described by Kohsuke Kawaguchi in a post of 2007, but his POM is broken with the current stage of the Maven repositories. In addition, there is a tweak with the PropertyListener customization.
So here is a little example schema:
We use the following file bindings.xjb to customize the Java classes generated by xjc. We make all classes serializable and include support for PropertyChangeListeners.
The following POM takes care of the code generation:
You do need to use the 1.1-SNAPSHOT version of the property-listener-injector, as the 1.0 release only supports VetoableChangeListeners and not the PropertyChangeListeners we want to use. The <li:listener> element in the bindings file is used to define the listener class.
It is important to exclude the jaxb-xjc dependency from the property-listener-injector, or else it will try to download an non-existing snapshot version. Looks like something is broken in the java.net repository, but then again, working with snapshot releases is always dangerous....
The general idea is same as described by Kohsuke Kawaguchi in a post of 2007, but his POM is broken with the current stage of the Maven repositories. In addition, there is a tweak with the PropertyListener customization.
So here is a little example schema:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/person/" targetNamespace="http://www.example.org/person/">
<complexType name="Person">
<sequence>
<element name="firstName" type="string"></element>
<element name="lastName" type="string"></element>
<element name="address" type="tns:Address"></element>
</sequence>
</complexType>
<complexType name="Address">
<sequence>
<element name="street" type="string"></element>
<element name="houseNumber" type="string"></element>
<element name="city" type="string"></element>
<element name="postalCode" type="string"></element>
<element name="country" type="string"></element>
</sequence>
</complexType>
</schema>
We use the following file bindings.xjb to customize the Java classes generated by xjc. We make all classes serializable and include support for PropertyChangeListeners.
<?xml version="1.0" encoding ="UTF-8"?>
<jaxb:bindings
schemaLocation="person.xsd"
version="2.1"
xmlns:li="http://jaxb.dev.java.net/plugin/listener-injector"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:bindings node="/xs:schema">
<jaxb:globalBindings>
<jaxb:serializable uid="1" />
</jaxb:globalBindings>
<li:listener>java.beans.PropertyChangeListener</li:listener>
</jaxb:bindings>
</jaxb:bindings>
The following POM takes care of the code generation:
<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>jaxb-properties</groupId>
<artifactId>jaxb-properties</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>JAXB PropertyListener Demo</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<generatePackage>com.example.jaxb</generatePackage>
<schemaIncludes>
<schemaInclude>person.xsd</schemaInclude>
</schemaIncludes>
<bindingIncludes>
<bindingInclude>bindings.xjb</bindingInclude>
</bindingIncludes>
<args>
<arg>-Xinject-listener-code</arg>
</args>
</configuration>
<dependencies>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.1.13</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2-commons</groupId>
<artifactId>property-listener-injector</artifactId>
<version>1.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
You do need to use the 1.1-SNAPSHOT version of the property-listener-injector, as the 1.0 release only supports VetoableChangeListeners and not the PropertyChangeListeners we want to use. The <li:listener> element in the bindings file is used to define the listener class.
It is important to exclude the jaxb-xjc dependency from the property-listener-injector, or else it will try to download an non-existing snapshot version. Looks like something is broken in the java.net repository, but then again, working with snapshot releases is always dangerous....
28 February 2010
Misconceptions about Java Internationalization
Let me start with a joke:
Most Java developers are familiar with resource bundles backed by properties files. The basics can be found in the Internationalization Trail of the Java Tutorial. Multilingual Java applications often come with a set of properties files, e.g.
However, you may be surprised in this case to end up with a German string even when you requested a resource for an English locale.
Assume nothing is a sound principle for robust software development, and you should not assume that English is the default or fallback language. In fact, the fallback for resources from an unsupported locale is the system default locale, which is based on the host environment.
See the documentation for ResourceBundle.getBundle() and Locale.getDefault() for more details.
So when the default locale of your system is de_DE and you request a resource for locale en_US, the lookup order for the properties files is
There are two solutions:
The preferred solution is the second one, of course. Even when MyApp_en.properties is empty, it will be picked up as entry point for resource lookup. If a given key cannot be found in this file, the parent file MyApp.properties will be used as fallback, which is just the desired behaviour.
What do you call someone who speaks three languages?To be fair on Americans, even most of us multilingual Europeans tend to be biased when it comes to internationalization, tacitly assuming that text is written left-to-right and can be sorted from A to Z.
Trilingual.
What do you call someone who speaks two languages?
Bilingual.
What do you call someone who speaks one language?
American.
Most Java developers are familiar with resource bundles backed by properties files. The basics can be found in the Internationalization Trail of the Java Tutorial. Multilingual Java applications often come with a set of properties files, e.g.
- MyApp_de_AT.properties
- MyApp_de.properties
- MyApp_es.properties
- MyApp.properties
However, you may be surprised in this case to end up with a German string even when you requested a resource for an English locale.
Assume nothing is a sound principle for robust software development, and you should not assume that English is the default or fallback language. In fact, the fallback for resources from an unsupported locale is the system default locale, which is based on the host environment.
See the documentation for ResourceBundle.getBundle() and Locale.getDefault() for more details.
So when the default locale of your system is de_DE and you request a resource for locale en_US, the lookup order for the properties files is
- MyApp_en_US.properties
- MyApp_en.properties
- MyApp_de_DE.properties
- MyApp_de.properties
- MyApp.properties
There are two solutions:
- As a user, set your default locale to en when launching the application.
- As a developer, make sure to provide a properties file for locale en (which may be empty).
The preferred solution is the second one, of course. Even when MyApp_en.properties is empty, it will be picked up as entry point for resource lookup. If a given key cannot be found in this file, the parent file MyApp.properties will be used as fallback, which is just the desired behaviour.
08 November 2008
The Digital World
Digital maps and geographical databases have come to be a commonplace commodity. To locate a friend's address, you simple open Google Maps, when you go to their place by car, your nav system will guide you, and if you feel challenged by the patent folding of your Falk city map, you can download a map on your mobile phone to cover the last mile to your friend's home.
The raw geographical data for such services are supplied by companies like NAVTEQ and Tele Atlas, but it takes a lot of additional data processing to build user-friendly services based on these data.
My daytime work is dedicated to the design and development of a map compiler for Harman/Becker, which will produce the map databases for the next generation of car navigation systems to hit the market within a few years from now.
Doing this job in Java does not sound natural to everyone, but for us, the choice of Java has been the key to building our work on top of a whole lot of ready-to-use components and libraries, both for general purpose and domain specific tasks. So it is really Java and all these excellent open source components that help us getting around the world.
Let me just mention some of the Java libraries or applications that are useful for dealing with geographical data. I will cover some of them in more detail in future posts.
The best thing about geo data is that you can have a look at them - if you have some viewer tool that renders a map for you. A couple of years ago, I was searching for a Java-based alternative to the home-grown tools we use at work, and I came across JUMP. This gave me a jump start into geo data processing in Java...
JUMP is a map viewer and editor for a number of open standard data formats, and it has "plug-in" interfaces for supporting alternative data formats, which was a key requirement for me. I put the word "plug-in" in quotes, because JUMP has absolutely nothing to do with Eclipse plug-ins or extension points or OSGi bundles. JUMP does its own bit of class loader magic to use extension classes from JAR files you drop into a given folder.
I found JUMP easy to use and fairly easy to extend. Some people complained to me about its bland and somewhat out-dated GUI, but that has never really bothered me. JUMP is a solid and mature piece of work, and the major downside I see is the fact that it is no longer under active development. There are now more flexible extension mechanisms, and some of the features I would like to extend or modify are simply not laid open, so I would have to modify the sources.
Actually, Mama JUMP may have retired, but her offspring is alive and kicking: There is a whole family of JUMP spin-off projects.
JUMP introduced me to the JTS Topology Suite which it uses for all operations on two-dimensional geometrical shapes. I found JTS to be extremely useful and well-designed, it is based on solid mathematical background and suceeds in hiding the most of the maths from the average user who just needs to get his job done, and it has a rather interesting history.
JTS has an LPGL license, whereas JUMP is under GPL. This may be too restrictive for some commercial applications, and when I wrote to Vivid Solutions, the company behind both JUMP and JTS, about this licensing issue, they pointed me to uDig as an LGPLed alternative.
That must have been some time in 2005. My first encounter with uDig was not very successful: I did see the power of its architecture, built on top of Eclipse RCP, but at that time, I was simply overwhelmed by all the prerequisites you had to understand to implement as much as a Hello World plug-in in uDig. And back then, I knew little or nothing about Eclipse plug-in development, so I concluded that uDig was not (yet) for me, but I kept watching its progress.
In the meantime, uDig has grown a lot in terms of functionality, stability and documentation, whereas my own knowledge of OSGi and Eclipse technologies has increased. Getting started with uDig extensions is still rather a challenge, but my efforts have started paying off. With support from the developer mailing list, my uDig plug-ins have grown to a level of functionality almost equivalent to my JUMP extensions, so I am planning to stop working with JUMP and use uDig as a more flexible, powerful and (hopefully) future-proof platform.
The abstractions of cartographic features and datastores used by uDig are based on Geotools, another open source project providing a set of Java libraries for processing a vast number of geospatial data formats, including plain files, databases or web services. Both Geotools and uDig use JTS for geometrical operations.
All these projects directly or indirectly rely on OpenGIS standards and specifications, in particular, the Simple Features Specification. Geotools provides implementations of the OpenGIS Java interfaces published by the GeoAPI project.
To sum up, for geospatial data processing, there is a wealth of open source Java libraries based on open standards. For any Java-based development in this area, one of these projects may save you some work.
The raw geographical data for such services are supplied by companies like NAVTEQ and Tele Atlas, but it takes a lot of additional data processing to build user-friendly services based on these data.
My daytime work is dedicated to the design and development of a map compiler for Harman/Becker, which will produce the map databases for the next generation of car navigation systems to hit the market within a few years from now.
Doing this job in Java does not sound natural to everyone, but for us, the choice of Java has been the key to building our work on top of a whole lot of ready-to-use components and libraries, both for general purpose and domain specific tasks. So it is really Java and all these excellent open source components that help us getting around the world.
Let me just mention some of the Java libraries or applications that are useful for dealing with geographical data. I will cover some of them in more detail in future posts.
The best thing about geo data is that you can have a look at them - if you have some viewer tool that renders a map for you. A couple of years ago, I was searching for a Java-based alternative to the home-grown tools we use at work, and I came across JUMP. This gave me a jump start into geo data processing in Java...
JUMP is a map viewer and editor for a number of open standard data formats, and it has "plug-in" interfaces for supporting alternative data formats, which was a key requirement for me. I put the word "plug-in" in quotes, because JUMP has absolutely nothing to do with Eclipse plug-ins or extension points or OSGi bundles. JUMP does its own bit of class loader magic to use extension classes from JAR files you drop into a given folder.
I found JUMP easy to use and fairly easy to extend. Some people complained to me about its bland and somewhat out-dated GUI, but that has never really bothered me. JUMP is a solid and mature piece of work, and the major downside I see is the fact that it is no longer under active development. There are now more flexible extension mechanisms, and some of the features I would like to extend or modify are simply not laid open, so I would have to modify the sources.
Actually, Mama JUMP may have retired, but her offspring is alive and kicking: There is a whole family of JUMP spin-off projects.
JUMP introduced me to the JTS Topology Suite which it uses for all operations on two-dimensional geometrical shapes. I found JTS to be extremely useful and well-designed, it is based on solid mathematical background and suceeds in hiding the most of the maths from the average user who just needs to get his job done, and it has a rather interesting history.
JTS has an LPGL license, whereas JUMP is under GPL. This may be too restrictive for some commercial applications, and when I wrote to Vivid Solutions, the company behind both JUMP and JTS, about this licensing issue, they pointed me to uDig as an LGPLed alternative.
That must have been some time in 2005. My first encounter with uDig was not very successful: I did see the power of its architecture, built on top of Eclipse RCP, but at that time, I was simply overwhelmed by all the prerequisites you had to understand to implement as much as a Hello World plug-in in uDig. And back then, I knew little or nothing about Eclipse plug-in development, so I concluded that uDig was not (yet) for me, but I kept watching its progress.
In the meantime, uDig has grown a lot in terms of functionality, stability and documentation, whereas my own knowledge of OSGi and Eclipse technologies has increased. Getting started with uDig extensions is still rather a challenge, but my efforts have started paying off. With support from the developer mailing list, my uDig plug-ins have grown to a level of functionality almost equivalent to my JUMP extensions, so I am planning to stop working with JUMP and use uDig as a more flexible, powerful and (hopefully) future-proof platform.
The abstractions of cartographic features and datastores used by uDig are based on Geotools, another open source project providing a set of Java libraries for processing a vast number of geospatial data formats, including plain files, databases or web services. Both Geotools and uDig use JTS for geometrical operations.
All these projects directly or indirectly rely on OpenGIS standards and specifications, in particular, the Simple Features Specification. Geotools provides implementations of the OpenGIS Java interfaces published by the GeoAPI project.
To sum up, for geospatial data processing, there is a wealth of open source Java libraries based on open standards. For any Java-based development in this area, one of these projects may save you some work.
03 November 2008
Why I use OSGi
I want modules and controlled dependencies in my Java applications. OSGi gives me both, that's why I use it.
It's as simple as that. Really.
Yes, OSGi gives you a lot more into the bargain, most notably services, which I also use, but the unique selling point for me is modules.
When you look at the sources and binaries of any software system (not only in Java), preferably one you haven't written yourself, you see a lot of files in a directory structure. Usually, the directory structure reflects the system architecture, subdirectories corresponding to subsystems or components.
Some of these directories correspond to binary artifacts (JARs, DLLs, whatever) which you may want to reuse independently or in another system.
Now when you start pulling out this library, you have to satisfy all its runtime dependencies. So you need to take a bunch of other libraries for this library to work. Identifying the dependencies may be a tedious trial-and-error process.
There may be additional compile-time dependencies you cannot recognize by looking at the binaries only. In C/C++, there is often some global.h directly or indirectly included by every source file in your system.
Even if there was some clever architect who designed the system in terms of components and allowed dependencies, there is usually no guarantee that this architecture will be adhered to, because nothing ever prevents a developer from including or importing something they are not supposed to use.
Java has packages and classes with visibility levels, but classes and even packages are rather too fine-grained from an architect's perspective. I want my modules to be larger than packages, and I want to use them as configuration units. The modules should be in one-to-one correspondence to libraries or JARs.
This is just what OSGi provides. A plain old JAR is turned into an OSGi bundle (that's what modules are called in OSGi-land) simply by adding a couple of special headers to its manifest.
The manifest headers declare the import and export relations between modules. A bundle B may have a package with public classes, but at runtime, no other bundle C can use these classes unless bundle B exports them.
When working with Eclipse, its Plugin Development Environment (PDE) already controls bundle imports and exports at compile time. You get a warning when you import a class that was not exported.
Of course this does not prevent you from adding import or export directives to your bundle manifests, thus diluting the original architecture. But Eclipse offers tools for the architect (or yourself) to inspect the bundle hierarchy and to easily detect any unintentional dependencies.
This is just one aspect of OSGi, but it's the one I find most valuable.
It's as simple as that. Really.
Yes, OSGi gives you a lot more into the bargain, most notably services, which I also use, but the unique selling point for me is modules.
When you look at the sources and binaries of any software system (not only in Java), preferably one you haven't written yourself, you see a lot of files in a directory structure. Usually, the directory structure reflects the system architecture, subdirectories corresponding to subsystems or components.
Some of these directories correspond to binary artifacts (JARs, DLLs, whatever) which you may want to reuse independently or in another system.
Now when you start pulling out this library, you have to satisfy all its runtime dependencies. So you need to take a bunch of other libraries for this library to work. Identifying the dependencies may be a tedious trial-and-error process.
There may be additional compile-time dependencies you cannot recognize by looking at the binaries only. In C/C++, there is often some global.h directly or indirectly included by every source file in your system.
Even if there was some clever architect who designed the system in terms of components and allowed dependencies, there is usually no guarantee that this architecture will be adhered to, because nothing ever prevents a developer from including or importing something they are not supposed to use.
Java has packages and classes with visibility levels, but classes and even packages are rather too fine-grained from an architect's perspective. I want my modules to be larger than packages, and I want to use them as configuration units. The modules should be in one-to-one correspondence to libraries or JARs.
This is just what OSGi provides. A plain old JAR is turned into an OSGi bundle (that's what modules are called in OSGi-land) simply by adding a couple of special headers to its manifest.
The manifest headers declare the import and export relations between modules. A bundle B may have a package with public classes, but at runtime, no other bundle C can use these classes unless bundle B exports them.
When working with Eclipse, its Plugin Development Environment (PDE) already controls bundle imports and exports at compile time. You get a warning when you import a class that was not exported.
Of course this does not prevent you from adding import or export directives to your bundle manifests, thus diluting the original architecture. But Eclipse offers tools for the architect (or yourself) to inspect the bundle hierarchy and to easily detect any unintentional dependencies.
This is just one aspect of OSGi, but it's the one I find most valuable.
Labels:
Dependencies,
Eclipse,
Java,
OSGi
Subscribe to:
Comments (Atom)
