【问题标题】:Issue with class-cast parsing Java source-code from a plugin project从插件项目解析 Java 源代码的类转换问题
【发布时间】:2012-04-17 09:00:08
【问题描述】:

我想知道如何获取 Java 源文件中给定行号的周围方法。我在stackoverflow的以下链接中找到了一个解决方案:

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);
    }
}

}

浏览互联网我认为问题是由于在一个插件项目中有多个 ClassLoader 并且无法转换:

JavacTask javacTask = (JavacTask) task;

我已经尝试了所有方法,但我没有更多的想法,有人可以帮我吗?

提前谢谢你。

【问题讨论】:

    标签: java parsing casting eclipse-plugin classloader


    【解决方案1】:

    我面临着完全相同的问题,但不是作为插件,而是作为蚂蚁任务。你是对的 - 这是一个类加载器问题。 对我有用的是在 ant 中使用“fork”属性。所以你的解决方案会是类似的——打开一个外部进程。呸!

    【讨论】:

      猜你喜欢
      • 2019-08-06
      • 1970-01-01
      • 1970-01-01
      • 2011-07-26
      • 1970-01-01
      • 2011-09-27
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多