Skip to content

Add com.codename1.crash on-device crash protection client#5001

Open
shai-almog wants to merge 2 commits into
masterfrom
add-crash-protection
Open

Add com.codename1.crash on-device crash protection client#5001
shai-almog wants to merge 2 commits into
masterfrom
add-crash-protection

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Summary

  • New com.codename1.crash package — CrashProtection, PiiScrubber (public, subclassable), CrashReportPayload. Storage-first delivery: every payload is written to Storage with a fresh eventId before the POST; the storage entry is deleted only on a 2xx response. Failed sends are retried on the next launch and the server dedups via the same eventId.
  • Default PiiScrubber rules: emails partially redacted (keep first 3 chars of local part + full domain, e.g. joe***@example.com); runs of 6+ consecutive digits collapsed to [num]; URLs are NOT scrubbed. App devs override scrubMessage / scrubFrame and register via CrashProtection.setScrubber(...).
  • Endpoint URL is fixed to https://cloud.codenameone.com/api/v2/crash/reports. Opt-in is developer-controlled via setEnabled(boolean) (persisted in Preferences, default off). Simulator skips uploads.
  • Wire-up: Android UncaughtExceptionHandler now forwards to CrashProtection.capture(e) alongside the legacy Log.bindCrashProtection path (guarded by try/catch so a bug here can't suppress the legacy path). iOS needs no client change — existing signal handlers already convert signals into JVM exceptions that flow through the EDT error handler.
  • Build-server helper: com.codename1.builders.util.CrashSymbolUploader is a standalone (no Spring) multipart-POST utility the cloud build executor calls after a successful release build to ship mapping.txt (Android) or the dSYM zip (iOS) to the matching server endpoint. AndroidGradleBuilder + IPhoneBuilder carry hook-point comments showing the executor where to call it.

Pairs with codenameone/BuildCloud's server PR adding the matching endpoints, entities, and migration.

Test plan

  • CN1 PR-CI doc validator (validate-java25-markdown-docs.sh) passes — all crash code uses /// markdown style, no classic /** Javadoc.
  • mvn compile succeeds on Java 8 / 17 / 21 matrix (core module enforces Java 5 source/target).
  • Maven plugin module compiles with the new CrashSymbolUploader utility.
  • tests/core PiiScrubberTest covers: email partial redaction, short local-part handling, digit-run scrubbing, URL pass-through, subclass override on top of defaults, null in / null out.
  • On-device sanity: build a sample app, call CrashProtection.install() + setEnabled(true), trigger an NPE, verify a CN1Crash__$<eventId> storage entry is created, then deleted after a successful POST to the cloud endpoint.
  • Confirm the legacy Log.bindCrashProtection path still works when both systems are installed (the Android handler runs both branches, guarded).

🤖 Generated with Claude Code

New package for capturing unhandled exceptions on device, scrubbing
PII, and uploading structured crash reports to the BuildCloud crash
service. Pairs with the new /api/v2/crash/reports server endpoint
(separate BuildCloud PR).

Surface:
- CrashProtection.install() / setEnabled() / setScrubber() /
  capture(). Endpoint is fixed; opt-in is developer-controlled and
  persisted in Preferences (default off).
- PiiScrubber is a public subclassable class. Default rules: emails
  partially redacted (keep first 3 chars + full domain), runs of 6+
  digits collapsed to [num]. URLs are NOT scrubbed.
- Storage-first delivery: every payload is written to Storage with a
  fresh eventId BEFORE the POST; the storage entry is deleted only on
  a 2xx. Failed sends are retried on next launch. The server uses
  eventId for idempotent dedup.

Wire-up:
- Android: AndroidImplementation's UncaughtExceptionHandler now also
  forwards to CrashProtection.capture(e), guarded by try/catch so a
  bug here can't suppress the legacy Log.bindCrashProtection path.
- iOS: no client change. The existing signal handlers in
  CodenameOne_GLAppDelegate.m convert signals to JVM exceptions which
  flow through the EDT error handler naturally.

Build-server utility:
- maven/codenameone-maven-plugin/.../util/CrashSymbolUploader. Used by
  the cloud build executor's post-build hook to POST mapping.txt
  (Android) or the dSYM zip (iOS, release builds only) to the
  /api/v2/build/{buildKey}/symbols endpoint. Standalone, no Spring dep.
  AndroidGradleBuilder + IPhoneBuilder carry comments pointing the
  executor at the right call sites.

Java 5 source compatibility maintained in the core client classes.
No new runtime dependencies on the device. ASCII-only sources;
CodenameOne header (not Oracle).

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

shai-almog commented May 22, 2026

Copy link
Copy Markdown
Collaborator Author

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

@shai-almog

shai-almog commented May 22, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 124 screenshots: 124 matched.

Native Android coverage

  • 📊 Line coverage: 13.21% (7905/59828 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.70% (39150/365755), branch 4.57% (1575/34436), complexity 5.61% (1854/33035), method 9.83% (1519/15457), class 16.06% (348/2167)
    • 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: 13.21% (7905/59828 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 10.70% (39150/365755), branch 4.57% (1575/34436), complexity 5.61% (1854/33035), method 9.83% (1519/15457), class 16.06% (348/2167)
    • 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 912.000 ms
Base64 CN1 encode 296.000 ms
Base64 encode ratio (CN1/native) 0.325x (67.5% faster)
Base64 native decode 837.000 ms
Base64 CN1 decode 388.000 ms
Base64 decode ratio (CN1/native) 0.464x (53.6% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog

shai-almog commented May 22, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 89000 ms
Simulator Boot (Run) 1000 ms
App Install 15000 ms
App Launch 7000 ms
Test Execution 254000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 747.000 ms
Base64 CN1 encode 1232.000 ms
Base64 encode ratio (CN1/native) 1.649x (64.9% slower)
Base64 native decode 504.000 ms
Base64 CN1 decode 1047.000 ms
Base64 decode ratio (CN1/native) 2.077x (107.7% slower)
Base64 SIMD encode 477.000 ms
Base64 encode ratio (SIMD/native) 0.639x (36.1% faster)
Base64 encode ratio (SIMD/CN1) 0.387x (61.3% faster)
Base64 SIMD decode 428.000 ms
Base64 decode ratio (SIMD/native) 0.849x (15.1% faster)
Base64 decode ratio (SIMD/CN1) 0.409x (59.1% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 62.000 ms
Image createMask (SIMD on) 9.000 ms
Image createMask ratio (SIMD on/off) 0.145x (85.5% faster)
Image applyMask (SIMD off) 147.000 ms
Image applyMask (SIMD on) 100.000 ms
Image applyMask ratio (SIMD on/off) 0.680x (32.0% faster)
Image modifyAlpha (SIMD off) 260.000 ms
Image modifyAlpha (SIMD on) 169.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.650x (35.0% faster)
Image modifyAlpha removeColor (SIMD off) 303.000 ms
Image modifyAlpha removeColor (SIMD on) 100.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.330x (67.0% faster)
Image PNG encode (SIMD off) 1286.000 ms
Image PNG encode (SIMD on) 1049.000 ms
Image PNG encode ratio (SIMD on/off) 0.816x (18.4% faster)
Image JPEG encode 717.000 ms

@shai-almog

shai-almog commented May 22, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 90000 ms
Simulator Boot (Run) 1000 ms
App Install 13000 ms
App Launch 42000 ms
Test Execution 1502000 ms

@github-actions

github-actions Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 124 screenshots: 124 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

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

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 627.000 ms
Base64 CN1 encode 1212.000 ms
Base64 encode ratio (CN1/native) 1.933x (93.3% slower)
Base64 native decode 369.000 ms
Base64 CN1 decode 870.000 ms
Base64 decode ratio (CN1/native) 2.358x (135.8% slower)
Base64 SIMD encode 387.000 ms
Base64 encode ratio (SIMD/native) 0.617x (38.3% faster)
Base64 encode ratio (SIMD/CN1) 0.319x (68.1% faster)
Base64 SIMD decode 373.000 ms
Base64 decode ratio (SIMD/native) 1.011x (1.1% slower)
Base64 decode ratio (SIMD/CN1) 0.429x (57.1% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 57.000 ms
Image createMask (SIMD on) 10.000 ms
Image createMask ratio (SIMD on/off) 0.175x (82.5% faster)
Image applyMask (SIMD off) 146.000 ms
Image applyMask (SIMD on) 63.000 ms
Image applyMask ratio (SIMD on/off) 0.432x (56.8% faster)
Image modifyAlpha (SIMD off) 172.000 ms
Image modifyAlpha (SIMD on) 78.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.453x (54.7% faster)
Image modifyAlpha removeColor (SIMD off) 156.000 ms
Image modifyAlpha removeColor (SIMD on) 79.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.506x (49.4% faster)
Image PNG encode (SIMD off) 988.000 ms
Image PNG encode (SIMD on) 809.000 ms
Image PNG encode ratio (SIMD on/off) 0.819x (18.1% faster)
Image JPEG encode 430.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