ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/jasper/compiler/JDTCompiler.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/jasper/compiler/JDTCompiler.java
Status
scanned
Type
file
Name
JDTCompiler.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
28232 (27.6 KB)
MD5
dc568272a29f00754467c538e5de143a
SHA1
1c9d4821bd8769665bc58923de640f72a7ecafbf
SHA256
9747a8d9edbe0a232e4901eeec561e80cc1e6443274a319705e23ec18d34b898
SHA512

      
    
SHA1_git
f71ca3093479e64eb3d58e65bc15832922ad7067
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
JDTCompiler.java | 27.6 KB |

/* * 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; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.StringTokenizer; import org.apache.jasper.JasperException; import org.apache.jasper.runtime.ExceptionUtils; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.ClassFile; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.Compiler; import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; import org.eclipse.jdt.internal.compiler.ICompilerRequestor; import org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy; import org.eclipse.jdt.internal.compiler.IProblemFactory; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader; import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException; import org.eclipse.jdt.internal.compiler.env.ICompilationUnit; import org.eclipse.jdt.internal.compiler.env.INameEnvironment; import org.eclipse.jdt.internal.compiler.env.NameEnvironmentAnswer; import org.eclipse.jdt.internal.compiler.impl.CompilerOptions; import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment; import org.eclipse.jdt.internal.compiler.lookup.ModuleBinding; import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory; /** * 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. */ public class JDTCompiler extends org.apache.jasper.compiler.Compiler { private final Log log = LogFactory.getLog(JDTCompiler.class); // must not be static @Override protected void 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 { private final String className; private final String sourceFile; CompilationUnit(String sourceFile, String className) { this.className = className; this.sourceFile = sourceFile; } @Override public char[] getFileName() { return sourceFile.toCharArray(); } @Override public char[] getContents() { char[] result = null; try (FileInputStream is = new FileInputStream(sourceFile); InputStreamReader isr = new InputStreamReader(is, ctxt.getOptions().getJavaEncoding()); Reader reader = new BufferedReader(isr)) { char[] chars = new char[8192]; StringBuilder buf = new StringBuilder(); 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 ioe) { log.error(Localizer.getMessage("jsp.error.compilation.source", sourceFile), ioe); } return result; } @Override public char[] getMainTypeName() { int dot = className.lastIndexOf('.'); if (dot > 0) { return className.substring(dot + 1).toCharArray(); } return className.toCharArray(); } @Override 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; } @Override public boolean ignoreOptionalProblems() { return false; } @Override public ModuleBinding module(LookupEnvironment environment) { return environment.getModule(ModuleBinding.UNNAMED); } @Override public char[] getModuleName() { return ModuleBinding.UNNAMED; } } 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()); } private NameEnvironmentAnswer findType(String className) { if (className.equals(targetClassName)) { ICompilationUnit compilationUnit = new CompilationUnit(sourceFile, className); return new NameEnvironmentAnswer(compilationUnit, null); } String resourceName = className.replace('.', '/') + ".class"; try (InputStream 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 | ClassFormatException exc) { log.error(Localizer.getMessage("jsp.error.compilation.dependent", className), exc); } return null; } private boolean isPackage(String result) { if (result.equals(targetClassName) || result.startsWith(targetClassName + '$')) { return false; } /* * This might look heavy-weight but, with only the ClassLoader API available, trying to load the * resource as a class is the only reliable way found so far to differentiate between a class and a * package. Other options, such as getResource(), fail for some edge cases on case insensitive file * systems. As this code is only called at compile time, the performance impact is not a significant * concern. */ try { classLoader.loadClass(result); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); return true; } return false; } @Override public boolean 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())) { return false; } } if (i > 0) { result.append('.'); } result.append(packageName); return isPackage(result.toString()); } @Override public void 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); } 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 if (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 } else if (opt.equals("9") || opt.equals("1.9")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_9); } else if (opt.equals("10")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_10); } else if (opt.equals("11")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_11); } else if (opt.equals("12")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_12); } else if (opt.equals("13")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_13); } else if (opt.equals("14")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_14); } else if (opt.equals("15")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_15); } else if (opt.equals("16")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_16); } else if (opt.equals("17")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_17); } else if (opt.equals("18")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_18); } else if (opt.equals("19")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_19); } else if (opt.equals("20")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_20); } else if (opt.equals("21")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_21); } else if (opt.equals("22")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_22); } else if (opt.equals("23")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_23); } else if (opt.equals("24")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_24); } else if (opt.equals("25")) { settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_25); } else if (opt.equals("26")) { // 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, "26"); } else { log.warn(Localizer.getMessage("jsp.warning.unknown.sourceVM", opt)); settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_17); } } else { // Default to 17 settings.put(CompilerOptions.OPTION_Source, CompilerOptions.VERSION_17); } // 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 if (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 } else if (opt.equals("9") || opt.equals("1.9")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_9); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_9); } else if (opt.equals("10")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_10); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_10); } else if (opt.equals("11")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_11); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_11); } else if (opt.equals("12")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_12); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_12); } else if (opt.equals("13")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_13); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_13); } else if (opt.equals("14")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_14); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_14); } else if (opt.equals("15")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_15); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_15); } else if (opt.equals("16")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_16); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_16); } else if (opt.equals("17")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_17); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_17); } else if (opt.equals("18")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_18); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_18); } else if (opt.equals("19")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_19); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_19); } else if (opt.equals("20")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_20); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_20); } else if (opt.equals("21")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_21); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_21); } else if (opt.equals("22")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_22); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_22); } else if (opt.equals("23")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_23); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_23); } else if (opt.equals("24")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_24); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_24); } else if (opt.equals("25")) { settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_25); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_25); } else if (opt.equals("26")) { // 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, "26"); settings.put(CompilerOptions.OPTION_Compliance, "26"); } else { log.warn(Localizer.getMessage("jsp.warning.unknown.targetVM", opt)); settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_17); } } else { // Default to 17 settings.put(CompilerOptions.OPTION_TargetPlatform, CompilerOptions.VERSION_17); settings.put(CompilerOptions.OPTION_Compliance, CompilerOptions.VERSION_17); } final IProblemFactory problemFactory = new DefaultProblemFactory(Locale.getDefault()); final ICompilerRequestor requestor = new ICompilerRequestor() { @Override public void 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 ioe) { log.error(Localizer.getMessage("jsp.error.compilation.jdt"), ioe); } } }; 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)); } } cOptions.parseLiteralExpressionsAsConstants = true; Compiler compiler = new Compiler(env, policy, cOptions, requestor, problemFactory); compiler.compile(compilationUnits); if (!ctxt.keepGenerated()) { File javaFile = new File(ctxt.getServletJavaFileName()); if (!javaFile.delete()) { throw new JasperException(Localizer.getMessage("jsp.warning.compiler.javafile.delete.fail", javaFile)); } } if (!problemList.isEmpty()) { JavacErrorDetail[] jeds = problemList.toArray(new JavacErrorDetail[0]); errDispatcher.javacError(jeds); } if (log.isDebugEnabled()) { long t2 = System.currentTimeMillis(); log.debug(Localizer.getMessage("jsp.compiled", ctxt.getServletJavaFileName(), Long.valueOf(t2 - t1))); } if (ctxt.isPrototypeMode()) { return; } // JSR45 Support if (!options.isSmapSuppressed()) { SmapUtil.installSmap(smaps); } } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
4.93
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9