DEV Community

Query Filter
Query Filter

Posted on

docker6

This is a classic "Enterprise Migration Trap." You are caught between a Legacy Runtime (Java 8) and a Modern Toolchain (Sonar/Tekton) that requires a higher version of Java to execute its own analysis logic.

Since you cannot migrate the actual source code to Java 21 yet, but the pipeline forces Java 21 for the Sonar step, you have three primary strategies to bypass the BASE64Decoder and JAXB compilation errors.


Strategy 1: Decouple Compilation from Analysis (Recommended)

SonarQube does not actually require Java 21 to compile your code; it only needs Java 17+ to run the scanner. You can tell Gradle to use a Java 8 Toolchain for the compilation/test tasks while letting the pipeline environment stay on Java 21.

Add this to your build.gradle:

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(8)
    }
}
Enter fullscreen mode Exit fullscreen mode

Why this works: Even if the Tekton agent is running on JDK 21, Gradle will automatically download (or use a provided) JDK 8 to compile your sun.misc code. The Sonar task will then run using the agent's JDK 21 to analyze the resulting Java 8 bytecode.


Strategy 2: Use the "Shimming" (Patching) approach

If you are forced to compile with the Java 21 compiler (e.g., due to strict LSE pipeline constraints), you can "patch" the missing symbols by adding the modern equivalents as dependencies.

  1. For JAXB (XmlAccessType errors):
    Add these to your dependencies. They provide the classes that were removed in JDK 11.

    implementation 'javax.xml.bind:jaxb-api:2.3.1'
    implementation 'org.glassfish.jaxb:jaxb-runtime:2.3.1'
    
  2. For BASE64Decoder:
    There is no "patch" for sun.misc in Java 21 because it was a private internal API. You must refactor this. As an engineer, the fastest "patch" is a global search and replace:

    • Replace: new BASE64Decoder().decodeBuffer(str)
    • With: java.util.Base64.getDecoder().decode(str)

Strategy 3: The "Double-Pass" Tekton Workflow

If your Tekton pipeline allows multi-step tasks, split the build into two distinct environments:

  1. Step 1 (Build): Use a Tekton step with a Java 8 image. Run ./gradlew clean assemble. This will succeed because Java 8 has the sun.misc classes.
  2. Step 2 (Sonar): Use a Tekton step with a Java 17/21 image. Run ./gradlew sonarqube -x compileJava.
    • The -x compileJava flag tells Gradle: "Don't try to re-compile the code (which would fail on JDK 21), just use the binaries/reports already created in Step 1."

Summary of the "Missing Operand" Error

Regarding your log's mkdir: missing operand and GRADLE_USER_HOME="":
In your Tekton YAML, you likely have a line like mkdir -p $GRADLE_USER_HOME. Because the variable is empty, the command resolves to just mkdir -p, which throws that error.

Fix: Ensure your Tekton Workspace or Environment Variable for GRADLE_USER_HOME is explicitly set to /workspace/source/.gradle or similar.

Wit-check: It's ironic that to prove your code is "High Quality" (Sonar), you have to use a version of Java that hates your code.

Which strategy fits your LSE pipeline constraints best? Strategy 1 (Toolchains) is usually the cleanest if your Artifactory has the JDK 8 distributions mirrored.

EXPERT GUIDE

The choice depends heavily on whether you have the "write access" to modify the build.gradle file or if you are restricted to only changing the Tekton pipeline YAML. Which one do you have more control over?

Top comments (0)