2012-04-03 80 views
3

我想知道如何獲取給定行號的Java源文件中的周邊方法。我在下面的鏈接找到了解決辦法在這裏計算器:從類插件項目解析Java源代碼問題

How to get surrounding method in Java source file for a given line number

我的這個解決方案的問題是,我正在開發一個插件項目。當我嘗試使用該解決方案我收到以下錯誤異常:

java.lang.ClassCastException: com.sun.tools.javac.api.JavacTaskImpl cannot be cast to com.sun.source.util.JavacTask 
    at xxx.xxx.xxx.xxx.views.versionsCompare.VersionsCompareView.widgetSelected(VersionsCompareView.java:330) 
    at org.eclipse.swt.widgets.TypedListener.handleEvent(TypedListener.java:234) 
    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:4066) 
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3657) 
    at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2640) 
    at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2604) 
    at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438) 
    at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671) 
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) 
    at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664) 
    at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149) 
    at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:115) 
    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:369) 
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:179) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:620) 
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:575) 
    at org.eclipse.equinox.launcher.Main.run(Main.java:1408) 
    at org.eclipse.equinox.launcher.Main.main(Main.java:1384) 

我的代碼是:

import javax.tools.DiagnosticCollector; 
import javax.tools.JavaCompiler; 
import javax.tools.JavaCompiler.CompilationTask; 
import javax.tools.JavaFileObject; 
import javax.tools.StandardJavaFileManager; 
import javax.tools.ToolProvider; 

import com.sun.source.tree.CompilationUnitTree; 
import com.sun.source.tree.LineMap; 
import com.sun.source.tree.MethodTree; 
import com.sun.source.util.JavacTask; 
import com.sun.source.util.SourcePositions; 
import com.sun.source.util.TreeScanner; 
import com.sun.source.util.Trees; 

public class Principal { 

    public static void main(String[] args) { 
    try { 
     JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 
     DiagnosticCollector<JavaFileObject> diagnosticsCollector = new DiagnosticCollector<JavaFileObject>(); 
     StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnosticsCollector, null, null); 
     Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects("C:\\Users\\Alejandro\\Desktop\\comparar\\pkg\\clase.java"); 
     CompilationTask task = compiler.getTask(null, fileManager, diagnosticsCollector, null, null, fileObjects); 

     //Here we switch to Sun-specific APIs 
     JavacTask javacTask = (JavacTask) task; 
     SourcePositions sourcePositions = Trees.instance(javacTask).getSourcePositions(); 
     Iterable<? extends CompilationUnitTree> parseResult = javacTask.parse(); 

     for (CompilationUnitTree compilationUnitTree : parseResult) { 
      compilationUnitTree.accept(new MethodLineLogger(compilationUnitTree, sourcePositions), null); 
     } 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

/* Class for visit methods */ 
private static class MethodLineLogger extends TreeScanner<Void, Void> { 
    private final CompilationUnitTree compilationUnitTree; 
    private final SourcePositions sourcePositions; 
    private final LineMap lineMap; 

    private MethodLineLogger(CompilationUnitTree compilationUnitTree, SourcePositions sourcePositions) { 
      this.compilationUnitTree = compilationUnitTree; 
      this.sourcePositions = sourcePositions; 
      this.lineMap = compilationUnitTree.getLineMap(); 
    } 

    @Override 
    public Void visitMethod(MethodTree arg0, Void arg1) { 
      long startPosition = sourcePositions.getStartPosition(compilationUnitTree, arg0); 
      long startLine = lineMap.getLineNumber(startPosition); 
      long endPosition = sourcePositions.getEndPosition(compilationUnitTree, arg0); 
      long endLine = lineMap.getLineNumber(endPosition); 

      System.out.println("Found method " + arg0.getName() + " from line " + startLine + " to line " + endLine + "."); 

      return super.visitMethod(arg0, arg1); 
    } 
} 

}

瀏覽互聯網,我認爲這個問題是由以下事實引起的在一個插件項目中有不止一個類加載器,並且不能施放此:

JavacTask javacTask = (JavacTask) task;

我已經嘗試了一切,我沒有更多的想法,有沒有人可以給我任何幫助?

預先感謝您。

回答

0

我面臨着完全相同的問題,但不是作爲一個插件,而是作爲一個螞蟻的任務。你是對的 - 這是一個類加載器的問題。 對我來說有效的是在ant中使用'fork'屬性。所以你的解決方案將是類似的 - 打開一個外部過程。呸!