This is an automated email from the ASF dual-hosted git repository.
remm pushed a commit to branch 10.1.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/10.1.x by this push:
new 5ff35e2bef Add simple Java Compiler for JSP
5ff35e2bef is described below
commit 5ff35e2befe8363493e51456d53a257ed28110c1
Author: remm <[email protected]>
AuthorDate: Wed Mar 26 11:32:58 2025 +0100
Add simple Java Compiler for JSP
Supports exploded webapps.
Uses JDT code for error processing.
---
java/org/apache/jasper/compiler/JavaCompiler.java | 108 ++++++++++++++++++++++
res/checkstyle/org-import-control.xml | 1 +
webapps/docs/changelog.xml | 5 +
3 files changed, 114 insertions(+)
diff --git a/java/org/apache/jasper/compiler/JavaCompiler.java
b/java/org/apache/jasper/compiler/JavaCompiler.java
new file mode 100644
index 0000000000..2cc6d48c5c
--- /dev/null
+++ b/java/org/apache/jasper/compiler/JavaCompiler.java
@@ -0,0 +1,108 @@
+/*
+ * 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.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+import org.apache.jasper.JasperException;
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
+
+/**
+ * Main JSP compiler class. This class uses the Java Compiler API for
compiling.
+ */
+public class JavaCompiler extends Compiler {
+
+ private final Log log = LogFactory.getLog(JavaCompiler.class); // must not
be static
+
+ @Override
+ protected void generateClass(Map<String, SmapStratum> smaps) throws
JasperException, IOException {
+
+ long t1 = 0;
+ if (log.isDebugEnabled()) {
+ t1 = System.currentTimeMillis();
+ }
+
+ javax.tools.JavaCompiler compiler =
ToolProvider.getSystemJavaCompiler();
+ DiagnosticCollector<JavaFileObject> diagnostics = new
DiagnosticCollector<>();
+ StandardJavaFileManager fileManager =
+ compiler.getStandardFileManager(diagnostics, null,
Charset.forName(ctxt.getOptions().getJavaEncoding()));
+ Iterable<? extends JavaFileObject> compilationUnits =
+ fileManager.getJavaFileObjectsFromFiles(List.of(new
File(ctxt.getServletJavaFileName())));
+ // Perform Java compilation using the appropriate options
+ List<String> compilerOptions =
+ List.of("-classpath", ctxt.getClassPath(), "-source",
ctxt.getOptions().getCompilerSourceVM(),
+ "-target", ctxt.getOptions().getCompilerTargetVM());
+ Boolean result =
+ compiler.getTask(null, fileManager, diagnostics,
compilerOptions, null, compilationUnits).call();
+
+ List<JavacErrorDetail> problemList = new ArrayList<>();
+ if (!result.booleanValue()) {
+ for (Diagnostic<? extends JavaFileObject> diagnostic :
diagnostics.getDiagnostics()) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ try {
+
problemList.add(ErrorDispatcher.createJavacError(diagnostic.getSource().getName(),
pageNodes,
+ new
StringBuilder(diagnostic.getMessage(Locale.getDefault())),
+ (int) diagnostic.getLineNumber(), ctxt));
+ } catch (JasperException e) {
+
log.error(Localizer.getMessage("jsp.error.compilation.jdtProblemError"), e);
+ }
+ }
+ }
+ }
+
+ 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);
+ }
+
+ }
+
+}
diff --git a/res/checkstyle/org-import-control.xml
b/res/checkstyle/org-import-control.xml
index b6d877321d..e324564703 100644
--- a/res/checkstyle/org-import-control.xml
+++ b/res/checkstyle/org-import-control.xml
@@ -106,6 +106,7 @@
<allow pkg="org.apache.el"/>
</subpackage>
<subpackage name="jasper">
+ <allow pkg="javax.tools"/>
<allow pkg="jakarta.el"/>
<allow pkg="jakarta.servlet"/>
<allow pkg="org.apache.el"/>
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index faa84ba3f4..5e82c457e0 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -188,6 +188,11 @@
Replace custom URL encoding provided by the JSP runtime library with
calls to <code>java.net.URLEncoder.encode()</code>. (markt)
</scode>
+ <add>
+ Add compiler using the <code>Java Compiler</code> API, supporting
+ exploded web applications. The <code>compilerClassName</code> to use is
+ <code>org.apache.jasper.compiler.JavaCompiler</code>. (remm)
+ </add>
</changelog>
</subsection>
<subsection name="Cluster">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]