private void wrapCompilationFailure(ScriptSource source, MultipleCompilationErrorsException e) { // Fix the source file name displayed in the error messages for (Object message : e.getErrorCollector().getErrors()) { if (message instanceof SyntaxErrorMessage) { try { SyntaxErrorMessage syntaxErrorMessage = (SyntaxErrorMessage) message; Field sourceField = SyntaxErrorMessage.class.getDeclaredField("source"); sourceField.setAccessible(true); SourceUnit sourceUnit = (SourceUnit) sourceField.get(syntaxErrorMessage); Field nameField = SourceUnit.class.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(sourceUnit, source.getDisplayName()); } catch (Exception failure) { throw UncheckedException.throwAsUncheckedException(failure); } } } SyntaxException syntaxError = e.getErrorCollector().getSyntaxError(0); Integer lineNumber = syntaxError == null ? null : syntaxError.getLine(); throw new ScriptCompilationException( String.format("Could not compile %s.", source.getDisplayName()), e, source, lineNumber); }
public void compile() { if (compiledTemplate == null) { try { long start = System.currentTimeMillis(); TClassLoader tClassLoader = new TClassLoader(); // Let's compile the groovy source final List<GroovyClass> groovyClassesForThisTemplate = new ArrayList<GroovyClass>(); // ~~~ Please ! CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); compilerConfiguration.setSourceEncoding("utf-8"); // ouf CompilationUnit compilationUnit = new CompilationUnit(compilerConfiguration); compilationUnit.addSource(new SourceUnit(name, compiledSource, compilerConfiguration, tClassLoader, compilationUnit.getErrorCollector())); Field phasesF = compilationUnit.getClass().getDeclaredField("phaseOperations"); phasesF.setAccessible(true); LinkedList[] phases = (LinkedList[]) phasesF.get(compilationUnit); LinkedList<GroovyClassOperation> output = new LinkedList<GroovyClassOperation>(); phases[Phases.OUTPUT] = output; output.add(new GroovyClassOperation() { public void call(GroovyClass gclass) { groovyClassesForThisTemplate.add(gclass); } }); compilationUnit.compile(); // ouf // Define script classes StringBuilder sb = new StringBuilder(); sb.append("LINESMATRIX" + "\n"); sb.append(Codec.encodeBASE64(Java.serialize(linesMatrix)).replaceAll("\\s", "")); sb.append("\n"); sb.append("DOBODYLINES" + "\n"); sb.append(Codec.encodeBASE64(Java.serialize(doBodyLines)).replaceAll("\\s", "")); sb.append("\n"); for (GroovyClass gclass : groovyClassesForThisTemplate) { tClassLoader.defineTemplate(gclass.getName(), gclass.getBytes()); sb.append(gclass.getName() + "\n"); sb.append(Codec.encodeBASE64(gclass.getBytes()).replaceAll("\\s", "")); sb.append("\n"); } // Cache BytecodeCache.cacheBytecode(sb.toString().getBytes("utf-8"), name, source); compiledTemplate = tClassLoader.loadClass(groovyClassesForThisTemplate.get(0).getName()); if (System.getProperty("precompile") != null) { try { // emit bytecode to standard class layout as well File f = Play.getFile("precompiled/templates/" + name.replaceAll("\\{(.*)\\}", "from_$1").replace(":", "_").replace("..", "parent")); f.getParentFile().mkdirs(); FileOutputStream fos = new FileOutputStream(f); fos.write(sb.toString().getBytes("utf-8")); fos.close(); } catch (Exception e) { e.printStackTrace(); } } Logger.trace("%sms to compile template %s to %d classes", System.currentTimeMillis() - start, name, groovyClassesForThisTemplate.size()); } catch (MultipleCompilationErrorsException e) { if (e.getErrorCollector().getLastError() != null) { SyntaxErrorMessage errorMessage = (SyntaxErrorMessage) e.getErrorCollector().getLastError(); SyntaxException syntaxException = errorMessage.getCause(); Integer line = this.linesMatrix.get(syntaxException.getLine()); if (line == null) { line = 0; } String message = syntaxException.getMessage(); if (message.indexOf("@") > 0) { message = message.substring(0, message.lastIndexOf("@")); } throw new TemplateCompilationException(this, line, message); } throw new UnexpectedException(e); } catch (Exception e) { throw new UnexpectedException(e); } } compiledTemplateName = compiledTemplate.getName(); }