Skip to content

Fix JPMS split-package error by bundling shims into the main JAR#379

Open
aleruz-dt wants to merge 1 commit intoOWASP:mainfrom
aleruz-dt:fix/jpms-split-package
Open

Fix JPMS split-package error by bundling shims into the main JAR#379
aleruz-dt wants to merge 1 commit intoOWASP:mainfrom
aleruz-dt:fix/jpms-split-package

Conversation

@aleruz-dt
Copy link
Copy Markdown

Problem

Since release 20240325.1, the library ships three separate JARs on Maven Central:

  • owasp-java-html-sanitizer
  • java8-shim
  • java10-shim

Both java8-shim and java10-shim declare the package org.owasp.shim. When all three JARs are placed on the JPMS module path (Java 9+), the JVM raises a hard error at startup — before any application code runs:

Error occurred during initialization of boot layer
java.lang.LayerInstantiationException: Package org.owasp.shim in both
  com.googlecode.owasp-java-html-sanitizer.java8.shim
  and com.googlecode.owasp-java-html-sanitizer.java10.shim

This is a split-package violation. JPMS forbids the same package from appearing in more than one named or automatic module, and there is no workaround available to consumers short of keeping the library off the module path entirely.

The issue was first reported in #341 (June 2024). This PR resolves it.


Root Cause

Java8Shim uses reflection at runtime to select the right implementation:

// Prefers ForJava9AndLater (from java10-shim); falls back to ForJava8 (from java8-shim)
_instance = Class.forName("org.owasp.shim.ForJava9AndLater").newInstance();

This dispatch works correctly on the classpath. The problem is purely structural: JPMS resolves modules — and enforces split-package constraints — at layer instantiation time, before any reflection can execute. Two JARs exporting the same package is unconditionally rejected.


Fix

Use maven-shade-plugin in owasp-java-html-sanitizer to inline both shim JARs into the main artifact at build time.

With org.owasp.shim living inside a single JAR, JPMS sees one module, one package — no split. The existing reflection-based dispatch in Java8Shim continues to work unchanged.

Both java8-shim and java10-shim remain published on Maven Central as standalone artifacts for backwards compatibility. They are marked <optional>true</optional> in the main module's POM so they no longer appear as transitive dependencies of consumers (their classes are now inlined).

An explicit Automatic-Module-Name: owasp.java.html.sanitizer is added to the JAR manifest so that the module name is stable and independent of the JAR filename, which is the recommended practice for libraries that have not yet migrated to a full module-info.java.


Changes

File Change
pom.xml Add maven-shade-plugin 3.6.0 to <pluginManagement> (required by requirePluginVersions enforcer)
owasp-java-html-sanitizer/pom.xml Add shade execution; mark shim deps <optional>; add Automatic-Module-Name to bundle manifest
docs/maven.md Update stale version example; note that the JAR is now self-contained
change_log.md Add entry for next release

Compatibility

No source or binary incompatibility for the public API (org.owasp.html). The following points are worth noting for the release notes:

  • Transitive dependencies: java8-shim and java10-shim no longer appear in the transitive dependency graph of owasp-java-html-sanitizer. Projects that inadvertently relied on them as transitives must now declare them explicitly. In practice this is unlikely, as org.owasp.shim is an internal implementation package.
  • OSGi: org.owasp.shim is not listed in Export-Package and was never part of the public OSGi contract. OSGi consumers are unaffected.
  • banDuplicateClasses enforcer rule: this rule is currently commented out in the parent POM with a TODO. The shading intentionally causes org.owasp.shim classes to appear in both the shim JARs and the inlined copy inside the main JAR within the reactor build. This is consistent with the existing TODO and does not affect published artifacts.

Verification

./mvnw verify

All tests pass. The OSGi manifest verification (maven-verifier-plugin) confirms Export-Package: org.owasp.html is present and correct in the shaded JAR.

Closes #341

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.

Please build the Java8/10 shim classes into the sanitizer JAR

1 participant