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.