Skip to content

Fix bytecode compliance check crash on project class references#5061

Merged
shai-almog merged 2 commits into
masterfrom
fix-bytecode-compliance-classloader
May 28, 2026
Merged

Fix bytecode compliance check crash on project class references#5061
shai-almog merged 2 commits into
masterfrom
fix-bytecode-compliance-classloader

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Summary

  • Real bug fix: BytecodeComplianceMojo.validateClass crashed with TypeNotPresentException / ClassNotFoundException whenever an invocation rewrite was applied to a class that referenced a sibling project class. ASM's CheckClassAdapter.verify was called without a ClassLoader, so SimpleVerifier fell back to Class.forName on the plugin classloader (which doesn't see user project classes). The crash matches the "sometimes works, sometimes doesn't" reports: classes without rewrites or without sibling references pass; otherwise fail. Now we pass a URLClassLoader spanning the project's output dir + compile-scope dep jars, and treat any remaining unresolvable type as a debug-level skip rather than a build failure — the verify is only a sanity check on our rewrite; the real compliance scan and the cloud build still catch genuine API misuse.
  • Deprecation warning cleanup: Migrated every internal POM, archetype, initializr template, the cn1lib lifecycle binding, and the bundled skill docs off the deprecated compliance-check goal name to the new bytecode-compliance. Fresh initializr projects no longer print the warning. The ComplianceCheckMojo alias remains for backward-compat with older user POMs, with a cleaned-up deprecation message (no more raw {@link ...} in the user-facing warning).

Affected files: BytecodeComplianceMojo.java, ComplianceCheckMojo.java, META-INF/plexus/components.xml, both archetypes, the five initializr POM templates, the bundled skill docs, and the various internal test/demo/script POMs.

Test plan

  • mvn -o test -Dtest=BytecodeComplianceMojoTest passes (all 4 rewrite tests, after null-project guard so direct mojo instantiation still works in unit tests).
  • Full mvn -o test is no worse than before (down from 7 → 3 errors; remaining 3 are pre-existing BindingAnnotationProcessorTest failures about missing getValidator() on NotifiableBinding subclasses, unrelated to this change).
  • grep -rn "<goal>compliance-check</goal>" on source POMs returns nothing.
  • Reporter's project (canopus-common with SwingTableQPane reference + String.split callsite) builds cleanly.

🤖 Generated with Claude Code

The cn1:compliance-check goal (now bytecode-compliance) crashed when an
invocation rewrite (String.split / replaceAll / replaceFirst) was applied
to a class that referenced a sibling project class. ASM's CheckClassAdapter
.verify was called without a ClassLoader, so SimpleVerifier fell back to
Class.forName on the plugin classloader, which doesn't see user project
classes, producing a TypeNotPresentException / ClassNotFoundException and
failing the build.

Pass a URLClassLoader that spans the project's output dir plus compile
-scope dependency jars, and treat any remaining unresolvable types as a
debug-level skip rather than a build failure — the verify is only a
sanity check on our rewrite; the real compliance scan and the cloud
build still catch genuine API misuse.

Also migrates all internal POMs, archetypes, initializr templates, and
the cn1lib lifecycle binding off the deprecated compliance-check alias
to the new bytecode-compliance goal, so fresh initializr projects no
longer print the deprecation warning. The alias remains for backward
compatibility with older user projects, with a cleaned-up deprecation
message.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 28, 2026

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

docs/demos pins to codenameone-maven-plugin 7.0.208 and
scripts/skindesigner pins to 7.0.228; neither has the bytecode-compliance
goal yet. Keep them on the compliance-check alias.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 116 screenshots: 116 matched.

Native Android coverage

  • 📊 Line coverage: 12.45% (7219/57972 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.16% (36294/357360), branch 4.27% (1446/33836), complexity 5.31% (1725/32486), method 9.25% (1407/15210), class 15.16% (321/2117)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 12.45% (7219/57972 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.16% (36294/357360), branch 4.27% (1446/33836), complexity 5.31% (1725/32486), method 9.25% (1407/15210), class 15.16% (321/2117)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)
      • kotlinx.coroutines.kotlinx.coroutines.JobSupport – 0.00% (0/423 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 843.000 ms
Base64 CN1 encode 189.000 ms
Base64 encode ratio (CN1/native) 0.224x (77.6% faster)
Base64 native decode 869.000 ms
Base64 CN1 decode 271.000 ms
Base64 decode ratio (CN1/native) 0.312x (68.8% faster)
Image encode benchmark status skipped (SIMD unsupported)

@github-actions
Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog shai-almog merged commit 2222a22 into master May 28, 2026
21 of 22 checks passed
@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 47 screenshots: 47 matched.
✅ JavaScript-port screenshot tests passed.

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 116 screenshots: 116 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 209 seconds

Build and Run Timing

Metric Duration
Simulator Boot 78000 ms
Simulator Boot (Run) 1000 ms
App Install 13000 ms
App Launch 3000 ms
Test Execution 268000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 532.000 ms
Base64 CN1 encode 1260.000 ms
Base64 encode ratio (CN1/native) 2.368x (136.8% slower)
Base64 native decode 256.000 ms
Base64 CN1 decode 860.000 ms
Base64 decode ratio (CN1/native) 3.359x (235.9% slower)
Base64 SIMD encode 896.000 ms
Base64 encode ratio (SIMD/native) 1.684x (68.4% slower)
Base64 encode ratio (SIMD/CN1) 0.711x (28.9% faster)
Base64 SIMD decode 869.000 ms
Base64 decode ratio (SIMD/native) 3.395x (239.5% slower)
Base64 decode ratio (SIMD/CN1) 1.010x (1.0% slower)
Image encode benchmark iterations 100
Image createMask (SIMD off) 101.000 ms
Image createMask (SIMD on) 10.000 ms
Image createMask ratio (SIMD on/off) 0.099x (90.1% faster)
Image applyMask (SIMD off) 144.000 ms
Image applyMask (SIMD on) 57.000 ms
Image applyMask ratio (SIMD on/off) 0.396x (60.4% faster)
Image modifyAlpha (SIMD off) 142.000 ms
Image modifyAlpha (SIMD on) 64.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.451x (54.9% faster)
Image modifyAlpha removeColor (SIMD off) 234.000 ms
Image modifyAlpha removeColor (SIMD on) 91.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.389x (61.1% faster)
Image PNG encode (SIMD off) 1146.000 ms
Image PNG encode (SIMD on) 868.000 ms
Image PNG encode ratio (SIMD on/off) 0.757x (24.3% faster)
Image JPEG encode 541.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 28, 2026

Compared 116 screenshots: 116 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 288 seconds

Build and Run Timing

Metric Duration
Simulator Boot 95000 ms
Simulator Boot (Run) 1000 ms
App Install 20000 ms
App Launch 7000 ms
Test Execution 355000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1103.000 ms
Base64 CN1 encode 1903.000 ms
Base64 encode ratio (CN1/native) 1.725x (72.5% slower)
Base64 native decode 345.000 ms
Base64 CN1 decode 1653.000 ms
Base64 decode ratio (CN1/native) 4.791x (379.1% slower)
Base64 SIMD encode 850.000 ms
Base64 encode ratio (SIMD/native) 0.771x (22.9% faster)
Base64 encode ratio (SIMD/CN1) 0.447x (55.3% faster)
Base64 SIMD decode 610.000 ms
Base64 decode ratio (SIMD/native) 1.768x (76.8% slower)
Base64 decode ratio (SIMD/CN1) 0.369x (63.1% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 122.000 ms
Image createMask (SIMD on) 33.000 ms
Image createMask ratio (SIMD on/off) 0.270x (73.0% faster)
Image applyMask (SIMD off) 159.000 ms
Image applyMask (SIMD on) 78.000 ms
Image applyMask ratio (SIMD on/off) 0.491x (50.9% faster)
Image modifyAlpha (SIMD off) 227.000 ms
Image modifyAlpha (SIMD on) 120.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.529x (47.1% faster)
Image modifyAlpha removeColor (SIMD off) 343.000 ms
Image modifyAlpha removeColor (SIMD on) 229.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.668x (33.2% faster)
Image PNG encode (SIMD off) 1527.000 ms
Image PNG encode (SIMD on) 1100.000 ms
Image PNG encode ratio (SIMD on/off) 0.720x (28.0% faster)
Image JPEG encode 777.000 ms

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