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.


16 comments:

  1. Great work on this plugin!

    One item of feedback. it is less obvious to me when looking at the default eclipse class viewer that I should right click on the class to enable decompiling of the class.

    Would it be possible to add a button or something on the no source class viewer to prompt me to enable decompilation?

    Thanks!
    Mike

    ReplyDelete
    Replies
    1. I have raised an issue to track this: https://github.com/mchr3k/jdeclipse-realign/issues/6

      However, fixing this will be a little tricky so I don't know how quickly I will have something ready.

      Delete
  2. I'm really impressed. Your algorithm is very efficient, using only the text string generated by JD-Eclipse. Mine gets a slightly better result, but it uses the internal data of JD.

    Your plugin is the best, today. Congratulation.

    Emmanuel.

    ReplyDelete
    Replies
    1. Thanks for your comment. I can't claim credit for the basic algorithm as my project is a fork of Alex Kosinsky's project. However, I have added code comments and made the algorithm line up enums and fields correctly. I am also working on trying to get the plugin to interact nicely with Eclipse as described in these blog posts.

      Delete
  3. Hi,
    I have made Class Editor as default in File Association for .class files and .class without source. But this association is not persisted in eclipse. Once i restart the file association resets to the Class File Viewer.

    Any suggestion !.

    ReplyDelete
    Replies
    1. I said in this post that "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". This post justifies why I think the Class Editor is the wrong solution.

      Instead my extension requires you to use the normal "Class File Viewer" and select decompiled source through the Package/Project Explorer context menu.

      If you want to disable "JD-Eclipse Realign" from interfering with file associations you can disable the startup hook in Preferences -> General -> Startup & Shutdown, uncheck "JD-Eclipse Plug-in".

      Delete
  4. Can someone show me how to decompile after having added by

    Install New Software

    http://mchr3k-eclipse.appspot.com and then Java Decomplier Eclipse Plug In

    then I restarted eclipse and can see the Referenced Libraries there...

    But what to do next? How to actually do the decompile as I right clicked on a class file but still no options to decompile, i.e same as before I installed this link?


    Seb

    ReplyDelete
    Replies
    1. The screenshots on this page should help: http://mchr3k.github.com/jdeclipse-realign/

      Delete
  5. Same as Sebastian, it doesn't work (i'm using Groovy/Grails Tool Suite 3.1.0.RELEASE)

    ReplyDelete
    Replies
    1. Let me know if the link I posted in reply to Sebastian helps you.

      Delete
  6. Hello and thanks for your work.
    I installed this plugin on Juno SR1, but at the opening of a .class file i just get the following error message :

    An error has occurred. See error log for more details.
    C:\Dev\softs\eclipse4.2.SR1-juno\4.2.SR1\configuration\org.eclipse.osgi\bundles\882\1\.cp\lib\linux\x86\libjd-eclipse.so: Can't load this .dll (machine code=0x101) on a IA 32-bit platform

    Is this error linked to this plugin ? (i didn't have it before i installed). BTW i'm not on linux, i'm on windows7, so that explain the absence of the .so

    Thanks for your help

    ReplyDelete
    Replies
    1. Any issues with loading the native library (e.g. the dll) need to be taken up with the main JD Eclipse project (http://java.decompiler.free.fr/?q=jdeclipse) which my plugin enhances.

      Delete
  7. Tried to get this plugin going in multiple environments over the years. Never a success. Tried with eclipse 3.4 and more recently 4.3. Always get a similar error, something long the lines of:

    java.lang.UnsatisfiedLinkError: C:\Users\username\Desktop\eclipse-standard-kepler-R-win32-x86_64\eclipse\configuration\org.eclipse.osgi\bundles\252\1\.cp\lib\win32\x86_64\jd-eclipse.dll: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail
    at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary1(Unknown Source)
    at java.lang.ClassLoader.loadLibrary0(Unknown Source)
    at java.lang.ClassLoader.loadLibrary(Unknown Source)
    at java.lang.Runtime.load0(Unknown Source)
    at java.lang.System.load(Unknown Source)
    at jd.ide.eclipse.editors.JDSourceMapper.loadLibrary(JDSourceMapper.java:172)
    at jd.ide.eclipse.editors.JDSourceMapper.findSource(JDSourceMapper.java:107)
    at jd.ide.eclipse.realignment.editors.RealignmentJDSourceMapper.findSource(RealignmentJDSourceMapper.java:220)
    at jd.ide.eclipse.realignment.editors.RealignmentJDSourceMapper.findSource(RealignmentJDSourceMapper.java:187)
    at org.eclipse.jdt.internal.core.SourceMapper.getSourceForRootPath(SourceMapper.java:1047)
    at org.eclipse.jdt.internal.core.SourceMapper.findSource(SourceMapper.java:1008)
    at org.eclipse.jdt.internal.core.SourceMapper.findSource(SourceMapper.java:983)
    at jd.ide.eclipse.realignment.editors.RealignmentJDSourceMapper.findSource(RealignmentJDSourceMapper.java:212)
    at org.eclipse.jdt.internal.core.ClassFile.mapSource(ClassFile.java:637)
    at org.eclipse.jdt.internal.core.ClassFile.openBuffer(ClassFile.java:630)
    at org.eclipse.jdt.internal.core.Openable.getBuffer(Openable.java:288)
    at org.eclipse.jdt.internal.core.ClassFile.getBuffer(ClassFile.java:359)
    at org.eclipse.jdt.internal.core.ClassFile.getSourceRange(ClassFile.java:518)
    at org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor.probeInputForSource(ClassFileEditor.java:763)
    at org.eclipse.jdt.internal.ui.javaeditor.ClassFileEditor.doSetInput(ClassFileEditor.java:662)
    at jd.ide.eclipse.editors.JDClassFileEditor.doSetInput(JDClassFileEditor.java:76)

    Or something like:

    An error has occurred. See error log for more details.
    C:\Users\username\Desktop\eclipse-standard-kepler-R-win32-x86_64\eclipse\configuration\org.eclipse.osgi\bundles\252\1\.cp\lib\win32\x86_64\jd-eclipse.dll: The application has failed to start because its side-by-side configuration is incorrect. Please see the application event log or use the command-line sxstrace.exe tool for more detail

    ReplyDelete
    Replies
    1. wow I *think* I've got it going now. Of course it took a manhunt between yoursite, leading me to http://sourceforge.net/projects/realignmentjd/ leading me to http://sourceforge.net/projects/realignmentjd/files/ leading me to http://java.decompiler.free.fr/ leading to me looking for a mirror of this site, which google led me back to your site, which I then googled a bit more which lead me to http://jd.benow.ca/#jd-eclipse-install which led me to finding out you need to install this: http://www.microsoft.com/en-us/download/details.aspx?id=2092

      Could have just said that literally in 100 places ;)

      Thanks for the hard work on the plugin though. Looks good now its finally working.

      Delete
  8. This comment has been removed by the author.

    ReplyDelete