0

我正在尝试编写一个程序,人们可以在其中上传他们的 Othello IA 的 src 代码并相互对战。所以我得到了一个带有 .java src 代码的 jar 文件,我想编译并上传到我的数据库。

我一直在使用 javax.tools.JavaCompiler 但是当他们使用多个包时它似乎不起作用。

这是我的代码示例:

public static void main(String args[]) throws IOException {
    File file = new File("toTest.jar");
    tester tester = new tester();
    tester.compile(file);
}

public void entpack(File srcJarFile, String destdir) throws IOException {
    JarFile jarfile = new JarFile(srcJarFile); // jar file path
    Enumeration<JarEntry> enu = jarfile.entries();
    // extract
    while (enu.hasMoreElements()) {
        JarEntry je = enu.nextElement();

        String name = je.getName().trim();
        // System.out.println(name);

        File fl = new File(destdir, name);
        if (!fl.exists()) {
            fl.getParentFile().mkdirs();
            fl = new java.io.File(destdir, name);
        }
        if (je.isDirectory()) {
            continue;
        }
        java.io.InputStream is = jarfile.getInputStream(je);
        java.io.FileOutputStream fo = new java.io.FileOutputStream(fl);
        while (is.available() > 0) {
            fo.write(is.read());
        }
        fo.close();
        is.close();
    }
    jarfile.close();
}

public void compile(File srcJarFile) throws IOException {
    String destdir = "compiled";
    entpack(srcJarFile, destdir);

    File file = new File(destdir);

    File[] subDir = file.listFiles();
    ArrayList<String> toCompile = new ArrayList<String>();
    toCompile = showFiles(subDir, destdir, toCompile);

    List<File> files = new ArrayList<File>();
    for (int i = 0; i < toCompile.size(); i++) {
        files.add(new File(toCompile.get(i)));
    }


    // approach wih compiler.getTask and set options
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

    DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
    try { //
        List<File> allFiles = getAllFiles(file, ".java"); //
        System.out.println(allFiles.get(1).getName());
        Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(files);
        ArrayList<String> options = new ArrayList<>();
        options.add("-classpath");
        options.add("/home/m/marotlassauzaa/workspace/tester/compiled"); //
        options.add("-d");
        options.add(file.getPath());
        JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, options, null,
                compilationUnits);
        //System.out.println(task.call());

        if (!task.call()) {
            System.out.println("failed");
        }
    } finally {
        fileManager.close();
    }

}



private List<File> getAllFiles(File dir, String extension) {
    ArrayList<File> fileList = new ArrayList<>();
    getAllFiles(dir, extension, fileList);
    return fileList;
}

private void getAllFiles(File dir, String extension, List<File> fileList) {
    for (File f : dir.listFiles()) {
        if (f.getName().endsWith(extension)) {
            fileList.add(f);
        }
        if (f.isDirectory()) {
            getAllFiles(f, extension, fileList);
        }
    }
}

// returns ArrayList with names of .java files which have to be compiled (mostly needed for later use)
public ArrayList<String> showFiles(File[] files, String directory, ArrayList<String> toCompile) {
    for (File file : files) {
        if (file.isDirectory()) {

            showFiles(file.listFiles(), directory + "/" + file.getName(), toCompile);
        } else {
            String name = directory + "/" + file.getName();
            if (name.endsWith(".java")) {
                toCompile.add(name);
            }
        }
    }
    return toCompile;
}

如果我的 toTest.jar 文件直接包含包而不是所有 .java 文件,则不会编译。

我看过 Java programmatically compile jar How to set classpath when I use javax.tools.JavaCompiler compile source? 以及此处的示例:http: //www.programcreek.com/java-api-examples/index.php?api=javax.tools.JavaCompiler

但我似乎找不到解决方案..

或者,如果可以在不解包和保存 jar 文件的情况下直接使用我保存文件的数据库中的比特流来完成此操作,那就太好了。

我对编程很陌生,所以我为我丑陋的代码道歉。我将不胜感激任何帮助或指示!

编辑:

从我所看到的 javac 认为我在错误的目录中并且在编译时找不到主类。因此,我需要将我的类路径变量设置为我当前正在处理的文件。但是,在我尝试过的所有方法中,他甚至都找不到 .java 文件了。

4

0 回答 0