/** perform the actual compilation */ private CompileResult compileJobs() { ArrayList<String> args = new ArrayList<String>(); StringTokenizer tokenizer = new StringTokenizer(this.compilerArgumentsToUse); while (tokenizer.hasMoreTokens()) { args.add(tokenizer.nextToken()); } Iterator<CompilationJob> job_it = this.jobs.iterator(); this.handler.startAction("Compilation", this.jobs.size()); // check whether compiler is valid (but only if there are jobs) if (job_it.hasNext()) { CompilationJob first_job = this.jobs.get(0); CompileResult check_result = first_job.checkCompiler(this.compilerToUse, args); if (!check_result.isContinue()) { return check_result; } } int job_no = 0; while (job_it.hasNext()) { CompilationJob job = job_it.next(); this.handler.nextStep(job.getName(), job.getSize(), job_no++); CompileResult job_result = job.perform(this.compilerToUse, args); if (!job_result.isContinue()) { return job_result; } } Debug.trace("compilation finished."); return new CompileResult(); }
/** * Check whether the given compiler works. * * <p>This performs two steps: * * <ol> * <li>check whether we can successfully call "compiler -help" * <li>check whether we can successfully call "compiler -help arguments" (not all compilers * return an error here) * </ol> * * <p>On failure, the method CompileHandler#errorCompile is called with a descriptive error * message. * * @param compiler the compiler to use * @param arguments additional arguments to pass to the compiler * @return false on error */ public CompileResult checkCompiler(String compiler, ArrayList<String> arguments) { // don't do further checks for eclipse compiler - it would exit if (compiler.equalsIgnoreCase(ECLIPSE_COMPILER_NAME)) { return new CompileResult(); } int retval = 0; FileExecutor executor = new FileExecutor(); String[] output = new String[2]; Debug.trace("checking whether \"" + compiler + " -help\" works"); { List<String> args = new ArrayList<String>(); args.add(compiler); args.add("-help"); retval = runCompiler(executor, output, args); if (retval != 0) { CompileResult result = new CompileResult( this.langpack.getString("CompilePanel.error.compilernotfound"), args, output[0], output[1]); this.listener.handleCompileError(result); if (!result.isContinue()) { return result; } } } Debug.trace("checking whether \"" + compiler + " -help +arguments\" works"); // used to collect the arguments for executing the compiler LinkedList<String> args = new LinkedList<String>(arguments); // add -help argument to prevent the compiler from doing anything args.add(0, "-help"); // add compiler in front of arguments args.add(0, compiler); // construct classpath argument for compiler // - collect all classpaths StringBuffer classpath_sb = new StringBuffer(); for (String cp : this.classpath) { if (classpath_sb.length() > 0) { classpath_sb.append(File.pathSeparatorChar); } classpath_sb.append(new File(cp).getAbsolutePath()); } String classpath_str = classpath_sb.toString(); // - add classpath argument to command line if (classpath_str.length() > 0) { args.add("-classpath"); args.add(classpath_str); } retval = runCompiler(executor, output, args); if (retval != 0) { CompileResult result = new CompileResult( this.langpack.getString("CompilePanel.error.invalidarguments"), args, output[0], output[1]); this.listener.handleCompileError(result); if (!result.isContinue()) { return result; } } return new CompileResult(); }
/** * Perform this job - start compilation. * * @param compiler The compiler to use. * @param arguments The compiler arguments to use. * @return The result. */ public CompileResult perform(String compiler, ArrayList<String> arguments) { Debug.trace("starting job " + this.name); // we have some maximum command line length - need to count int cmdline_len = 0; // used to collect the arguments for executing the compiler LinkedList<String> args = new LinkedList<String>(arguments); { for (String arg : args) { cmdline_len += (arg).length() + 1; } } boolean isEclipseCompiler = compiler.equalsIgnoreCase(ECLIPSE_COMPILER_NAME); // add compiler in front of arguments args.add(0, compiler); cmdline_len += compiler.length() + 1; // construct classpath argument for compiler // - collect all classpaths StringBuffer classpath_sb = new StringBuffer(); for (String cp : this.classpath) { if (classpath_sb.length() > 0) { classpath_sb.append(File.pathSeparatorChar); } classpath_sb.append(new File(cp).getAbsolutePath()); } String classpath_str = classpath_sb.toString(); // - add classpath argument to command line if (classpath_str.length() > 0) { args.add("-classpath"); cmdline_len += 11; args.add(classpath_str); cmdline_len += classpath_str.length() + 1; } // remember how many arguments we have which don't change for the // job int common_args_no = args.size(); // remember how long the common command line is int common_args_len = cmdline_len; // used for execution FileExecutor executor = new FileExecutor(); String output[] = new String[2]; // used for displaying the progress bar String jobfiles = ""; int fileno = 0; int last_fileno = 0; // now iterate over all files of this job for (File file : this.files) { String fpath = file.getAbsolutePath(); Debug.trace("processing " + fpath); // we add the file _first_ to the arguments to have a better // chance to get something done if the command line is almost // MAX_CMDLINE_SIZE or even above fileno++; jobfiles += file.getName() + " "; args.add(fpath); cmdline_len += fpath.length(); // start compilation if maximum command line length reached if (!isEclipseCompiler && cmdline_len >= MAX_CMDLINE_SIZE) { Debug.trace("compiling " + jobfiles); // display useful progress bar (avoid showing 100% while // still compiling a lot) this.listener.progress(last_fileno, jobfiles); last_fileno = fileno; int retval = runCompiler(executor, output, args); // update progress bar: compilation of fileno files done this.listener.progress(fileno, jobfiles); if (retval != 0) { CompileResult result = new CompileResult( this.langpack.getString("CompilePanel.error"), args, output[0], output[1]); this.listener.handleCompileError(result); if (!result.isContinue()) { return result; } } else { // verify that all files have been compiled successfully // I found that sometimes, no error code is returned // although compilation failed. Iterator<String> arg_it = args.listIterator(common_args_no); while (arg_it.hasNext()) { File java_file = new File(arg_it.next()); String basename = java_file.getName(); int dotpos = basename.lastIndexOf('.'); basename = basename.substring(0, dotpos) + ".class"; File class_file = new File(java_file.getParentFile(), basename); if (!class_file.exists()) { CompileResult result = new CompileResult( this.langpack.getString("CompilePanel.error.noclassfile") + java_file.getAbsolutePath(), args, output[0], output[1]); this.listener.handleCompileError(result); if (!result.isContinue()) { return result; } // don't continue any further break; } } } // clean command line: remove files we just compiled for (int i = args.size() - 1; i >= common_args_no; i--) { args.removeLast(); } cmdline_len = common_args_len; jobfiles = ""; } } if (cmdline_len > common_args_len) { this.listener.progress(last_fileno, jobfiles); int retval = runCompiler(executor, output, args); if (!isEclipseCompiler) { this.listener.progress(fileno, jobfiles); } if (retval != 0) { CompileResult result = new CompileResult( this.langpack.getString("CompilePanel.error"), args, output[0], output[1]); this.listener.handleCompileError(result); if (!result.isContinue()) { return result; } } else { // verify that all files have been compiled successfully // I found that sometimes, no error code is returned // although compilation failed. Iterator<String> arg_it = args.listIterator(common_args_no); while (arg_it.hasNext()) { File java_file = new File(arg_it.next()); String basename = java_file.getName(); int dotpos = basename.lastIndexOf('.'); basename = basename.substring(0, dotpos) + ".class"; File class_file = new File(java_file.getParentFile(), basename); if (!class_file.exists()) { CompileResult result = new CompileResult( this.langpack.getString("CompilePanel.error.noclassfile") + java_file.getAbsolutePath(), args, output[0], output[1]); this.listener.handleCompileError(result); if (!result.isContinue()) { return result; } // don't continue any further break; } } } } Debug.trace("job " + this.name + " done (" + fileno + " files compiled)"); return new CompileResult(); }