Search code examples
javagradlebuild.gradlesaxonsecurityexception

Eliminating SecurityException with saxon jar in Gradle 8


I have a Gradle 8 Java program that is throwing this exception:

java.lang.SecurityException: class "net.sf.saxon.value.UntypedAtomicValue"'s signer
information does not match signer information of other classes in the same package

The class net.sf.saxon.value.UntypedAtomicValue appears to be part of Saxon-HE.

An answer to Java SecurityException: signer information does not match says:

This happens when classes belonging to the same package are loaded from different JAR files, and those JAR files have signatures signed with different certificates - or, perhaps more often, at least one is signed and one or more others are not (which includes classes loaded from directories since those AFAIK cannot be signed). Another response indicates that it can be due to a duplicated jar.

These are the dependencies for my project:

dependencies {
    implementation 'com.github.javaparser:javaparser-symbol-solver-core:3.25.3'
    implementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    implementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
    implementation 'org.junit.platform:junit-platform-launcher:1.10.0-M1'
    implementation 'org.junit.platform:junit-platform-console:1.10.0-RC1'
    testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.0-M1'
    implementation 'org.jacoco:org.jacoco.core:0.8.10'
    implementation 'org.json:json:20230618'
    implementation 'com.puppycrawl.tools:checkstyle:10.12.1'
    implementation 'net.sourceforge.pmd:pmd:6.54.0'
    implementation 'net.sourceforge.pmd:pmd-java:6.54.0'
    implementation 'net.sourceforge.pmd:pmd-core:6.54.0'
}

To find transitive dependencies, I ran:

./gradlew dependencies > dependencies.txt

Here is an excerpt of the results:

+--- com.puppycrawl.tools:checkstyle:10.12.1
|    +--- info.picocli:picocli:4.7.4
|    +--- org.antlr:antlr4-runtime:4.11.1
|    +--- commons-beanutils:commons-beanutils:1.9.4
|    |    +--- commons-logging:commons-logging:1.2
|    |    \--- commons-collections:commons-collections:3.2.2
|    +--- com.google.guava:guava:32.0.1-jre (*)
|    +--- org.reflections:reflections:0.10.2
|    |    +--- org.javassist:javassist:3.28.0-GA -> 3.29.2-GA
|    |    +--- com.google.code.findbugs:jsr305:3.0.2
|    |    \--- org.slf4j:slf4j-api:1.7.32
|    +--- net.sf.saxon:Saxon-HE:12.2                          <-----
|    |    \--- org.xmlresolver:xmlresolver:5.1.2
|    \--- org.checkerframework:checker-qual:3.27.0 -> 3.33.0
+--- net.sourceforge.pmd:pmd:6.54.0
+--- net.sourceforge.pmd:pmd-java:6.54.0
|    +--- net.sourceforge.pmd:pmd-core:6.54.0
|    |    +--- org.antlr:antlr4-runtime:4.7.2 -> 4.11.1
|    |    +--- com.beust:jcommander:1.48
|    |    +--- net.sourceforge.saxon:saxon:9.1.0.8            <-----
|    |    +--- org.apache.commons:commons-lang3:3.8.1
|    |    +--- org.ow2.asm:asm:9.3 -> 9.5
|    |    \--- com.google.code.gson:gson:2.8.9
|    +--- net.sourceforge.saxon:saxon:9.1.0.8                 <-----
|    +--- org.ow2.asm:asm:9.3 -> 9.5
|    \--- org.apache.commons:commons-lang3:3.8.1
+--- net.sourceforge.pmd:pmd-core:6.54.0 (*)

The artifact net.sf.saxon:Saxon-HE appears only once (for checkstyle). The presumably related artifact net.sourceforge.saxon:saxon appears multiple times under net.sourceforge.pmd artifacts, always the same version: 9.1.0.8. (This is the only available version of saxon.)

The SecurityException goes away if I remove the checkstyle dependency, so it may be some sort of conflict between net.sf.saxon:Saxon-HE.

I got a library conflict when I tried using a PMD 7 RC. Although Gradle doesn't show a dependency from checkstyle to PMD, one appears in checkstyle's pom.xml.

My questions are:

  1. Why I am getting this error?
  2. How can I fix it in this Gradle 8 (Groovy DSL) project?

Solution

  • It seems that the failure is because you have two different versions of Saxon on the classpath. This isn't going to work, because the class loader will load classes from the two different versions more or less at random, and they won't be compatible with each other.

    There's no easy solution. You're going to have to upgrade all parts of the application to use the same Saxon version. If some of those components are third-party code, and if they dig deep into Saxon internal interfaces rather than sticking to the stable public API, then this may not be a trivial task.