Skip to content

Inline cn1app/cn1lib archetypes; bring to initializr parity#4953

Merged
shai-almog merged 2 commits into
masterfrom
feat/inline-archetypes
May 15, 2026
Merged

Inline cn1app/cn1lib archetypes; bring to initializr parity#4953
shai-almog merged 2 commits into
masterfrom
feat/inline-archetypes

Conversation

@shai-almog
Copy link
Copy Markdown
Collaborator

Summary

  • Moved cn1app-archetype and cn1lib-archetype from shannah/cn1-maven-archetypes into this repo as Maven modules under maven/. They now share the main reactor's parent pom, central-publishing config, sign-artifacts profile, and version policy.
  • Rewired CI (release-on-maven-central.yml, archetype-smoke.yml, ant.yml) and scripts/setup-workspace.sh to use the in-tree archetypes — removed the git clone https://github.com/shannah/cn1-maven-archetypes step and the inline sed hack that injected the maven-resources-plugin pin at deploy time. The pin is now a real <pluginManagement> entry in each archetype pom (3.3.1, keeps the Java 17 / Maven 4-only 4.0.0-beta-1 out of the JDK 8 release runner).
  • Updated the templates so generated projects match what start.codenameone.com currently produces — Java 17 defaults under JDK 17+, Codename One authoring skill bundled for Java 17 apps, Windows / UWP module dropped for Java 17, plus all the universal initializr-side cleanups (hardenPlatformModulePomAgainstDoubleJarAttach, normalizeJavasePom, normalizeIntellijMiscXml, applySimulatorJvmExportToIdeaWorkspace).
  • Modernized cn1lib-archetype (was on the pre-javaVersion=auto scaffold with cn1Version=7.0.26): added cn1PluginVersion and javaVersion=auto required properties, velocity-templated ${javaVersion} into all four poms (root/common/javase/lib) and the library required-properties file.

How it works

Knob Where Behaviour
javaVersion=auto (default) archetype-metadata.xml requiredProperty Velocity writes auto into the templates; archetype-post-generate.groovy resolves it to 17 when running on JDK >= 17 and 8 otherwise.
-DjavaVersion=8 / -DjavaVersion=17 explicit mvn archetype:generate flag Velocity substitutes the value directly; the groovy reads it back so the win/skill conditionals branch correctly.
win/ drop post-generate groovy Java 17 only: delete the win/ source tree + strip the <profile><id>win</id></profile> block from cn1app's root pom or the <module>win</module> line from cn1lib's root pom.
Claude Code skill bundle cn1app-archetype/pom.xml <resource> entry Build-time copy from scripts/initializr/common/src/main/resources/skill/** into archetype-resources/.claude/skills/codename-one/**. Skill files stay single-source-of-truth in the initializr; the post-generate groovy strips them when resolved Java version is 8. Libraries don't ship the skill.
IntelliJ languageLevel post-generate groovy Rewritten to JDK_17 or JDK_1_8. project-jdk-name / project-jdk-type are stripped in the template directly.
jar-plugin phase=none on android/ios/javascript poms baked into cn1app templates Universal — prevents the double JAR attach the initializr's hardenPlatformModulePomAgainstDoubleJarAttach was inserting at generation time.
Top-level provided-scope codenameone-core + codenameone-javase in cn1app's javase/pom.xml baked into the template Universal — removed. The profile-scoped desktop_build provided deps stay (they're legitimately conditional).
--add-exports=java.desktop/com.apple.eawt=ALL-UNNAMED in .idea/workspace.xml Run-in-Simulator vmOptions baked into the cn1app template Universal — matches initializr's applySimulatorJvmExportToIdeaWorkspace.

Test plan

Verified locally with 16 mvn archetype:generate runs (cn1app × cn1lib × JDK 17 / JDK 8 × auto / explicit override):

cn1app:

Scenario win/ .claude/skills/ <source> settings win profile languageLevel top-level provided deps in javase
JDK17 + auto dropped 18 files 17 17 stripped JDK_17 0
JDK17 + =8 kept dropped 8 8 kept JDK_1_8 0
JDK8 + auto kept dropped 8 8 kept JDK_1_8 0
JDK8 + =17 dropped 18 files 17 17 stripped JDK_17 0

cn1lib:

Scenario win/ <module>win> <source> (all 4 poms) codename1.arg.java.version cn1.plugin.version languageLevel
JDK17 + auto dropped absent 17 17 8.0-SNAPSHOT JDK_17
JDK17 + =8 kept present 8 8 8.0-SNAPSHOT JDK_1_8
JDK8 + auto kept present 8 8 8.0-SNAPSHOT JDK_1_8
JDK8 + =17 dropped absent 17 17 8.0-SNAPSHOT JDK_17

CI checklist:

  • Java CI (ant.yml) builds the new modules and refreshes the archetype catalog
  • Archetype simulator smoke resolves the in-tree archetype (no external zip fetch)
  • Release on Maven Central workflow change tested on next tag — single mvn deploy should publish core + plugin + both archetypes in one pass; the Central-poll safety net still covers central-publishing-maven-plugin false-positive failures

Notes for reviewers

  • The skill is bundled by adding a second <resource> entry in maven/cn1app-archetype/pom.xml that targets archetype-resources/.claude/skills/codename-one. The skill markdown lives only under scripts/initializr/common/src/main/resources/skill/**; the archetype JAR embeds a copy at build time. No file duplication in git.
  • The archetypes are part of the default reactor (not behind a profile). mvn install -Plocal-dev-javase builds them; release runs them with -Darchetype.test.skip=true -DskipTests because their ITs invoke the codenameone-maven-plugin against the SNAPSHOT version being released, which isn't on Central yet at deploy time.
  • cn1lib-archetype doesn't bundle the skill (libraries are libraries). It also doesn't need the hardenPlatformModulePomAgainstDoubleJarAttach or normalizeJavasePom transforms — its platform poms have a different shape (no codenameone-maven-plugin build invocation; antrun-based JAR build).

🤖 Generated with Claude Code

…zr parity

Move the cn1app-archetype and cn1lib-archetype modules in from
https://github.com/shannah/cn1-maven-archetypes so the main repo owns and
releases them alongside the framework. Update the templates so generated
projects match what start.codenameone.com currently produces, including
the Java 17 defaults and the Codename One authoring skill.

* maven/cn1app-archetype/ and maven/cn1lib-archetype/ added as Maven
  modules under maven/pom.xml. Parent switched to `codenameone` so they
  inherit central-publishing, sign-artifacts, and version policy from
  the main reactor. maven-resources-plugin pinned to 3.3.1 in both
  pom files (replaces the inline sed hack the release workflow used to
  inject at deploy time).

* CI rewired to the in-tree modules:
  - .github/workflows/release-on-maven-central.yml — collapsed from 6
    steps into 3 (single `mvn deploy` covers core + archetypes since
    they're one reactor; Central-poll safety net keeps protecting
    against central-publishing-maven-plugin false-positive failures).
  - .github/workflows/archetype-smoke.yml — drop the external-zip
    fetch, install the in-tree archetypes via the main build, then
    refresh the local archetype catalog.
  - .github/workflows/ant.yml — same cleanup.
  - scripts/setup-workspace.sh — replace the 35-line clone-and-install
    block with a 2-line catalog refresh.
  - maven/README.adoc + README.md — updated build docs.
  - maven/update-version.sh — also bump the embedded `<defaultValue>`s
    in archetype-metadata.xml and `cn1Version` / `cn1PluginVersion` in
    the IT archetype.properties fixtures (guards against missing files
    so cn1lib's basic-only fixtures don't break the loop).

* Java version handling matches the initializr exactly:
  - cn1app-archetype already shipped `javaVersion=auto` (resolves to 17
    on JDK >= 17, otherwise 8); cn1lib-archetype is brought up to the
    same scaffold.
  - Velocity templates `${javaVersion}` into common pom `<source>` /
    `<target>` and codenameone_settings.properties; the
    archetype-post-generate.groovy rewrites the literal "auto" to the
    resolved value after the maven-archetype-plugin's velocity pass.
  - `-DjavaVersion=8` and `-DjavaVersion=17` overrides still win and
    are read back by the groovy so the conditional transforms below
    branch correctly.

* Java-17-only transforms applied by the post-generate groovy (mirrors
  the initializr's per-template logic):
  - drop the `win/` UWP source tree (the legacy Windows / UWP cloud
    target is retired for Java 17 builds)
  - strip the `<profile><id>win</id></profile>` block from the cn1app
    root pom and the `<module>win</module>` line from the cn1lib root
    pom (different shapes — the lib archetype uses default modules
    rather than per-platform profiles)
  - set IntelliJ `languageLevel` to `JDK_17` (vs `JDK_1_8` on Java 8)
  - keep `.claude/skills/codename-one/**` for Java 17 projects, strip
    it for Java 8 (apps only — libraries don't ship the skill)

* Codename One authoring skill bundled into the cn1app-archetype JAR
  from `scripts/initializr/common/src/main/resources/skill/**` (the
  initializr's source of truth). The cn1app-archetype/pom.xml adds an
  extra `<resource>` entry that stages the skill files into
  `archetype-resources/.claude/skills/codename-one/` at build time, so
  the skill stays single-source-of-truth and doesn't get duplicated in
  git. `.claude/**` is added as a fileSet in archetype-metadata.xml so
  the maven-archetype-plugin actually extracts it.

* Universal (non-Java-17-specific) initializr improvements baked into
  the cn1app-archetype templates so generated projects no longer drift
  from initializr output:
  - `hardenPlatformModulePomAgainstDoubleJarAttach` parity: added the
    `maven-jar-plugin` 3.4.1 / default-jar phase=none block to
    android/ios/javascript pom.xml.
  - `normalizeJavasePom` parity: removed the top-level provided-scope
    `codenameone-core` and `codenameone-javase` dependencies from
    javase/pom.xml (the profile-scoped provided deps in
    `desktop_build` etc. stay — they're the legitimate ones).
  - `normalizeIntellijMiscXml` parity: stripped `project-jdk-name` and
    `project-jdk-type` from `.idea/misc.xml`; `languageLevel` is
    rewritten in the groovy as noted above.
  - `applySimulatorJvmExportToIdeaWorkspace` parity: pre-filled the
    `Run in Simulator` configuration's `vmOptions` with
    `--add-exports=java.desktop/com.apple.eawt=ALL-UNNAMED` in
    `.idea/workspace.xml`.
  The cn1lib-archetype's platform poms have a different shape (no
  codenameone-maven-plugin build invocation, antrun-based JAR build)
  so the JAR-attach and javase normalization don't apply; the misc.xml
  cleanup does.

* cn1lib-archetype modernization (separately required for parity):
  - cn1Version defaultValue 7.0.26 → 8.0-SNAPSHOT.
  - Added `cn1PluginVersion` requiredProperty (previously shared a
    single `cn1Version` for both — wrong when plugin and framework
    diverge during release transitions).
  - Added `javaVersion=auto` requiredProperty.
  - ${javaVersion} velocity placeholders in root pom, common pom,
    javase pom, lib pom, javadoc-plugin <source>, and
    `codenameone_library_required.properties`.

Verified locally with 16 archetype:generate runs (cn1app × cn1lib ×
JDK17/JDK8 × auto/explicit-override): win/ behavior correct,
.claude/skills/ kept only for Java 17 apps, languageLevel matches the
resolved JDK, project-jdk-name/-type absent, jar-plugin phase=none
present in platform poms, top-level provided-scope deps stripped from
javase pom, cn1Version and cn1PluginVersion separate.

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

github-actions Bot commented May 15, 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.

Two regressions in the previous commit:

* tests/core.sh failed with `cannot access com.codename1.system.NativeInterface`
  during cn1lib stub generation. The Phase 3b strip of the top-level
  provided-scope codenameone-core / codenameone-javase from the generated
  javase/pom.xml was too aggressive — those deps are how
  `mvn package -Dcodename1.platform=javase` (the invocation tests/core.sh
  uses) gets the simulator runtime on the compile classpath. None of the
  profiles that supply them as compile-scope auto-activates on just the
  codename1.platform property, so removing the top-level deps broke
  standalone javase builds. The initializr's normalizeJavasePom must work
  on a different invocation path; for the archetype we restore the
  historical deps and accept the divergence.

* scripts/setup-workspace.sh and tests/all.sh ran `mvn install` without
  -Darchetype.test.skip=true and the maven-archetype-plugin
  integration-test phase fired against both archetypes. The ITs generate
  sub-projects pinned to cn1Version=8.0-SNAPSHOT and invoke the
  codenameone-maven-plugin against them — but that plugin is built in
  this same reactor and isn't on Central yet, so the nested mvn fails.
  Set <archetype.test.skip>true</archetype.test.skip> as a default
  property in both archetype poms; the dedicated archetype-smoke
  workflow (and ad-hoc invocations) can opt back in with
  -Darchetype.test.skip=false.

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

shai-almog commented May 15, 2026

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

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 15, 2026

Compared 107 screenshots: 107 matched.

Native Android coverage

  • 📊 Line coverage: 11.54% (6388/55367 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 9.19% (31713/344940), branch 3.97% (1300/32776), complexity 5.08% (1597/31431), method 8.86% (1303/14708), class 14.90% (297/1993)
    • 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: 11.54% (6388/55367 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 9.19% (31713/344940), branch 3.97% (1300/32776), complexity 5.08% (1597/31431), method 8.86% (1303/14708), class 14.90% (297/1993)
    • 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 1093.000 ms
Base64 CN1 encode 230.000 ms
Base64 encode ratio (CN1/native) 0.210x (79.0% faster)
Base64 native decode 812.000 ms
Base64 CN1 decode 392.000 ms
Base64 decode ratio (CN1/native) 0.483x (51.7% faster)
Image encode benchmark status skipped (SIMD unsupported)

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 15, 2026

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 104000 ms
Simulator Boot (Run) 1000 ms
App Install 17000 ms
App Launch 6000 ms
Test Execution 290000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1370.000 ms
Base64 CN1 encode 1405.000 ms
Base64 encode ratio (CN1/native) 1.026x (2.6% slower)
Base64 native decode 773.000 ms
Base64 CN1 decode 935.000 ms
Base64 decode ratio (CN1/native) 1.210x (21.0% slower)
Base64 SIMD encode 414.000 ms
Base64 encode ratio (SIMD/native) 0.302x (69.8% faster)
Base64 encode ratio (SIMD/CN1) 0.295x (70.5% faster)
Base64 SIMD decode 427.000 ms
Base64 decode ratio (SIMD/native) 0.552x (44.8% faster)
Base64 decode ratio (SIMD/CN1) 0.457x (54.3% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 82.000 ms
Image createMask (SIMD on) 23.000 ms
Image createMask ratio (SIMD on/off) 0.280x (72.0% faster)
Image applyMask (SIMD off) 234.000 ms
Image applyMask (SIMD on) 82.000 ms
Image applyMask ratio (SIMD on/off) 0.350x (65.0% faster)
Image modifyAlpha (SIMD off) 182.000 ms
Image modifyAlpha (SIMD on) 88.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.484x (51.6% faster)
Image modifyAlpha removeColor (SIMD off) 248.000 ms
Image modifyAlpha removeColor (SIMD on) 222.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.895x (10.5% faster)
Image PNG encode (SIMD off) 1658.000 ms
Image PNG encode (SIMD on) 1306.000 ms
Image PNG encode ratio (SIMD on/off) 0.788x (21.2% faster)
Image JPEG encode 637.000 ms

@shai-almog
Copy link
Copy Markdown
Collaborator Author

shai-almog commented May 15, 2026

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

Benchmark Results

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

Build and Run Timing

Metric Duration
Simulator Boot 95000 ms
Simulator Boot (Run) 0 ms
App Install 13000 ms
App Launch 6000 ms
Test Execution 284000 ms

Detailed Performance Metrics

Metric Duration
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 native encode 1933.000 ms
Base64 CN1 encode 1336.000 ms
Base64 encode ratio (CN1/native) 0.691x (30.9% faster)
Base64 native decode 1368.000 ms
Base64 CN1 decode 1330.000 ms
Base64 decode ratio (CN1/native) 0.972x (2.8% faster)
Base64 SIMD encode 556.000 ms
Base64 encode ratio (SIMD/native) 0.288x (71.2% faster)
Base64 encode ratio (SIMD/CN1) 0.416x (58.4% faster)
Base64 SIMD decode 492.000 ms
Base64 decode ratio (SIMD/native) 0.360x (64.0% faster)
Base64 decode ratio (SIMD/CN1) 0.370x (63.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 99.000 ms
Image createMask (SIMD on) 28.000 ms
Image createMask ratio (SIMD on/off) 0.283x (71.7% faster)
Image applyMask (SIMD off) 119.000 ms
Image applyMask (SIMD on) 82.000 ms
Image applyMask ratio (SIMD on/off) 0.689x (31.1% faster)
Image modifyAlpha (SIMD off) 210.000 ms
Image modifyAlpha (SIMD on) 51.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.243x (75.7% faster)
Image modifyAlpha removeColor (SIMD off) 197.000 ms
Image modifyAlpha removeColor (SIMD on) 119.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.604x (39.6% faster)
Image PNG encode (SIMD off) 1165.000 ms
Image PNG encode (SIMD on) 813.000 ms
Image PNG encode ratio (SIMD on/off) 0.698x (30.2% faster)
Image JPEG encode 475.000 ms

@shai-almog shai-almog merged commit fa57bb2 into master May 15, 2026
20 checks passed
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