是否有可能有一个程序从另一个程序(.java文件)运行代码并自动调试每一行

时间:2014-10-27 19:15:03

标签: java multithreading debugging

例如,假设我想要一个通用程序创建一个线程来运行来自JFileChooser中指定的.java文件的代码,并逐行或直到特定行运行它,并从调试器打印每个更改,或至少像一个函数(IE打印数据结构和变量内部的值)。

在写出来的时候,这听起来像普通的IDE或者我自己运行和调试它可以得到的东西,但是我想说我想要一种更简单的调试方法,而不是自己完成每个步骤并查看调试器,向下滚动,展开我要检查的值,然后再向下滚动等。大多数时候我调试时,我得到了很多我不太关心的信息,所以我想限制为只所有变量中的值,而不是它的属性等。

这似乎是一个相当大的项目,或者它可能不是,而且实际上很简单。无论哪种方式,我想创建一个...... 1。 有一个运行代码指定.java文件的线程

2。 在第一个线程中打印值更改的线程(为了使它更容易,我可以只有一个GUI并让它更新每个值和步骤.IE(String [] names => [],[" Joe Shmoe& #34;],[" Joe Shmoe"," Kyle Stanly"],[]等。)

3。 能够逐行读取,或者至少记录发生的持续变化,以便我可以回过头看看它。

4。 抛出任何要查看的错误,例如,包含堆栈跟踪的另一个文本框。

我想知道这是否可行,如果可以,从哪里开始。如果我设法做到了,它会帮助我调试我以后尝试的任何项目。

1 个答案:

答案 0 :(得分:4)

您无法调试.java文件。但是,您可以做的是编译这些文件并输出自定义诊断信息!诊断基本上是编译时得到的调试器输出。您的所有诊断信息都将存储在DiagnosticsCollector中,您甚至可以自己实施(但您不必这样做)。

您想要了解的是JavaCompiler实用程序。 javadocs很好地解释了事情,我认为,但是如果你发现它们乏善可陈(就像我在白天做的那样)你可以谷歌任何你不理解的东西。那里有很多例子和教程。

这就是我在我个人项目中所拥有的:

public boolean compile() {
    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();

    try {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        try (StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null)) {

            Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(classFiles);
            compiler.getTask(null, fileManager, diagnostics, compileOptions, null, compilationUnits).call();
        }
    } catch (IOException ex) {
        System.err.println("Compilation failed: " + ex.getMessage());
        return false;
    }

    System.out.println("Compilation finished.");

    // returns false if the diagnostics contain errors, and true if there are no
    // diagnostics or if all the diagnostics are warnings.
    return successfullCompilation(diagnostics.getDiagnostics());
}

它不会编译下架,但它应该会给你一个很好的推动。

以下是您可以使用诊断程序执行操作的示例:

private boolean successfullCompilation(List<Diagnostic<? extends JavaFileObject>> diagnostics) {
    if (!diagnostics.isEmpty()) {
        boolean errors = false;
        try (PrintWriter writer = new PrintWriter("compiler.log", "UTF-8")) {
            for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics) {
                if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
                    errors = true;
                }

                writer.println("Code: " + diagnostic.getCode());
                writer.println("Type: " + diagnostic.getKind());
                writer.println("  Source: " + diagnostic.getSource());
                writer.println("  Message: " + diagnostic.getMessage(null));
                writer.println("    At row: " + diagnostic.getPosition());
                writer.println();
            }
        } catch (FileNotFoundException | UnsupportedEncodingException ex) {
            System.out.println("Could not write compile log: " + ex.getMessage());
        }

        if (errors) {
            System.err.println("The compiler finished with errors.");
            return false;
        }

        System.err.println("The compiler finished with warnings.");
    }

    return true;
}