Skip to content

SONARJAVA-7285 Compile Jasper helper classes with the JDK compiler - #6453

Closed
aurelien-coet-sonarsource wants to merge 6 commits into
ac/java-psi-frontend-3from
ac/java-psi-frontend-4
Closed

aurelien-coet-sonarsource wants to merge 6 commits into
ac/java-psi-frontend-3from
ac/java-psi-frontend-4

Conversation

@aurelien-coet-sonarsource

@aurelien-coet-sonarsource aurelien-coet-sonarsource commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

Summary by Gitar

  • New feature:
    • Added JasperCompiler, which compiles JSP tag helpers with the JDK compiler via ToolProvider
    • Built the compiler classpath from the context classpath, JSP loader URLs, and the running JVM
  • Configuration:
    • JasperOptions.getCompilerClassName() now returns JasperCompiler
  • Build:
    • Excluded JDTCompiler* classes from the shaded jar in sonar-java-plugin/pom.xml
  • Tests:
    • Updated JasperOptionsTest to expect the new compiler class name

This will update automatically on new commits.

@hashicorp-vault-sonar-prod hashicorp-vault-sonar-prod Bot changed the title Compile Jasper helper classes with the JDK compiler SONARJAVA-7285 Compile Jasper helper classes with the JDK compiler Nov 2, 2026
@hashicorp-vault-sonar-prod

hashicorp-vault-sonar-prod Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

SONARJAVA-7285

Comment on lines +43 to +46
var compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
throw new JasperException("A JDK compiler is required to process JSP tag files");
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Bug: JSP tag files now fail on JRE-only scanners that ship without javac

JasperOptions.getCompilerClassName() now always returns JasperCompiler. Tomcat 9.0.123's JspCompilationContext.createCompiler() uses that class directly and never falls back to JDTCompiler, and this PR also removes JDTCompiler*.class from the shaded jar. JasperCompiler.generateClass relies on ToolProvider.getSystemJavaCompiler(), which returns null when the jdk.compiler module is missing. That module is missing from the Temurin JREs SonarScanner downloads through JRE auto-provisioning (Temurin 21 module list, ToolProvider docs, scanner JRE provisioning).

Before this PR, Jasper compiled tag-file helper classes with JDTCompiler, using the unrelocated org.eclipse.jdt.internal.compiler classes that jdt-package still provides. That works on a plain JRE. After this PR, any JSP that uses a .tag file throws JasperException("A JDK compiler is required...") on a JRE runtime. Jasper.generateFiles catches the exception, drops the page, and logs only a generic warning, so those pages are silently left out of the analysis in the default scanner setup.

Suggested fix: fall back to the previous ECJ/JDT path (or another in-process compiler) when no system compiler is available, rather than failing. Also log a clear, user-visible warning that tag-file JSPs need a JDK.

Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Nov 2, 2026

Copy link
Copy Markdown
Code Review ⚠️ Changes requested 0 closed / 1 findings

🟡 Medium risk · Switching Jasper tag-helper compilation to the JDK compiler changes JSP processing and could cause analyses to fail when the compiler or classpath differs.

Adds JasperCompiler, which compiles JSP tag-file helper classes with the JDK compiler via ToolProvider, and switches JasperOptions.getCompilerClassName() to it. Changes requested: on JRE-only scanners without the jdk.compiler module, ToolProvider.getSystemJavaCompiler() returns null, so any JSP using a .tag file now fails with a JasperException, is dropped from analysis, and only gets a generic warning. Fall back to the previous JDT compiler path when no system compiler is available, and log a clear warning that tag-file JSPs need a JDK.

⚠️ Bug: JSP tag files now fail on JRE-only scanners that ship without javac

📄 java-jsp/src/main/java/org/sonar/java/jsp/JasperCompiler.java:43-46 📄 java-jsp/src/main/java/org/sonar/java/jsp/JasperOptions.java:158 📄 sonar-java-plugin/pom.xml:247-249

JasperOptions.getCompilerClassName() now always returns JasperCompiler. Tomcat 9.0.123's JspCompilationContext.createCompiler() uses that class directly and never falls back to JDTCompiler, and this PR also removes JDTCompiler*.class from the shaded jar. JasperCompiler.generateClass relies on ToolProvider.getSystemJavaCompiler(), which returns null when the jdk.compiler module is missing. That module is missing from the Temurin JREs SonarScanner downloads through JRE auto-provisioning (Temurin 21 module list, ToolProvider docs, scanner JRE provisioning).

Before this PR, Jasper compiled tag-file helper classes with JDTCompiler, using the unrelocated org.eclipse.jdt.internal.compiler classes that jdt-package still provides. That works on a plain JRE. After this PR, any JSP that uses a .tag file throws JasperException("A JDK compiler is required...") on a JRE runtime. Jasper.generateFiles catches the exception, drops the page, and logs only a generic warning, so those pages are silently left out of the analysis in the default scanner setup.

Suggested fix: fall back to the previous ECJ/JDT path (or another in-process compiler) when no system compiler is available, rather than failing. Also log a clear, user-visible warning that tag-file JSPs need a JDK.

🤖 Prompt for agents
Code Review: Adds `JasperCompiler`, which compiles JSP tag-file helper classes with the JDK compiler via `ToolProvider`, and switches `JasperOptions.getCompilerClassName()` to it. Changes requested: on JRE-only scanners without the `jdk.compiler` module, `ToolProvider.getSystemJavaCompiler()` returns `null`, so any JSP using a `.tag` file now fails with a `JasperException`, is dropped from analysis, and only gets a generic warning. Fall back to the previous JDT compiler path when no system compiler is available, and log a clear warning that tag-file JSPs need a JDK.

1. ⚠️ Bug: JSP tag files now fail on JRE-only scanners that ship without javac
   Files: java-jsp/src/main/java/org/sonar/java/jsp/JasperCompiler.java:43-46, java-jsp/src/main/java/org/sonar/java/jsp/JasperOptions.java:158, sonar-java-plugin/pom.xml:247-249

   `JasperOptions.getCompilerClassName()` now always returns `JasperCompiler`. Tomcat 9.0.123's `JspCompilationContext.createCompiler()` uses that class directly and never falls back to `JDTCompiler`, and this PR also removes `JDTCompiler*.class` from the shaded jar. `JasperCompiler.generateClass` relies on `ToolProvider.getSystemJavaCompiler()`, which returns `null` when the `jdk.compiler` module is missing. That module is missing from the Temurin JREs SonarScanner downloads through JRE auto-provisioning ([Temurin 21 module list](https://github.com/adoptium/adoptium-support/issues/1385), [ToolProvider docs](https://docs.oracle.com/en/java/javase/21/docs/api/java.compiler/javax/tools/ToolProvider.html), [scanner JRE provisioning](https://docs.sonarsource.com/sonarqube-server/10.6/analyzing-source-code/scanners/general-requirements)).
   
   Before this PR, Jasper compiled tag-file helper classes with `JDTCompiler`, using the unrelocated `org.eclipse.jdt.internal.compiler` classes that `jdt-package` still provides. That works on a plain JRE. After this PR, any JSP that uses a `.tag` file throws `JasperException("A JDK compiler is required...")` on a JRE runtime. `Jasper.generateFiles` catches the exception, drops the page, and logs only a generic warning, so those pages are silently left out of the analysis in the default scanner setup.
   
   Suggested fix: fall back to the previous ECJ/JDT path (or another in-process compiler) when no system compiler is available, rather than failing. Also log a clear, user-visible warning that tag-file JSPs need a JDK.

Verification Rules 2/2 met Repos 4 inspected · PRs 2 inspected

Functional validation No results

Rules 2 passed 1 not applicable

✅ Internal artifact registries
✅ Repository license compliance

Broader impact Repos 4 inspected PRs 2 inspected
Cross-repo 4 repositories inspected 0 open impacts

SonarSource/sonar-java-symbolic-execution Inspected
SonarSource/sonarqube Inspected
SonarSource/sonarlint-intellij Inspected
SonarSource/sonarlint-vscode Inspected

Cross-PR 2 PRs inspected 0 open impacts

PR 6454: SONARJAVA-7286 Add PSI dependencies packaging and third-party license notices Inspected
PR 6449: SONARJAVA-7283 Decouple the frontend from Eclipse JDT core Inspected

Auto-approval Not enabled

Set up

For more verification details, comment gitar display:verbose.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing compact verification results.
Unblock → Override a blocking verdict and allow merging.

Comment with these commands to change the behavior for this request:

Auto-apply Compact Unblock
gitar auto-apply:on         
gitar display:verbose         
gitar unblock         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqube-next

sonarqube-next Bot commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Quality Gate failed Quality Gate failed

Failed conditions
2 New issues

See analysis details on SonarQube

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE SonarQube for IDE

@aurelien-coet-sonarsource
aurelien-coet-sonarsource force-pushed the ac/java-psi-frontend-3 branch 2 times, most recently from d5e9f9f to 847e881 Compare November 2, 2026 16:21
@aurelien-coet-sonarsource
aurelien-coet-sonarsource deleted the ac/java-psi-frontend-4 branch November 3, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant