Category: Java

05/14/10

Permalink 12:04:26 pm, by admin Email , 528 words, 87 views   English (US)
Categories: Java

Cross-compiling around @Override interface-method

Every now and then the decision is made to have a Java library more broadly usable by compiling for an older Java version. When developers are working with the latest compiler and do not set their project settings to match the specified version, newer features creep in, and once in a while you’ll see some activity removing those features again (mostly right before a release).

I recently observed such an activity where @Override annotations were removed from source code, as the library should be compatible with J2SE 5. Now, J2SE 5 reached its End of Service Life last year, so one might debate whether users should use that version at all, but consider that decision to be made.

Personally, I rather like having @Override on methods implementing interface methods. In Java 5 the @Override annotation was added, but could only be applied to methods overriding other implementations, not interfaces. This was changed in Java 6, which makes the code more robust. The removed annotations will likely not be re-added immediately if a decision is made to base the library at Java 6, so let’s have a look at another option.

The javac Java compiler has the option to cross-compile to another version of Java, perhaps this can be used to compile the code with the latest compiler, keeping the annotations and their safety improvements in the code, while distributing a version that is compatible with Java 5?

To test this, I created the following file:

Code:

//import java.util.Deque;
 
public class Test implements TestInterface {
        public static void main(String[] args) {
                TestInterface t = new Test();
                t.printHello();
        }
 
        @Override
        public void printHello() {
                System.out.println("Hello!");
        }
}
 
interface TestInterface {
        void printHello();
}

Compiling this with JDK6 works fine, but running with an older Java version doesn’t:

$ /usr/local/jdk1.6.0_14/bin/javac Test.java
$ /usr/local/jdk1.5.0_22/bin/java Test
Exception in thread "main" java.lang.UnsupportedClassVersionError: Bad version number in .class file
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:621)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
...

When compiling with an older version, like JDK 1.5 u 22, we’ll get an error:

$ /usr/local/jdk1.5.0_22/bin/javac Test.java
Test.java:9: method does not override a method from its superclass
@Override
^
1 error

Now if we use the cross-compiling feature, the compilation succeeds, as does the invocation of the class with Java 5:

$ /usr/local/jdk1.6.0_14/bin/javac -target 1.5 -bootclasspath /usr/local/jdk1.5.0_15/jre/lib/rt.jar -extdirs "" Test.java
$ /usr/local/jdk1.5.0_22/bin/java Test
Hello!

The given settings specify that the code should be compiled for Java 5, and that the libraries of jdk1.5.0_15 should be used. The reason for passing the libraries of an older version is to prevent runtime errors when classes are used that were added in a later version, like the Deque interface for which the import is commented-out. With the import and the correct bootclasspath, the compiler will generate an error.

Also note that if the code were changed so that the method did not override an interface method any more (hard to imagine in such a contrived example, but it does happen in real-life, especially when using overloaded methods), the Java6 compiler WILL terminate with an error.

04/16/10

Permalink 09:27:33 pm, by admin Email , 29 words, 37 views   English (US)
Categories: Java

Nice exceptions read

I would like to recommend this read by Elliotte Rusty Harold: Tip: When you can’t throw an exception.

It’s nice to see there are still proponents of checked exceptions.

04/03/10

Permalink 08:00:27 pm, by admin Email , 683 words, 65 views   English (US)
Categories: Java

Extending GPX and processing the result with JAXB

Recently I found myself in need of storing some additional information to GPS tracks I recorded (colors for visualization in my GPS post-processing application, descriptions, etc). The GPX 1.1 schema allows for extensions to be specified. Essentially, there are some spots where you can drop an ‘extensions’ element and fill it with anything you like. It turns out that one can generate a JAXB parser that supports this situation.

The relevant part of the GPX schema looks like:

Code:

....
<xsd:complexType name="trksegType">
  ...
  <xsd:sequence>
    <xsd:element name="trkpt" type="wptType" minOccurs="0" maxOccurs="unbounded">
    ...
    </xsd:element>
    <xsd:element name="extensions" type="extensionsType" minOccurs="0">
      <xsd:annotation>
        <xsd:documentation>
          You can add extend GPX by adding your own elements from another schema here.
        </xsd:documentation>
      </xsd:annotation>
    </xsd:element>
  </xsd:sequence>
</xsd:complexType>
....
<xsd:complexType name="extensionsType">
  ...
  <xsd:sequence>
    <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded">
      ...
    </xsd:any>
  </xsd:sequence>
</xsd:complexType>
....

Now an extension can be as simple as:

Code:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="http://floris.ouwendijk.nl/gpxeditor/1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
  <xsd:element name="gpxeditor">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="name" type="xsd:string"/>
        <xsd:element name="color" type="xsd:string"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

There is no need to extend or include the GPX schema. Do note that the GPX schema allows for extensions elements in multiple types, such as the trksegType above, but also in gpxType, wptType and others. The schema will therefore not enforce that for instance a track segment can have a color and a name, but a point in that segment can’t. Or that the point can have a name but no color. Support for the values and enforcement of rules will be up to the application.

Having JAXB generate the parser has many advantages over crafting a parser and writer by hand. For one it is easy and all classes are instantly available, along with type safety and prevention of misspelling element names. One distinct advantage that I can really appreciate is that it will also keep track of features not used by the application as well as unknown extensions. For instance, my application has currently no need for hdop, vdop, etc. Some parsers and writers, like that of NASA WorldWind, do not use it either, but will also strip the data from the file when exporting a parsed file. Extensions from other tools will also disappear. JAXB on the other hand, will insert W3C-DOM elements into the list containing the contents of the extensionsType when no parsing rules are found. These elements can be used for manual parsing, and they will be written along with all the data if the GPX file is written back to disk.

Now, the generation of the parser for just the GPX schema is as easy as:

xjc -d generated -p gpxschema gpx.xsd

To support the extensions, you only need to add the custom extension schema:

xjc -d generated -p gpxschema gpx.xsd gpxeditor-extension.xsd

Parsing a GPX file remains simple:

Code:

JAXBContext jc = JAXBContext.newInstance("gpxschema");
Unmarshaller u = jc.createUnmarshaller();
GpxType gpx = ((JAXBElement<GpxType>) u.unmarshal(gpxFile)).getValue();

Now to get to the color for a TrksegType, you’d need to iterate over the elements in the extensions element, looking for an instance of the Gpxeditor class, which was generated by JAXB for the element matching the definition given in the second schema:

Code:

for (Object obj : trackSegment.getExtensions().getAny()) {
  if (obj instanceof Gpxeditor) {
    return ((Gpxeditor)obj).getColor();
    }
}

To add extensions to a file, you can add a new instance of ExtensionsType to the appropriate type (such as an instance of TrksegType) and subsequently add an instance of the Gpxeditor class to the list returned by getAny().

12/15/09

Permalink 12:13:36 pm, by admin Email , 498 words, 98 views   English (US)
Categories: Java

Closure issues clarified

With the recent revival of adding closures to Java, I came across the post by Stephen Colebourne that contained an updated version of his comparison table (which appeared earlier in his ‘Comparing ‘closure’ proposals’ post). The list contained some items that weren’t immediately clear to me, so I went ahead to attempt to attach a description to each of them.

Literals for reflection
Instead of using Strings and reflection to create a reference to a method or field, reflection literals would allow you to directly refer to a method. One of the benefits is the possibility of compile-time checks.

Method references
The above reflection literals allow for references to existing methods, which can then (easily) be passed around and called.

Closures assignable to single method interface
This allows a closure to be assigned to a variable whose type is an interface with a single method. This would eliminate the verbose syntax currently used to create an anonymous inner class with a single method, like a Runnable or ActionListener.

Closures independent of single method interface
Having closures independent of a single method interface allows the creation of closures without the need for an interface to exist.

Access non-final local variables
With inner classes, one cannot access local variables (variables local to the method that defined the inner class). Being able to access and modify non-final local variables gives more flexibility.

Keyword ‘this’ binds to enclosing class
With inner classes, ‘this’ binds to the instance of the innerclass. Most proposals agree that ‘this’ will refer to the enclosing class.

Local ‘return’ (binds to closure)
This means that a return statement within a closure will return from the closure and continue from the location where the closure was called.

Non-local ‘return’ (binds to enclosing method)
In contrast to the local return, the non-local return would return from the defining method. In a situation where the closure blends in with the rest of the code, as in control structures, this makes a lot of sense but the BGGA proposal is the only one proposing this. It has some issues when the method containing the definition has already exited.

Alternative ‘return’ binding (Last-line-no-semicolon)
Complements the previous item: if the default is a non-local return, then this would allow one to return a value from a closure.

Exception transparancy
When an exception is thrown from a method, it needs to be defined. For closures this would either require function types or interfaces to specify the exceptions that can be thrown from the closure, or the exception to be handled/converted within the body of the closure. By having exception transparency the exceptions need not be defined beforehand, and can be handled by the code calling the closure.

Function types
These are used to be able to assign a closure that is independent of an interface to a variable.

Library based Control Structure
This means that control structures, such as the enhanced for loop, can be added as a library, instead of modifying the language.

11/20/09

Permalink 04:04:05 pm, by admin Email , 659 words, 89 views   English (US)
Categories: Java

Devoxx 2009 - day 3

The last day of Devoxx. The booths are gone, the pavilion is closed, just four parallel tracks and three timeslots to go to.

‘The Pomodoro technique’ in the methodology track discussed techniques for gaining flow/focus (whichever you’d like to call it) and optimizing one’s effectiveness. It started with a lengthy introduction on the subject, discussing duration vs events (durations make anxious), the arousal graph (which shows that optimal arousal is somewhere between complexity and redundancy, when something becomes so common it is boring), procrastination. and the attention deficit trait (this is illustrated with a sketch with puppets about a workday that is constantly interrupted). Instead of either having interruptions steer your day or planning everything a year ahead, one should use the pomodoro technique. It works by selecting a subject, working on it for a predefined amount of time (25min) not allowing distractions. During the day you go through a few states: planning in the morning (don’t over- or under-commit). Then do multiple iterations, tracking how you’re doing. In the evening you record how you did, process the data and finally visualize how you can improve your performance. Tools: pencil, timer, todo-today list, activity inventory (big todolist) and recordsheet. During a pomodoro (focus period of 25mins), you break for a few minutes, followed by a minute or so determining what to do next, which might be the same action. After four pomodoro periods you break for a period of 15-20 minutes. If your done with a task within a pomodoro you keep on the activity, optimizing it or leaning from it. The recording phase records the number of pomodoros you did. Interruptions are what hold you back from completing pomodoros (if you stop/break the pomodoro it doesn’t count as a pomodoro), and can be categorised as internal and external. Dealing with the internal interruptions is visualizing and intensifying. A strategy is to add it to the todo-list (marking it as an interruption for tracking). Dealing with external interruptions can be turning off devices and telling people to come back later. Again, this is recorded (with a different mark). If the interruption is so large that you have to stop, you void the pomodoro.

‘Towards a universal VM’ by Brian Goetz and Alex Buckly looked at the evolution of the Java VM from a platform for the Java Language to a platform for all sorts of languages. It is enabled by the JIT: static compilers can generate ‘dumb’ bytecode, while the JIT compiler can work with the information that is only available at runtime. Since the JIT optimizations are bytecode specific, all languages will benefit from those. Now more and more languages are used on the platform, some specific changes are required to the JVM to allow for some ‘tricks’ that Java doesn’t need, but some (dynamic) languages do. Those languages currently simulate the required features, leading to decreased performance. Of the many requested features, more flexible method calls is the most urgent. The result is ‘invokedynamic’, where the VM asks some language logic how to call the method. This allows for multiple problems to be solved at once in an elegant way.

‘Project Lombok: bye bye boilerplate’ was presented nicely. I recently heard about Lombok in several blogs/podcasts, and wanted to check it out. Lombok generates the boilerplate for getters, setters, and constructors on value objects, and it can also be used to generate toString, hashCode and equals methods. Then there’s annotations for cleanup, synchronization and exceptions. The project is available for Javac and Eclipse, volunteers are needed for Netbeans and IntelliJ support. The presentation fell a bit short on clarifying what’s under the hood, but as a tool this could be very useful to reduce the clutter of code.

Another great event has come and gone. The way of picking sessions works well: there were few sessions that were less interesting. I had a great time, and another list of follow-up actions to keep me busy.

:: Next Page >>

Floris' Blog

Personal blog on my interests.

| Next >

September 2010
Sun Mon Tue Wed Thu Fri Sat
 << <   > >>
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    

Search

Categories

Misc

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 2

powered by b2evolution free blog software