/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/ package org.apache.jasper.compiler;
/** * JDT class compiler. This compiler will load source dependencies from the * context classloader, reducing dramatically disk access during * the compilation process. * * Based on code from Cocoon2. * * @author Remy Maucherat
*/ publicclass JDTCompiler extends org.apache.jasper.compiler.Compiler {
privatefinal Log log = LogFactory.getLog(JDTCompiler.class); // must not be static
/** * Compile the servlet from .java file to .class file
*/
@Override protectedvoid generateClass(Map<String,SmapStratum> smaps) 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 List<JavacErrorDetail> problemList = new ArrayList<>();
class CompilationUnit implements ICompilationUnit {
final INameEnvironment env = new INameEnvironment() {
@Override public NameEnvironmentAnswer findType(char[][] compoundTypeName) {
StringBuilder result = new StringBuilder(); for (int i = 0; i < compoundTypeName.length; i++) { if (i > 0) {
result.append('.');
}
result.append(compoundTypeName[i]);
} return findType(result.toString());
}
@Override public NameEnvironmentAnswer findType(char[] typeName, char[][] packageName) {
StringBuilder result = new StringBuilder(); int i=0; for (; i < packageName.length; i++) { if (i > 0) {
result.append('.');
}
result.append(packageName[i]);
} if (i > 0) {
result.append('.');
}
result.append(typeName); return findType(result.toString());
}
privateboolean isPackage(String result) { if (result.equals(targetClassName) || result.startsWith(targetClassName + '$')) { returnfalse;
}
String resourceName = result.replace('.', '/') + ".class"; try (InputStream is =
classLoader.getResourceAsStream(resourceName)) { return is == null;
} catch (IOException e) { // we are here, since close on is failed. That means it was not null returnfalse;
}
}
@Override publicboolean isPackage(char[][] parentPackageName, char[] packageName) {
StringBuilder result = new StringBuilder(); int i = 0; if (parentPackageName != null) { for (; i < parentPackageName.length; i++) { if (i > 0) {
result.append('.');
}
result.append(parentPackageName[i]);
}
}
if (Character.isUpperCase(packageName[0])) { if (!isPackage(result.toString())) { returnfalse;
}
} if (i > 0) {
result.append('.');
}
result.append(packageName);
return isPackage(result.toString());
}
@Override publicvoid cleanup() {
}
};
final IErrorHandlingPolicy policy = DefaultErrorHandlingPolicies.proceedWithAllProblems();
final Map<String,String> 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);
} elseif(opt.equals("1.2")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_2);
} elseif(opt.equals("1.3")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_3);
} elseif(opt.equals("1.4")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_4);
} elseif(opt.equals("1.5")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_5);
} elseif(opt.equals("1.6")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_6);
} elseif(opt.equals("1.7")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_7);
} elseif(opt.equals("1.8")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_1_8); // Version format changed from Java 9 onwards. // Support old format that was used in EA implementation as well
} elseif(opt.equals("9") || opt.equals("1.9")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9);
} elseif(opt.equals("10")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10);
} elseif(opt.equals("11")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
} elseif(opt.equals("12")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12);
} elseif(opt.equals("13")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13);
} elseif(opt.equals("14")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_14);
} elseif(opt.equals("15")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15);
} elseif(opt.equals("16")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_16);
} elseif(opt.equals("17")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_17);
} elseif(opt.equals("18")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_18);
} elseif (opt.equals("19")) {
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_19);
} elseif (opt.equals("20")) { // Constant not available in latest ECJ version shipped with // Tomcat. May be supported in a snapshot build. // This is checked against the actual version below.
settings.put(CompilerOptions.OPTION_Source, "20");
} elseif (opt.equals("21")) { // Constant not available in latest ECJ version shipped with // Tomcat. May be supported in a snapshot build. // This is checked against the actual version below.
settings.put(CompilerOptions.OPTION_Source, "21");
} else {
log.warn(Localizer.getMessage("jsp.warning.unknown.sourceVM", opt));
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
}
} else { // Default to 11
settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11);
}
// 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);
} elseif(opt.equals("1.2")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_2);
} elseif(opt.equals("1.3")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_3);
} elseif(opt.equals("1.4")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_4);
} elseif(opt.equals("1.5")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_5);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_5);
} elseif(opt.equals("1.6")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_6);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_6);
} elseif(opt.equals("1.7")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_7);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_7);
} elseif(opt.equals("1.8")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_1_8);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_1_8); // Version format changed from Java 9 onwards. // Support old format that was used in EA implementation as well
} elseif(opt.equals("9") || opt.equals("1.9")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9);
} elseif(opt.equals("10")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10);
} elseif(opt.equals("11")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
} elseif(opt.equals("12")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12);
} elseif(opt.equals("13")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13);
} elseif(opt.equals("14")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_14);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_14);
} elseif(opt.equals("15")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15);
} elseif(opt.equals("16")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_16);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_16);
} elseif(opt.equals("17")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_17);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_17);
} elseif(opt.equals("18")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_18);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_18);
} elseif (opt.equals("19")) {
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_19);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_19);
} elseif (opt.equals("20")) { // Constant not available in latest ECJ version shipped with // Tomcat. May be supported in a snapshot build. // This is checked against the actual version below.
settings.put(CompilerOptions.OPTION_TargetPlatform, "20");
settings.put(CompilerOptions.OPTION_Compliance, "20");
} elseif (opt.equals("21")) { // Constant not available in latest ECJ version shipped with // Tomcat. May be supported in a snapshot build. // This is checked against the actual version below.
settings.put(CompilerOptions.OPTION_TargetPlatform, "21");
settings.put(CompilerOptions.OPTION_Compliance, "21");
} else {
log.warn(Localizer.getMessage("jsp.warning.unknown.targetVM", opt));
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
}
} else { // Default to 11
settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11);
settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11);
}
final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault());
final ICompilerRequestor requestor = new ICompilerRequestor() {
@Override publicvoid acceptResult(CompilationResult result) { try { if (result.hasProblems()) {
IProblem[] problems = result.getProblems(); for (IProblem problem : problems) { if (problem.isError()) {
String name = new String(problem.getOriginatingFileName()); try {
problemList.add(ErrorDispatcher.createJavacError
(name, pageNodes, new StringBuilder(problem.getMessage()),
problem.getSourceLineNumber(), ctxt));
} catch (JasperException e) {
log.error(Localizer.getMessage("jsp.error.compilation.jdtProblemError"), e);
}
}
}
} if (problemList.isEmpty()) {
ClassFile[] classFiles = result.getClassFiles(); for (ClassFile classFile : classFiles) { char[][] compoundName =
classFile.getCompoundName();
StringBuilder classFileName = new StringBuilder(outputDir).append('/'); for (int j = 0;
j < compoundName.length; j++) { if (j > 0) {
classFileName.append('/');
}
classFileName.append(compoundName[j]);
} byte[] bytes = classFile.getBytes();
classFileName.append(".class"); try (FileOutputStream fout = new FileOutputStream(classFileName.toString());
BufferedOutputStream bos = new BufferedOutputStream(fout)) {
bos.write(bytes);
}
}
}
} catch (IOException exc) {
log.error(Localizer.getMessage("jsp.error.compilation.jdt"), 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);
}
CompilerOptions cOptions = new CompilerOptions(settings);
// Check source/target JDK versions as the newest versions are allowed // in Tomcat configuration but may not be supported by the ECJ version // being used.
String requestedSource = ctxt.getOptions().getCompilerSourceVM(); if (requestedSource != null) {
String actualSource = CompilerOptions.versionFromJdkLevel(cOptions.sourceLevel); if (!requestedSource.equals(actualSource)) {
log.warn(Localizer.getMessage("jsp.warning.unsupported.sourceVM", requestedSource, actualSource));
}
}
String requestedTarget = ctxt.getOptions().getCompilerTargetVM(); if (requestedTarget != null) {
String actualTarget = CompilerOptions.versionFromJdkLevel(cOptions.targetJDK); if (!requestedTarget.equals(actualTarget)) {
log.warn(Localizer.getMessage("jsp.warning.unsupported.targetVM", requestedTarget, actualTarget));
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.