2013年2月23日土曜日

Java Decompiler が Eclipse Juno で動かない

Scala コンパイラが生成するクラスファイルが、Java としてどうなっているのかを確認したかったので、 Java の逆コンパイラを導入する。

Java の逆コンパイラといえば Jad が有名だが Java 1.5 以降には対応していないなど古くなってきていて、 最近はその名の通り Java Decompiler というのがよく使われているようなのでそちらを採用。 Eclipse 用に JD Eclipse という Plugin もある。

がどうやっても JD Eclipse が動かない。
結局断念して単独の GUI 版を使うことにした。

いつかの再挑戦に備えて今回の敗退の記録を残しておく。



導入

導入は簡単。
Eclipse の 「Install New Software」で、 JD-Eclipse update site の URL 「http://jd.benow.ca/jd-eclipse/update」を指定して、 JD-Eclipse Plug-in をインストール。
Eclipse の再起動を要求されるので再起動。

Plugin 一式をダウロードして配置する方法も用意されているが、 Plugin 本体である「jd.ide.eclipse.win32.x86_64_0.1.3.jar」や「jd.ide.eclipse_0.1.3.jar」も 「Install New Software」時に正しくインストールされたようなので手動配置は不要。

「Preferences > General > Editors > File Associations」で 「Class without sources」 を コーヒーカップアイコンの Java Class Editorに変更。

これで設置は完了。



動作確認

Package Explorer ではクラスファイルが表示されないので、 Navigator View を使って生成されたクラスファイルを表示してみる。

が、普通のクラスファイルビューアーが起動して「Source not found」の表示とともに、 VMコードが表示されてしまう。
Eclipse のログファイルを見ると以下のようなエラーログが出ている。

!ENTRY jd.ide.eclipse 4 0 2013-02-23 02:31:26.140
!MESSAGE bin [in HelloWorld] is not on its project's build path
!STACK 1
Java Model Exception: Java Model Status [bin [in HelloWorld] is not on its project's build path]
 at org.eclipse.jdt.internal.core.JavaElement.newJavaModelException(JavaElement.java:505)
 at org.eclipse.jdt.internal.core.Openable.generateInfos(Openable.java:246)
 at org.eclipse.jdt.internal.core.JavaElement.openWhenClosed(JavaElement.java:518)
 at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:255)
 at org.eclipse.jdt.internal.core.JavaElement.getElementInfo(JavaElement.java:241)
 at org.eclipse.jdt.internal.core.PackageFragmentRoot.getKind(PackageFragmentRoot.java:481)
 at org.eclipse.jdt.internal.core.PackageFragmentRoot.getSourceAttachmentPath(PackageFragmentRoot.java:595)
 at jd.ide.eclipse.editors.JDClassFileEditor.setupSourceMapper(JDClassFileEditor.java:106)
 at jd.ide.eclipse.editors.JDClassFileEditor.doSetInput(JDClassFileEditor.java:41)
 at org.eclipse.ui.texteditor.AbstractTextEditor$19.run(AbstractTextEditor.java:3209)
 at org.eclipse.jface.operation.ModalContext.runInCurrentThread(ModalContext.java:464)
 at org.eclipse.jface.operation.ModalContext.run(ModalContext.java:372)
 at org.eclipse.ui.internal.WorkbenchWindow$13.run(WorkbenchWindow.java:1666)
 at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
 at org.eclipse.ui.internal.WorkbenchWindow.run(WorkbenchWindow.java:1663)
 at org.eclipse.ui.texteditor.AbstractTextEditor.internalInit(AbstractTextEditor.java:3227)
 at org.eclipse.ui.texteditor.AbstractTextEditor.init(AbstractTextEditor.java:3254)
 at org.eclipse.ui.internal.EditorReference.initialize(EditorReference.java:324)
 at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.create(CompatibilityPart.java:288)
 at sun.reflect.GeneratedMethodAccessor43.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
 at java.lang.reflect.Method.invoke(Unknown Source)
 at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56)
 at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:857)
 at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:837)
 at org.eclipse.e4.core.internal.di.InjectorImpl.inject(InjectorImpl.java:111)
 at org.eclipse.e4.core.internal.di.InjectorImpl.internalMake(InjectorImpl.java:318)
 at org.eclipse.e4.core.internal.di.InjectorImpl.make(InjectorImpl.java:240)
 at org.eclipse.e4.core.contexts.ContextInjectionFactory.make(ContextInjectionFactory.java:161)
 at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.createFromBundle(ReflectionContributionFactory.java:102)
 at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.doCreate(ReflectionContributionFactory.java:71)
 at org.eclipse.e4.ui.internal.workbench.ReflectionContributionFactory.create(ReflectionContributionFactory.java:53)
 at org.eclipse.e4.ui.workbench.renderers.swt.ContributedPartRenderer.createWidget(ContributedPartRenderer.java:141)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createWidget(PartRenderingEngine.java:889)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:623)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.safeCreateGui(PartRenderingEngine.java:725)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.access$2(PartRenderingEngine.java:696)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$7.run(PartRenderingEngine.java:690)
 at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.createGui(PartRenderingEngine.java:675)
 at org.eclipse.e4.ui.internal.workbench.PartServiceImpl$1.handleEvent(PartServiceImpl.java:90)
 at org.eclipse.e4.ui.services.internal.events.UIEventHandler$1.run(UIEventHandler.java:41)
 at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:180)
 at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)
 at org.eclipse.swt.widgets.Display.syncExec(Display.java:4687)
 at org.eclipse.e4.ui.internal.workbench.swt.E4Application$1.syncExec(E4Application.java:187)
 at org.eclipse.e4.ui.services.internal.events.UIEventHandler.handleEvent(UIEventHandler.java:38)
 at org.eclipse.equinox.internal.event.EventHandlerWrapper.handleEvent(EventHandlerWrapper.java:197)
 at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:197)
 at org.eclipse.equinox.internal.event.EventHandlerTracker.dispatchEvent(EventHandlerTracker.java:1)
 at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230)
 at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148)
 at org.eclipse.equinox.internal.event.EventAdminImpl.dispatchEvent(EventAdminImpl.java:135)
 at org.eclipse.equinox.internal.event.EventAdminImpl.sendEvent(EventAdminImpl.java:78)
 at org.eclipse.equinox.internal.event.EventComponent.sendEvent(EventComponent.java:39)
 at org.eclipse.e4.ui.services.internal.events.EventBroker.send(EventBroker.java:81)
 at org.eclipse.e4.ui.internal.workbench.UIEventPublisher.notifyChanged(UIEventPublisher.java:57)
 at org.eclipse.emf.common.notify.impl.BasicNotifierImpl.eNotify(BasicNotifierImpl.java:374)
 at org.eclipse.e4.ui.model.application.ui.impl.ElementContainerImpl.setSelectedElement(ElementContainerImpl.java:171)
 at org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.showElementInWindow(ModelServiceImpl.java:418)
 at org.eclipse.e4.ui.internal.workbench.ModelServiceImpl.bringToTop(ModelServiceImpl.java:385)
 at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.delegateBringToTop(PartServiceImpl.java:578)
 at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.bringToTop(PartServiceImpl.java:314)
 at org.eclipse.e4.ui.internal.workbench.PartServiceImpl.showPart(PartServiceImpl.java:962)
 at org.eclipse.ui.internal.WorkbenchPage.busyOpenEditor(WorkbenchPage.java:3071)
 at org.eclipse.ui.internal.WorkbenchPage.access$21(WorkbenchPage.java:2996)
 at org.eclipse.ui.internal.WorkbenchPage$8.run(WorkbenchPage.java:2978)
 at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:70)
 at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2974)
 at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2933)
 at org.eclipse.ui.internal.WorkbenchPage.openEditor(WorkbenchPage.java:2924)
 at org.eclipse.ui.ide.IDE.openEditor(IDE.java:655)
 at org.eclipse.ui.ide.IDE.openEditor(IDE.java:614)
 at org.eclipse.ui.actions.OpenFileAction.openFile(OpenFileAction.java:99)
 at org.eclipse.ui.actions.OpenSystemEditorAction.run(OpenSystemEditorAction.java:99)
 at org.eclipse.ui.views.navigator.OpenActionGroup.runDefaultAction(OpenActionGroup.java:133)
 at org.eclipse.ui.views.navigator.MainActionGroup.runDefaultAction(MainActionGroup.java:330)
 at org.eclipse.ui.views.navigator.ResourceNavigator.handleOpen(ResourceNavigator.java:787)
 at org.eclipse.ui.views.navigator.ResourceNavigator$6.open(ResourceNavigator.java:499)
 at org.eclipse.ui.OpenAndLinkWithEditorHelper$InternalListener.open(OpenAndLinkWithEditorHelper.java:48)
 at org.eclipse.jface.viewers.StructuredViewer$2.run(StructuredViewer.java:866)
 at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
 at org.eclipse.ui.internal.JFaceUtil$1.run(JFaceUtil.java:49)
 at org.eclipse.jface.util.SafeRunnable.run(SafeRunnable.java:175)
 at org.eclipse.jface.viewers.StructuredViewer.fireOpen(StructuredViewer.java:864)
 at org.eclipse.jface.viewers.StructuredViewer.handleOpen(StructuredViewer.java:1152)
 at org.eclipse.jface.viewers.StructuredViewer$6.handleOpen(StructuredViewer.java:1256)
 at org.eclipse.jface.util.OpenStrategy.fireOpenEvent(OpenStrategy.java:275)
 at org.eclipse.jface.util.OpenStrategy.access$2(OpenStrategy.java:269)
 at org.eclipse.jface.util.OpenStrategy$1.handleEvent(OpenStrategy.java:309)
 at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:84)
 at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1053)
 at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4169)
 at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3758)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1022)
 at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
 at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:916)
 at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:86)
 at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:585)
 at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
 at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:540)
 at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
 at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:124)
 at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196)
 at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:110)
 at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:79)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:353)
 at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:180)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
 at java.lang.reflect.Method.invoke(Unknown Source)
 at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:629)
 at org.eclipse.equinox.launcher.Main.basicRun(Main.java:584)
 at org.eclipse.equinox.launcher.Main.run(Main.java:1438)
 at org.eclipse.equinox.launcher.Main.main(Main.java:1414)
!SUBENTRY 1 org.eclipse.jdt.core 4 1006 2013-02-23 02:31:26.171
!MESSAGE bin [in HelloWorld] is not on its project's build path

生成されたクラスファイルを jar にしてパスを通してみたりもしたが結局状況は変わらなかった。



Eclipse realign

JD Plugin は Eclipse JUNO ではうまく動かないことがあるらしい。
なんでもソース付きのクラスファイルとソースなしのクラスファイルが混在した場合、 クラスエディタが切り替えに失敗するらしい。
そのために、JD-Plugin から fork した 「JD-Eclipse Realign」というものがある。

ログを見る限りでは「JDClassFileEditor」が実行されているにもかかわらず、 Model Exception が出ているので 今回は Editor 選択にかかわるものではないと思うが 一応導入してみる。

update site は 「http://mchr3k-eclipse.appspot.com/」。
「Java Decompiler Eclipse Plug-in」 カテゴリの

  • JD Eclipse (Realign Edition) version 1.1.2
  • JD-Eclipse Plug-in version 0.1.3
の2つを選択してインストール&再起動。
ただし、オリジナルの JD-Eclipse が既に設置されている場合は、 「JD-Eclipse Plug-in version 0.1.3」は指定する必要はないし、 指定しても「インストール済みなので無視します」のように表示されてインストールはスキップされる。

実行してみる。
やはり状況は変わらない。ログに出るエラーも同じ。
ログのスタックトレースでは RealignmentJDClassFileEditor が実行されているので、 Editor は選択されているものの Decompile で失敗する模様。



今回はここまで。おとなしく Java Decompiler の 単独 GUI 版を使うことにする。
いつかまた再挑戦しよう。


0 件のコメント:

コメントを投稿