Thursday 9 August 2012

Eclipse 4.2 (Juno) - Bugs

For the last couple of releases the Eclipse project has been working on two streams of development. 3.x uses the legacy workbench and has been the primary release train in past years. However, since Eclipse Helios (3.8) there has also been a second 4.x release train working on a new workbench framework. This has been delivering releases at the same time as 3.x (e.g. Helios (3.6/4.0), Indigo (3.7/4.1)).

This year Eclipse Juno (3.8/4.2) was released and for the first time the 4.x version was chosen to be the primary release and 3.8 is in theory the last 3.x release. Unfortunately my testing has quickly revealed some glaring bugs - basic elements of interacting with the workbench don't quite work correctly. I have raised five bugs and found one existing bug covering the key issues which I hit:
  • 362420 - Make "Quick access" optional and hidden by default
  • 386804 - The target area to DND Views and Editors into existing stacks is too small
  • 386803 - Quick Access mishandles Home and End
  • 386802 - DND of Views and Editors not working properly
  • 386806 - New Eclipse Icon not used by Eclipse 4.2 on Windows 7
  • 386817 - Customize Perspective Tool Bar Visibility appears broken in 4.2
Eclipse 4.2 also includes a new default theme (new and noteworthy, bug covering implementation) which I really dislike. A classic theme is included which makes Eclipse look much more like the previous 3.x releases but tediously you have to restart to fully apply a theme change despite Eclipse updating most elements dynamically and not warning that a restart is needed to fully apply the change (362522).
    Eclipse 3.8 workbench:


    Eclipse 4.2 workbench:


    As a result of all of these issues I will be sticking to Eclipse 3.8 this year but I will keep an eye on future 4.x releases. The Eclipse 4.2 downloads are easy to find but there is only one 3.8 package available:

    Wednesday 8 August 2012

    JD-Eclipse Realign - Source Lifetime

    In my initial post about my fork of JD-Eclipse Realign I mentioned the difficulties I encountered in trying to allow a user to switch quickly between decompiled source and attached source. Since that post I have realised that my original fix was insufficient.

    Opening a class file in the JD-Eclipse Realign editor involves the following steps:
    1. Check whether a source mapper is already installed for the container jar.
    2. If one already exists use that to get the source for this class file.
    3. If one does not exist create a new one, register it with the container jar and then use it to get the source for this class file.
    The JD-Eclipse editor subclasses the built in Class File Viewer (which already implements steps 1. and 2.) and provides an implementation of 3. that always returns a source mapper that generates decompiled source code. This has the unfortunate side effect that once you have loaded a single class in the JD-Eclipse editor (which registers a decompiling source mapper with the jar) you can open the standard Class File Viewer and get decompiled source for any other class in the same jar.

    My original JD-Eclipse Realign editor changes fixed this by de-registering the source mapper when you close the editor. This still meant that while a single JD-Eclipse Realign editor was open you could still get decompiled source in the standard Class File Viewer. I tried to address this once and for all by removing the source mapper as soon as the JD-Eclipse Realign editor was opened. Unfortunately this had unforeseen consequences. It turns out that navigating to a particular element (e.g. from the Outline view) relies on a source mapper being available.

    In light of all of this I concluded that having a special JD-Eclipse editor was actually the wrong approach. A better solution is to treat enabling class decompilation the same way as attaching real source code. To enable this I reworked the Open Class With menu which I had already added to work slightly differently.
    • When there is no source attached and decompilation is disabled:

    • When there is no source attached and decompilation is enabled:

    • When there is source attached:


    In this last case the menu doesn't allow decompilation to be directly enabled for dull implementation reasons. In all cases when the source attachment/decompilation state changes all open class file viewers are updated.

    With the addition of these new menu options I have also removed the JD-Eclipse Realign editor. My code is packaged as a fragment that extends the base JD Eclipse plugin so I can't remove the vanilla JD Eclipse editor. However, on every startup my fragment will check whether the JD Eclipse editor has been associated with class files (or class files without source) and revert any such associations to use the standard Class File Viewer.

    An updated version of JD Eclipse Realign is available from my update site now: http://mchr3k-eclipse.appspot.com/

    If you have any issues please do raise it here.


    Tuesday 7 August 2012

    Java Packaging

    jar (http://ant.apache.org/manual/Tasks/jar.html)

    The basic mechanism for packaging Java code is within a jar file. This can be achieved in ant using the jar task. The jar task is more powerful than it first appears as you can use a nested zipfileset to package multiple source jars into a single output jar.

    However, the danger with this mechanism is that you may end up packaging a version of a class which conflicts with the version required by another dependency.

    jarjar (http://code.google.com/p/jarjar/)

    jarjar extends the default jar ant task with a new "rule" child element which specifies mappings of package names. This rewrites all the classes within the output jar to move the classes within the specified packages and update all the references to these classes.

    For example org.apache.commons.io could be moved to com.product.internal.commons.io. This is one way to avoid the classic jar hell.

    jarinjarloader (no site)

    The jarinjar classloader is an internal part of the Eclipse JDT project. However, you can get the classes by opening org.eclipse.jdt.ui_*version_number*.jar with an archiver and extracting the file jar-in-jar-loader.zip.

    With the aid of these classes it is possible to package a jar within another jar and still load the contained classes and resources. For an example of what this looks like in practice you can look at getSWTClassloader() in SWTLoader.java.

    Another project which claims to do the same is One-Jar (http://one-jar.sourceforge.net/). However, I haven't used this myself.

    swtjar (http://mchr3k.github.com/swtjar/)

    The standard approach to packaging SWT applications is to create a bundle per platform (32/64 bit and Win/Linux/OSX). This is because SWT requires the application to load the correct jar for the platform being used.

    However, with the help of the jarinjar loader classes it is possible to include multiple SWT jars within an application jar and then use standard platform detection code to pick the correct one to programmatically add to the class path. My swtjar project packages this solution as an ant task.

    jarbundler (http://informagen.com/JarBundler/)

    OSX has its own package format to allow an application to provide an icon and control startup options. This is particularly useful as SWT on OSX requires an extra command line argument to work. The jarbundler project is an ant task that helps you to build OSX application bundles.

    For details about using this tool you should refer to this page: http://mchr3k.github.com/swtjar/osxapp.html