protected String compileUnits( final JRCompilationUnit[] units, String classpath, File tempDirFile) { final StringBuffer problemBuffer = new StringBuffer(); INameEnvironment env = getNameEnvironment(units); final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems(); final Map settings = getJdtSettings(); final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); final ICompilerRequestor requestor = getCompilerRequestor(units, problemBuffer); ICompilationUnit[] compilationUnits = new ICompilationUnit[units.length]; for (int i = 0; i < compilationUnits.length; i++) { compilationUnits[i] = new CompilationUnit(units[i].getSourceCode(), units[i].getName()); } Compiler compiler = new Compiler(env, policy, settings, requestor, problemFactory); compiler.compile(compilationUnits); if (problemBuffer.length() > 0) { return problemBuffer.toString(); } return null; }
protected Class<?> compile(String className, char[] source) { if (source == null) { source = findSource(className); } if (source != null) { if (compiler == null) { compiler = new Compiler( getNameEnvironment(), getErrorHandlingPolicy(), getCompilerOptions(), getCompileRequestor(), getProblemFactory()); } ICompilationUnit[] units = new CompilationUnit[1]; units[0] = new CompilationUnit(source, className, null); compiler.compile(units); if (hasErrors()) { StringBuilder sb = new StringBuilder(); try { writeProblemLog(sb); } catch (IOException e) { db.p(e); } finally { clearProblems(); } throw new CompileException(sb.toString()); } } return getCachedClass(className); }
/** * General API -> compile each of supplied files -> recompile any required types for which we have * an incomplete principle structure */ public void compile(ICompilationUnit[] sourceUnits) { this.stats.startTime = System.currentTimeMillis(); // GROOVY start // sort the sourceUnits - java first! might be temporary, hmmm if (this.options.buildGroovyFiles == 2) { int groovyFileIndex = -1; // System.out.println("before"); // for (int u=0,max=sourceUnits.length;u<max;u++) { // System.out.println(sourceUnits[u].getFileName()); // } for (int u = 0, max = sourceUnits.length; u < max; u++) { char[] fn = sourceUnits[u].getFileName(); boolean isDotJava = fn[fn.length - 1] == 'a'; // a means .java if (isDotJava) { if (groovyFileIndex != -1) { // swap them! ICompilationUnit swap = sourceUnits[groovyFileIndex]; sourceUnits[groovyFileIndex] = sourceUnits[u]; sourceUnits[u] = swap; // find the next .groovy file after the groovyFileIndex (worst case it will be 'u') int newGroovyFileIndex = -1; for (int g = groovyFileIndex; g <= u; g++) { char[] fn2 = sourceUnits[g].getFileName(); boolean isDotGroovy = fn2[fn2.length - 1] == 'm'; // ZALUUM if (isDotGroovy) { newGroovyFileIndex = g; break; } } groovyFileIndex = newGroovyFileIndex; } } else { if (groovyFileIndex == -1) { groovyFileIndex = u; } } } // System.out.println("after"); // for (int u=0,max=sourceUnits.length;u<max;u++) { // System.out.println(sourceUnits[u].getFileName()); // } } // GROOVY end CompilationUnitDeclaration unit = null; ProcessTaskManager processingTask = null; try { // build and record parsed units reportProgress(Messages.compilation_beginningToCompile); if (this.annotationProcessorManager == null) { beginToCompile(sourceUnits); } else { ICompilationUnit[] originalUnits = (ICompilationUnit[]) sourceUnits.clone(); // remember source units in case a source type collision occurs try { beginToCompile(sourceUnits); processAnnotations(); if (!this.options.generateClassFiles) { // -proc:only was set on the command line return; } } catch (SourceTypeCollisionException e) { reset(); // a generated type was referenced before it was created // the compiler either created a MissingType or found a BinaryType for it // so add the processor's generated files & start over, // but remember to only pass the generated files to the annotation processor int originalLength = originalUnits.length; int newProcessedLength = e.newAnnotationProcessorUnits.length; ICompilationUnit[] combinedUnits = new ICompilationUnit[originalLength + newProcessedLength]; System.arraycopy(originalUnits, 0, combinedUnits, 0, originalLength); System.arraycopy( e.newAnnotationProcessorUnits, 0, combinedUnits, originalLength, newProcessedLength); this.annotationProcessorStartIndex = originalLength; compile(combinedUnits); return; } } if (this.useSingleThread) { // process all units (some more could be injected in the loop by the lookup environment) for (int i = 0; i < this.totalUnits; i++) { unit = this.unitsToProcess[i]; reportProgress( Messages.bind(Messages.compilation_processing, new String(unit.getFileName()))); try { if (this.options.verbose) this.out.println( Messages.bind( Messages.compilation_process, new String[] { String.valueOf(i + 1), String.valueOf(this.totalUnits), new String(this.unitsToProcess[i].getFileName()) })); process(unit, i); } finally { // cleanup compilation unit result unit.cleanUp(); } this.unitsToProcess[i] = null; // release reference to processed unit declaration reportWorked(1, i); this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length; long acceptStart = System.currentTimeMillis(); this.requestor.acceptResult(unit.compilationResult.tagAsAccepted()); this.stats.generateTime += System.currentTimeMillis() - acceptStart; // record accept time as part of generation if (this.options.verbose) this.out.println( Messages.bind( Messages.compilation_done, new String[] { String.valueOf(i + 1), String.valueOf(this.totalUnits), new String(unit.getFileName()) })); } } else { processingTask = new ProcessTaskManager(this); int acceptedCount = 0; // process all units (some more could be injected in the loop by the lookup environment) // the processTask can continue to process units until its fixed sized cache is full then it // must wait // for this this thread to accept the units as they appear (it only waits if no units are // available) while (true) { try { unit = processingTask.removeNextUnit(); // waits if no units are in the processed queue } catch (Error e) { unit = processingTask.unitToProcess; throw e; } catch (RuntimeException e) { unit = processingTask.unitToProcess; throw e; } if (unit == null) break; reportWorked(1, acceptedCount++); this.stats.lineCount += unit.compilationResult.lineSeparatorPositions.length; this.requestor.acceptResult(unit.compilationResult.tagAsAccepted()); if (this.options.verbose) this.out.println( Messages.bind( Messages.compilation_done, new String[] { String.valueOf(acceptedCount), String.valueOf(this.totalUnits), new String(unit.getFileName()) })); } } } catch (AbortCompilation e) { this.handleInternalException(e, unit); } catch (Error e) { this.handleInternalException(e, unit, null); throw e; // rethrow } catch (RuntimeException e) { this.handleInternalException(e, unit, null); throw e; // rethrow } finally { if (processingTask != null) { processingTask.shutdown(); processingTask = null; } reset(); this.annotationProcessorStartIndex = 0; this.stats.endTime = System.currentTimeMillis(); } if (this.options.verbose) { if (this.totalUnits > 1) { this.out.println( Messages.bind(Messages.compilation_units, String.valueOf(this.totalUnits))); } else { this.out.println(Messages.bind(Messages.compilation_unit, String.valueOf(this.totalUnits))); } } }
/** Compile the servlet from .java file to .class file */ protected void generateClass(String[] smap) throws FileNotFoundException, JasperException, Exception { long t1 = 0; if (log.isDebugEnabled()) { t1 = System.currentTimeMillis(); } final String sourceFile = ctxt.getServletJavaFileName(); final String outputDir = ctxt.getOptions().getScratchDir().getAbsolutePath(); String packageName = ctxt.getServletPackageName(); final String targetClassName = ((packageName.length() != 0) ? (packageName + ".") : "") + ctxt.getServletClassName(); final ClassLoader classLoader = ctxt.getJspLoader(); String[] fileNames = new String[] {sourceFile}; String[] classNames = new String[] {targetClassName}; final ArrayList problemList = new ArrayList(); class CompilationUnit implements ICompilationUnit { String className; String sourceFile; CompilationUnit(String sourceFile, String className) { this.className = className; this.sourceFile = sourceFile; } public char[] getFileName() { return sourceFile.toCharArray(); } public char[] getContents() { char[] result = null; FileInputStream is = null; try { is = new FileInputStream(sourceFile); Reader reader = new BufferedReader(new InputStreamReader(is, ctxt.getOptions().getJavaEncoding())); if (reader != null) { char[] chars = new char[8192]; StringBuffer buf = new StringBuffer(); int count; while ((count = reader.read(chars, 0, chars.length)) > 0) { buf.append(chars, 0, count); } result = new char[buf.length()]; buf.getChars(0, result.length, result, 0); } } catch (IOException e) { log.error("Compilation error", e); } finally { if (is != null) { try { is.close(); } catch (IOException exc) { // Ignore } } } return result; } public char[] getMainTypeName() { int dot = className.lastIndexOf('.'); if (dot > 0) { return className.substring(dot + 1).toCharArray(); } return className.toCharArray(); } public char[][] getPackageName() { StringTokenizer izer = new StringTokenizer(className, "."); char[][] result = new char[izer.countTokens() - 1][]; for (int i = 0; i < result.length; i++) { String tok = izer.nextToken(); result[i] = tok.toCharArray(); } return result; } public boolean ignoreOptionalProblems() { return false; } } final INameEnvironment env = new INameEnvironment() { public NameEnvironmentAnswer findType(char[][] compoundTypeName) { String result = ""; String sep = ""; for (int i = 0; i < compoundTypeName.length; i++) { result += sep; result += new String(compoundTypeName[i]); sep = "."; } return findType(result); } public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) { String result = ""; String sep = ""; for (int i = 0; i < packageName.length; i++) { result += sep; result += new String(packageName[i]); sep = "."; } result += sep; result += new String(typeName); return findType(result); } private NameEnvironmentAnswer findType(String className) { InputStream is = null; try { if (className.equals(targetClassName)) { ICompilationUnit compilationUnit = new CompilationUnit(sourceFile, className); return new NameEnvironmentAnswer(compilationUnit, null); } String resourceName = className.replace('.', '/') + ".class"; is = classLoader.getResourceAsStream(resourceName); if (is != null) { byte[] classBytes; byte[] buf = new byte[8192]; ByteArrayOutputStream baos = new ByteArrayOutputStream(buf.length); int count; while ((count = is.read(buf, 0, buf.length)) > 0) { baos.write(buf, 0, count); } baos.flush(); classBytes = baos.toByteArray(); char[] fileName = className.toCharArray(); ClassFileReader classFileReader = new ClassFileReader(classBytes, fileName, true); return new NameEnvironmentAnswer(classFileReader, null); } } catch (IOException exc) { log.error("Compilation error", exc); } catch (org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException exc) { log.error("Compilation error", exc); } finally { if (is != null) { try { is.close(); } catch (IOException exc) { // Ignore } } } return null; } private boolean isPackage(String result) { if (result.equals(targetClassName)) { return false; } String resourceName = result.replace('.', '/') + ".class"; InputStream is = classLoader.getResourceAsStream(resourceName); return is == null; } public boolean isPackage(char[][] parentPackageName, char[] packageName) { String result = ""; String sep = ""; if (parentPackageName != null) { for (int i = 0; i < parentPackageName.length; i++) { result += sep; String str = new String(parentPackageName[i]); result += str; sep = "."; } } String str = new String(packageName); if (Character.isUpperCase(str.charAt(0))) { if (!isPackage(result)) { return false; } } result += sep; result += str; return isPackage(result); } public void cleanup() {} }; final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems(); final Map settings = new HashMap(); settings.put(CompilerOptions.OPTION_LineNumberAttribute, CompilerOptions.GENERATE); settings.put(CompilerOptions.OPTION_SourceFileAttribute, CompilerOptions.GENERATE); settings.put(CompilerOptions.OPTION_ReportDeprecation, CompilerOptions.IGNORE); if (ctxt.getOptions().getJavaEncoding() != null) { settings.put(CompilerOptions.OPTION_Encoding, ctxt.getOptions().getJavaEncoding()); } if (ctxt.getOptions().getClassDebugInfo()) { settings.put(CompilerOptions.OPTION_LocalVariableAttribute, CompilerOptions.GENERATE); } // Source JVM if (ctxt.getOptions().getCompilerSourceVM() != null) { String opt = ctxt.getOptions().getCompilerSourceVM(); if (opt.equals("1.1")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_1); } else if (opt.equals("1.2")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_2); } else if (opt.equals("1.3")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3); } else if (opt.equals("1.4")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4); } else if (opt.equals("1.5")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); } else if (opt.equals("1.6")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6); } else if (opt.equals("1.7")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7); } else { log.warn("Unknown source VM " + opt + " ignored."); settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); } } else { // Default to 1.5 settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5); } // Target JVM if (ctxt.getOptions().getCompilerTargetVM() != null) { String opt = ctxt.getOptions().getCompilerTargetVM(); if (opt.equals("1.1")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_1); } else if (opt.equals("1.2")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2); } else if (opt.equals("1.3")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3); } else if (opt.equals("1.4")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4); } else if (opt.equals("1.5")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); } else if (opt.equals("1.6")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6); } else if (opt.equals("1.7")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7); } else { log.warn("Unknown target VM " + opt + " ignored."); settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); } } else { // Default to 1.5 settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5); } final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); final ICompilerRequestor requestor = new ICompilerRequestor() { public void acceptResult(CompilationResult result) { try { if (result.hasProblems()) { IProblem[] problems = result.getProblems(); for (int i = 0; i < problems.length; i++) { IProblem problem = problems[i]; if (problem.isError()) { String name = new String(problems[i].getOriginatingFileName()); try { problemList.add( ErrorDispatcher.createJavacError( name, pageNodes, new StringBuffer(problem.getMessage()), problem.getSourceLineNumber(), ctxt)); } catch (JasperException e) { log.error("Error visiting node", e); } } } } if (problemList.isEmpty()) { ClassFile[] classFiles = result.getClassFiles(); for (int i = 0; i < classFiles.length; i++) { ClassFile classFile = classFiles[i]; char[][] compoundName = classFile.getCompoundName(); String className = ""; String sep = ""; for (int j = 0; j < compoundName.length; j++) { className += sep; className += new String(compoundName[j]); sep = "."; } byte[] bytes = classFile.getBytes(); String outFile = outputDir + "/" + className.replace('.', '/') + ".class"; FileOutputStream fout = new FileOutputStream(outFile); BufferedOutputStream bos = new BufferedOutputStream(fout); bos.write(bytes); bos.close(); } } } catch (IOException exc) { log.error("Compilation error", exc); } } }; ICompilationUnit[] compilationUnits = new ICompilationUnit[classNames.length]; for (int i = 0; i < compilationUnits.length; i++) { String className = classNames[i]; compilationUnits[i] = new CompilationUnit(fileNames[i], className); } Compiler compiler = new Compiler(env, policy, settings, requestor, problemFactory, true); compiler.compile(compilationUnits); if (!ctxt.keepGenerated()) { File javaFile = new File(ctxt.getServletJavaFileName()); javaFile.delete(); } if (!problemList.isEmpty()) { JavacErrorDetail[] jeds = (JavacErrorDetail[]) problemList.toArray(new JavacErrorDetail[0]); errDispatcher.javacError(jeds); } if (log.isDebugEnabled()) { long t2 = System.currentTimeMillis(); log.debug("Compiled " + ctxt.getServletJavaFileName() + " " + (t2 - t1) + "ms"); } if (ctxt.isPrototypeMode()) { return; } // JSR45 Support if (!options.isSmapSuppressed()) { SmapUtil.installSmap(smap); } }