0

I'm trying to write a program in which people can upload their src code for a Othello IA and play against each other. So I get the a jar file with .java src code which I want to compile and upload to my database.

I've been using javax.tools.JavaCompiler but it doesn't seem to work with when they use multiple packages.

Here is an example of my code:

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

If my toTest.jar file contains packages instead of all .java files directly this doesn't compile.

I've looked at Java programmatically compile jar How to set classpath when I use javax.tools.JavaCompiler compile the source? and the examples from here: http://www.programcreek.com/java-api-examples/index.php?api=javax.tools.JavaCompiler

but I can't seem to find the solution..

Alternatively it would be nice if this could be done without unpacking and saving the jar file but directly with a bite stream from the database where I've saved the file.

I'm pretty new to programming so I apologize for my ugly code. I'd be grateful for any help or indication!

EDIT:

From what I've seen javac thinks I'm in the wrong directory and can't find the main class when compiling. Thus I need to set my classpath variable to the file I'm currently working on. However, in all the ways I've tried to do that he can't even find the .java file anymore.

Community
  • 1
  • 1
Val.M
  • 37
  • 1
  • 11
  • Do you want to handle ANY Java code someone might upload, with ANY external dependencies? Consider that managing dependencies like this requires something of the complexity level of the entire Maven architecture. Is this what you are trying to achieve? You're much better off requiring your clients to provide you a complete standalone jar file with all dependencies included. – Jim Garrison Jun 21 '16 at 16:00
  • Suggestion: Try walking before you run. See if you can save the files in the jar to the file system and use ProcessBuilder or Runtime.exec to run javac and compile them – ControlAltDel Jun 21 '16 at 16:01

0 Answers0