Skip to content

Fix cn1:build on Maven 3.9+ (drop @Execute fork) + retire legacy Windows UWP/C# port#5267

Merged
liannacasper merged 3 commits into
masterfrom
fix-build-goal-double-package
Jun 21, 2026
Merged

Fix cn1:build on Maven 3.9+ (drop @Execute fork) + retire legacy Windows UWP/C# port#5267
liannacasper merged 3 commits into
masterfrom
fix-build-goal-double-package

Conversation

@shai-almog

@shai-almog shai-almog commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator

1. cn1:build double-package abort on Maven 3.9+

A freshly generated app fails every cn1:build target on Maven 3.9+:

maven-jar-plugin:3.4.1:jar: You have to use a classifier to attach supplemental artifacts to the project instead of replacing them.

CN1BuildMojo declared @Execute(phase = PACKAGE) and is bound to the package phase by every platform profile, so it forked a second package lifecycle. The empty per-module jar then gets attached twice and Maven 3.9 aborts. The fork was redundant (mvn package already runs package first). Fix: drop @Execute — package runs once, no double-attach.

Also fixes a latent bug found while verifying every target: getCN1ProjectDir() omitted "linux" from its platform list, so linux-device couldn't find common/codenameone_settings.properties. Added "linux".

2. Retire the legacy Windows UWP/C# port

The old Windows device port was UWP/C#. The only supported Windows targets are now win32 (native, ParparVM → C, like Linux) and windows-desktop (JavaSE). This removes the C# garbage and makes the win module a C target:

  • StubGenerator: no more .cs native-interface stubs (drop generateCSFile/javaTypeToCSharpType + the win-module C# detection). Native C stubs (win/src/main/c, like linux) unchanged.
  • Archetypes (app + cn1lib): the win module fileSet is C (src/main/c, *.c/*.h) instead of C# (src/main/csharp, *.cs), mirroring linux; csharp source dirs removed.
  • GenerateAppProjectMojo / GenerateCn1libProjectMojo / Cn1libMojo: copy win native sources from src/main/c instead of src/main/csharp.
  • Delete Ports/WinPhone7 (legacy Windows Phone / Silverlight C#, 36 files; confirmed unreferenced).
  • Cleaned stale "UWP"/C# wording in build.sh/build.bat, nb-configuration, .vscode, mvnconfig.toml, the common-pom profile (uwpwin), README, and the post-generate groovy comments.

windows-device now sends a win32 build to the server (cloud), mirroring linux-device, instead of being classified local-only. The local clang-cl cross-compile stays as local-windows-device, and windows-source still generates a local project. The buildxml-template windows-device target dropped certificate/certPassword: the build client pairs certificate with provisioningProfile (the iOS model) which Windows has no equivalent for, so a cert alone failed with "attribute provisioningProfile is required". Cloud win32 builds submit unsigned (like linux-device).

Verification

Every build target was exercised end-to-end against a freshly generated app with fake certs:

Target Result
ios-device, ios-device-release, mac-os-x-native departed ✅
mac-os-x-desktop, windows-desktop, javascript departed ✅
android-device, linux-device, windows-device (→ win32) departed ✅
jar, ios-source, android-source built locally ✅

Plus: plugin compiles, StubGeneratorTest passes, a freshly generated app has zero csharp/.cs/uwp references, and the new offline @Execute regression test (cn1app-desktop-build-test.sh, wired into all.sh) passes — it asserts the package phase runs exactly once with no double-attach.

Out of scope / follow-ups

  • Inert C# remnants remain in Executor.java (a .cs entry in two extension allowlists + a dead Silverlight mime type), deep in the cloud build-client; left untouched as they don't affect behavior and editing the client is risky.
  • Authenticode signing of cloud win32 builds needs build-client support (local-windows-device still honours codename1.windows.signing.*).

🤖 Generated with Claude Code

…fork

The CN1 `build` goal declared @execute(phase=package) AND is bound to the
package phase by every platform profile, so invoking it forked a second
package lifecycle. The per-platform modules (javase/ios/android/win/linux)
carry no classes of their own -- the app code lives in `common` -- so their
default jar is empty. On Maven 3.9+ the forked run inherits the already
attached empty main artifact and maven-jar-plugin aborts with "You have to
use a classifier to attach supplemental artifacts...". This broke every
build target (desktop, device, source) for freshly generated apps.

The fork was redundant: `mvn package` (the only supported invocation) runs
package before the build goal anyway. Removing @execute makes package run
once, with no double-attach.

Also fixes a latent bug surfaced while verifying every build target: the
linux module could not locate common/codenameone_settings.properties because
getCN1ProjectDir() omitted "linux" from its platform fast-path list, so
linux-device failed before departure. Added "linux" to the list.

Verified all targets after the change (fake certs): ios-device,
ios-device-release, mac-os-x-native, mac-os-x-desktop, windows-desktop,
javascript, android-device and linux-device all depart to the build server;
jar, ios-source and android-source build locally. windows-device (local
native cross-compile) runs the full lifecycle and only stops at the missing
xwin Windows SDK, as expected on a non-Windows host.

Adds an offline integration test (cn1app-desktop-build-test.sh) that
exercises the desktop build lifecycle via the bundled Maven 3.9 wrapper and
asserts the package phase runs exactly once with no double-attach.

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

shai-almog commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 129 screenshots: 129 matched.

Native Android coverage

  • 📊 Line coverage: 14.25% (8686/60957 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 11.54% (42779/370723), branch 5.10% (1779/34877), complexity 6.10% (2038/33422), method 10.55% (1648/15620), class 17.15% (378/2204)
    • 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: 14.25% (8686/60957 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 11.54% (42779/370723), branch 5.10% (1779/34877), complexity 6.10% (2038/33422), method 10.55% (1648/15620), class 17.15% (378/2204)
    • 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
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 196ms / native 177ms = 1.1x speedup
SIMD float-mul (64K x300) java 156ms / native 78ms = 2.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 215.000 ms
Base64 CN1 decode 230.000 ms
Base64 native encode 858.000 ms
Base64 encode ratio (CN1/native) 0.251x (74.9% faster)
Base64 native decode 834.000 ms
Base64 decode ratio (CN1/native) 0.276x (72.4% faster)
Image encode benchmark status skipped (SIMD unsupported)

@github-actions

github-actions Bot commented Jun 21, 2026

Copy link
Copy Markdown
Contributor

✅ 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.

@shai-almog

shai-almog commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

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

The old Windows device port was UWP/C#. It is retired: the only supported
Windows targets are now win32 (native, ParparVM -> C, like the Linux target)
and windows-desktop (JavaSE). This removes the C# garbage and makes the win
module a C target.

 - StubGenerator: stop emitting C# (.cs) native-interface stubs; drop
   generateCSFile/javaTypeToCSharpType and the win-module C# detection. Native
   C stubs (win/src/main/c, like linux) are unchanged.
 - Archetypes (app + cn1lib): the win module fileSet is C (src/main/c, *.c/*.h)
   instead of C# (src/main/csharp, *.cs), mirroring linux; remove the csharp
   source dirs.
 - GenerateAppProjectMojo / GenerateCn1libProjectMojo / Cn1libMojo: copy win
   native sources from src/main/c (*.c/*.h) instead of src/main/csharp.
 - Delete Ports/WinPhone7 (legacy Windows Phone / Silverlight C# port, 36
   files); confirmed unreferenced by the build.
 - Clean the stale "UWP"/C# wording in build.sh/build.bat, nb-configuration,
   .vscode, mvnconfig, common pom profile (uwp -> win), README and the
   archetype post-generate groovy comments.

windows-device now sends a "win32" build to the server (cloud), mirroring
linux-device, instead of being treated as a local-only native build. The
local clang-cl cross-compile remains available as local-windows-device, and
windows-source still generates a local project. The buildxml-template
windows-device target dropped the certificate/certPassword attributes: the
build client pairs certificate with provisioningProfile (the iOS model) which
Windows has no equivalent for, so passing a cert alone failed with "attribute
provisioningProfile is required". Cloud win32 builds submit unsigned (matching
linux-device); Authenticode signing of cloud builds is a separate follow-up,
and local-windows-device still honours codename1.windows.signing.*.

Verified end to end: plugin compiles, StubGeneratorTest passes, a freshly
generated app has zero csharp/.cs/uwp references, windows-device departs to
the server as win32, and the @execute double-package regression test still
passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shai-almog shai-almog changed the title Fix cn1:build double-package abort on Maven 3.9+ (drop @Execute fork) Fix cn1:build on Maven 3.9+ (drop @Execute fork) + retire legacy Windows UWP/C# port Jun 21, 2026
@shai-almog

shai-almog commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 210 screenshots: 210 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

@shai-almog

shai-almog commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 64000 ms
Simulator Boot (Run) 1000 ms
App Install 9000 ms
App Launch 13000 ms
Test Execution 306000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 209ms / native 7ms = 29.8x speedup
SIMD float-mul (64K x300) java 186ms / native 6ms = 31.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 451.000 ms
Base64 CN1 decode 675.000 ms
Base64 native encode 1010.000 ms
Base64 encode ratio (CN1/native) 0.447x (55.3% faster)
Base64 native decode 461.000 ms
Base64 decode ratio (CN1/native) 1.464x (46.4% slower)
Base64 SIMD encode 92.000 ms
Base64 encode ratio (SIMD/CN1) 0.204x (79.6% faster)
Base64 SIMD decode 59.000 ms
Base64 decode ratio (SIMD/CN1) 0.087x (91.3% faster)
Base64 encode ratio (SIMD/native) 0.091x (90.9% faster)
Base64 decode ratio (SIMD/native) 0.128x (87.2% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 20.000 ms
Image createMask (SIMD on) 3.000 ms
Image createMask ratio (SIMD on/off) 0.150x (85.0% faster)
Image applyMask (SIMD off) 94.000 ms
Image applyMask (SIMD on) 121.000 ms
Image applyMask ratio (SIMD on/off) 1.287x (28.7% slower)
Image modifyAlpha (SIMD off) 427.000 ms
Image modifyAlpha (SIMD on) 82.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.192x (80.8% faster)
Image modifyAlpha removeColor (SIMD off) 104.000 ms
Image modifyAlpha removeColor (SIMD on) 213.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 2.048x (104.8% slower)

@shai-almog

shai-almog commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 57ms / native 13ms = 4.3x speedup
SIMD float-mul (64K x300) java 51ms / native 3ms = 17.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 271.000 ms
Base64 CN1 decode 183.000 ms
Base64 native encode 586.000 ms
Base64 encode ratio (CN1/native) 0.462x (53.8% faster)
Base64 native decode 345.000 ms
Base64 decode ratio (CN1/native) 0.530x (47.0% faster)
Base64 SIMD encode 54.000 ms
Base64 encode ratio (SIMD/CN1) 0.199x (80.1% faster)
Base64 SIMD decode 46.000 ms
Base64 decode ratio (SIMD/CN1) 0.251x (74.9% faster)
Base64 encode ratio (SIMD/native) 0.092x (90.8% faster)
Base64 decode ratio (SIMD/native) 0.133x (86.7% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 17.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.118x (88.2% faster)
Image applyMask (SIMD off) 60.000 ms
Image applyMask (SIMD on) 33.000 ms
Image applyMask ratio (SIMD on/off) 0.550x (45.0% faster)
Image modifyAlpha (SIMD off) 55.000 ms
Image modifyAlpha (SIMD on) 39.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.709x (29.1% faster)
Image modifyAlpha removeColor (SIMD off) 66.000 ms
Image modifyAlpha removeColor (SIMD on) 55.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.833x (16.7% faster)

@shai-almog

shai-almog commented Jun 21, 2026

Copy link
Copy Markdown
Collaborator Author

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 66000 ms
Simulator Boot (Run) 1000 ms
App Install 11000 ms
App Launch 3000 ms
Test Execution 242000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 88ms / native 3ms = 29.3x speedup
SIMD float-mul (64K x300) java 59ms / native 5ms = 11.8x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 366.000 ms
Base64 CN1 decode 196.000 ms
Base64 native encode 400.000 ms
Base64 encode ratio (CN1/native) 0.915x (8.5% faster)
Base64 native decode 256.000 ms
Base64 decode ratio (CN1/native) 0.766x (23.4% faster)
Base64 SIMD encode 55.000 ms
Base64 encode ratio (SIMD/CN1) 0.150x (85.0% faster)
Base64 SIMD decode 47.000 ms
Base64 decode ratio (SIMD/CN1) 0.240x (76.0% faster)
Base64 encode ratio (SIMD/native) 0.138x (86.3% faster)
Base64 decode ratio (SIMD/native) 0.184x (81.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 16.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.125x (87.5% faster)
Image applyMask (SIMD off) 49.000 ms
Image applyMask (SIMD on) 52.000 ms
Image applyMask ratio (SIMD on/off) 1.061x (6.1% slower)
Image modifyAlpha (SIMD off) 52.000 ms
Image modifyAlpha (SIMD on) 30.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.577x (42.3% faster)
Image modifyAlpha removeColor (SIMD off) 59.000 ms
Image modifyAlpha removeColor (SIMD on) 27.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.458x (54.2% faster)

The build-linux-jdk8 CI job failed: native-interfaces.sh still asserted that
migrating a legacy project produces a C# stub at
win/src/main/csharp/.../HelloNativeImpl.cs. With the UWP/C# port retired, the
win module is a native C target and that file is no longer produced.

 - GenerateAppProjectMojo / GenerateCn1libProjectMojo: the migration's win
   "resources" copy now also excludes *.cs, so a legacy project's C# sources
   are not dragged into the migrated win module (previously they would have
   landed in win/src/main/resources).
 - native-interfaces.sh: replace the "win C# impl present" check with an
   assertion that NO .cs is carried into the win module. Guarded on the win
   dir existing, since the archetype post-generate script strips the win
   module for Java 17 projects (kept for Java 8).

Verified on JDK 8 (the CI runner's level): migrating cn1-native-interface-tests
yields a win module with no .cs, and the assertion passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@liannacasper liannacasper merged commit 92ff47f into master Jun 21, 2026
29 checks passed
@liannacasper liannacasper deleted the fix-build-goal-double-package branch June 21, 2026 12:19
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.

2 participants