Repository navigation
Add shared Process API for desktop and backend - #6010
Conversation
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d396e5faba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
|
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows x64Runner CPU: AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2f3785fbf7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Cloudflare Preview
|
|
Compared 170 screenshots: 170 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
|
Compared 206 screenshots: 206 matched. |
|
Compared 185 screenshots: 185 matched. ParparVM vs HotSpot (JDK 25): Linux x64Runner CPU: INTEL(R) XEON(R) PLATINUM 8573C (baseline 1 performance regression:
Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
A change that moves performance ON PURPOSE records the new baseline in Result: performance regression |
|
Compared 185 screenshots: 185 matched. ParparVM vs HotSpot (JDK 25): Linux arm64Runner CPU: Neoverse-N2 (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows arm64Runner CPU: ARMv8 (64-bit) Family 8 Model D49 Revision 0, MICROSOFT CORPORATION (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
|
Compared 12 screenshots: 12 matched. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 26bd8cc408
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d53d55000e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. 🚀 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Compared 168 screenshots: 168 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
|
Compared 167 screenshots: 167 matched. Benchmark Results
Detailed Performance Metrics
|
|
Compared 236 screenshots: 236 matched. |
|
Compared 163 screenshots: 163 matched. |
|
Compared 168 screenshots: 168 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
|
Compared 179 screenshots: 179 matched. Benchmark Results
Detailed Performance Metrics
ParparVM vs HotSpot (JDK 25): macOS arm64Runner CPU: Apple M1 (Virtual) (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
#6010 (merged) recorded the same translator memory improvement on that runner from the same baseline (0.467x; ours 0.452x). Master's row stands. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…erlay after #6010 A driver's balance counts only fares that were paid for. An account in the middle of a ride cannot be blocked, and a live connection opening while a block or a role change commits reads the account again once registered. #6010 rebaselined two of the rows this overlay moved, from the same values. Windows arm64 translator RAM is left to its 0.513, which covers this change's runs; Windows x64 hello RAM now chains from #6010's 0.828 to this change's two runs, 1.154. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…emplate (#5984) * Wayline: a full-stack ride-hailing sample, its CI and an Initializr template scripts/wayline is one Maven project in one language: a Codename One app styled with CSS, and a Codename One Backend server. The role the server gives an account decides what it opens on: a rider's map, a driver's screen or an administrator's console, on a phone, on the desktop and hosted by the server itself in a browser. The server keeps its data in ORM entities behind repositories, with transactional services and Flyway-style migrations, and runs on SQLite, PostgreSQL, MySQL and MariaDB. It has sign-in through the built-in authorization server, phone verification, driver applications, matching, payments (simulated or Stripe), statistics and a live WebSocket channel. The app reports usage to Codename One analytics after consent. Tested like hellocodenameone: server tests on the JVM and as a native binary, simulator end-to-end tests with screenshots on phone and desktop, a headless-browser check of the hosted app, and a generated-project check (.github/workflows/wayline.yml). The Initializr offers it as a template, kept in step by scripts/sync-initializr-wayline.py, and the developer guide gains a user's and an implementor's chapter. Framework changes the sample needed or uncovered: - cn1:backend-webapp and the Gradle backendWebApp task build the app for the browser and let the server host it. - Shared-module contracts in an app reactor; ResponseStatusException; ConcurrencyFailureException for write conflicts and deadlocks, which MariaDB's snapshot isolation reports where other engines change no row. - Build-time weaving no longer exposes private types in generated code. - ParparVM: a receiver that escapes is no longer retired at frame exit. - Vector maps: tile queue with stand-ins, label collision grid, halos, road hierarchy, kinetic pan, zoom about the cursor. - JavaScript port: geolocation no longer blocks the EDT waiting for a position that never arrives; asynchronous XHR; coalesced accessibility refresh; released text layers. - JavaSE test runner retires each test's threads and listeners, and a killed test process is reported as such. - GridLayout preferred height counts implicit rows; GeneralPath grows geometrically; JavaSE mixed-font width uses advances. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: review fixes, and two builds this branch broke Gradle: a project in Java and Kotlin failed in compileJava with two copies of one generated mapper. Kotlin's pass compiles the Java it has not seen yet only to resolve types, and that output was read as a dependency's, so a @Mapped Java class was mapped by both passes. AnnotationProcessing now takes the class directories that are the module's own and offers nothing out of them. wayline.yml: the simulator job runs in the pr-ci-container image and the workflow could not pull it without packages: read. Sample server: - A refund is refused while a tip on the ride is still being charged, so a tip can no longer land on a ride that was refunded without it. - A ride left completed with its payment pending is settled by a scheduled pass; settling is safe to repeat. - The card limit is enforced where a card is saved, not only where a setup starts. - Two registrations racing for one e-mail answer 409, not a server error. - Changing an account's roles closes the live channel it has open. Sample client: tokens are stored under a name made from the server's address, and cleared when the address changes, so one server's tokens are never sent to another. Maps: a map removed while gliding is taken off the form that animates it, and a failed tile is asked for again when its delay runs out, without waiting for something else to repaint the map. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reseed the Linux and Windows map baselines The vector map engine draws differently on this branch, so the four map screenshots are reseeded from this branch's CI captures. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Playground demo test: read a sample's bounds once the overlay has caught up The JavaScript port on this branch brings the ARIA overlay up to date after the screen goes quiet rather than on every change, so a bounds read 150ms after a wheel event could still describe the list part way through the scroll, and the click then selected a different sample. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Build an application with no Maven wrapper for iOS, and reseed two iOS 27 map baselines build-ios-app.sh checked that MAVEN_HOME holds a Maven and then ran ./mvnw regardless, so the Wayline iOS job failed with 'No such file or directory'. It now uses the application's wrapper where there is one and that Maven otherwise, as build-android-app.sh does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Initializr: offer the full-stack template from 7.0.277 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Lay a road name out by its letters' share of the drawn name, and reseed the macOS map baselines A name that follows a bend is drawn a straight stretch at a time. The stretches were laid out by each letter's width measured on its own, which a font with kerning sets wider than the same letters drawn together, so on iOS and Mac Catalyst a name read "Bro adway" where the road turned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: second round of review fixes - A charge that fails without the processor saying whether it took the money leaves the ride pending and is asked for again under the same key; only a refused card is a failed payment. The same for a tip, which stays on the ride and can be sent again with the same amount. - A rider's two requests and two rides choosing one driver now take turns on the rider's and the driver's row, so neither ends in two rides. - The limit on guesses at a phone code is applied by the statement that counts the guess. - The driver role is not withdrawn from a driver who is on a ride. - A reconnect timer left over from before the live channel was restarted no longer opens a second connection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: give the generated template's theme compile a display, and two prose fixes The template check built the generated app with no display, and the theme compiler opens a window; it now takes a virtual display from xvfb-run on a Linux machine without one, as server.sh does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Reseed the macOS map baselines for road names laid out by drawn width Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Say what laying a road name out by drawn width does and does not fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Initializr: let the generated-project build test take as long as a cold build does, and one prose fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: build the theme without a display, as the compiler now does The CSS compiler no longer opens a window, so the virtual display the template check, server.sh and the web job arranged for it goes, along with the designer jar the simulator's pom passed along. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Rebaseline hello and translator RAM on Windows arm64 for the tightened retire proof Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: retryable refunds, retired addresses, admin races and five more review fixes - A refund the server claimed and never recorded is asked for again; the processor's refund is keyed by the charge, so a repeat is one refund. - A closed account's e-mail is retired (hash kept), since its rides stay filed under it and a re-registration would inherit them. - Role changes and blocks hold both profiles and re-read the acting admin, so two admins cannot remove each other at once. - A failed SMS send discards only its own code. - Closing an account asks for the password again. - /api/geo is rate limited. - Recent destinations belong to the account that chose them. - The location listener is removed when the last watcher leaves. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: serialize account races, keep sign-in addresses private, and nine more review fixes - Closing an account, removing a card, choosing the default card, keeping a first payment customer and sending a phone code hold the profile row, so each takes turns with a ride being asked for and with itself. - A guess at a phone code is claimed against the hash that was read. - A driver's status report holds the driver's row before reading it. - A card tip counts toward the balance once its charge is recorded. - A ride gives the rider's and the driver's usernames only to their owners and to an admin. - The app ignores profile answers that arrive after the session changed. - The staged web root is withheld only when the active profile, not any profile file, declares cn1.webapp.root. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline guide: say online minutes, as the prose gate asks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ParparVM perf: rebaseline hello peak RAM on Linux arm64 and Windows x64 for this change The tightened retire-early proof keeps more objects for the collector, so hello's peak RAM rises on every platform, as it already had on Windows arm64. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: earnings are the driver's share, one cash-out at a time, and four more review fixes The driving screen summed the fare, commission included, as earned. The period totals counted a card tip whose charge never came back. Two cash-outs at once could both be taken back. A date was accepted with a day its month does not have. The map's retry timer ignored a tile that failed while a longer wait was pending. The hosted-web job did not run for the JavaScript port's Java sources. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * vm-tests: runtime-library tests on two JDKs, a wider limit; Wayline: one Stripe customer per account The lock, file, stack-overflow, uncaught-exception and float-formatting tests ran once per JDK although none depends on which javac compiled them; they now run on the oldest and the newest. The job's limit goes from 120 to 150 minutes: passing runs were within a slow runner's variance of the old one. Creating a Stripe customer now carries an idempotency key, so two first cards started together do not leave a second customer behind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a changed password ends the other sign-ins, and seven more review fixes Changing a password removes the account's other grants, so a refresh token on a lost device stops working; closing an account removes them all. Saving or uploading to a driving application holds it against being handed in meanwhile. The map drops overzoomed pieces that left the view instead of drawing them all, and bounds the labels it keeps. The JavaScript port's storage shim no longer logs a prefix of what it stores. The bytecode check takes only the sibling modules the application ships, not test-scoped ones, and the stub goal deletes the stubs it no longer emits. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Map: compare waiting pieces by serial, not by reference; rebaseline Windows x64 translator time PMD forbids comparing references, and the piece waiting under a key is told from one it replaced by a serial number instead. The Windows x64 translator time is bimodal on its runner; its baseline is taken from two runs and now sits between the groups. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Rebaseline Linux arm64 translator RAM Two runs of the same code sit at 0.49 and 0.52 against 0.45, either side of the 15% tolerance; the cause is the one already recorded for the hello rows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: five review fixes around privacy, payments and settings A past ride no longer carries its driver's current position. Closing an account deletes the rider's record at the payment processor, and neither a card nor an account can be removed while a ride's charge is still being asked about. A different account signing in on a device no longer sees or saves the last account's home, work, contact and ride options, and a half of the account's values that never arrived is fetched again rather than overwritten. Two first saves of the settings take turns. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: unpaid fares stay out of payouts, no block mid-ride; perf overlay after #6010 A driver's balance counts only fares that were paid for. An account in the middle of a ride cannot be blocked, and a live connection opening while a block or a role change commits reads the account again once registered. #6010 rebaselined two of the rows this overlay moved, from the same values. Windows arm64 translator RAM is left to its 0.513, which covers this change's runs; Windows x64 hello RAM now chains from #6010's 0.828 to this change's two runs, 1.154. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: serialize password changes and approvals, refunds take tips back - Accounts.changePassword holds the profile before checking the old password, so two changes made together cannot both pass it. - Applications.approve holds the applicant's profile, as blocking does, so the rewrite of the sign-in row cannot undo a block that committed between. - A card tip counts toward the balance only while its ride is paid: a refund returns it with the fare. - The earnings screen's day/week/month totals count a fare only once paid, matching the balance; the trip still counts. - LocationManager sets the request before bindListener(), which every port reads it from (priority on iOS/Android, accuracy in the browser). - BackendWebApp.copy refuses a destination inside or around the staged app instead of copying it into itself or deleting its source. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: keep the previous SMS code good, stage/copy and watch-id fixes - PhoneVerification keeps the code before a resend good until it would have expired: SMS order is not guaranteed and the first code can arrive last. At most two live codes; using either uses both up. - BackendWebApp.stage refuses a bundle inside the output directory, which is emptied before the bundle is read. - The Gradle backendPackage up-to-date check compares the whole staged web app (names, lengths, times), not only index.html. - The browser geolocation shim answers -1 for "no watch" and clears a watch whose id is 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: accept vs block, code guess budget, payout and admin races; build freshness - Accepting an offer holds the driver's profile and re-checks the account is enabled, so a block cannot land between the guard and the accept. - The SMS code kept across a resend keeps its own remaining guesses. - Saving payout details holds the profile: the first save has no row. - Production admin bootstrap treats a concurrent instance's insert as done. - backendWebApp is never up to date: its bundle is not a snapshot input. - The bytecode compliance check counts checked sibling modules' classes when deciding whether its last result still holds. - MapView wheel zoom keeps its sign; WheelEvent's doc stated the wrong wheel direction for a positive deltaY, which the ports negate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: reconcile pending refunds, and hold rows for first writes - A refund Stripe answers pending (or requires_action) is recorded as REFUND_PENDING, not REFUNDED. Payments.settleRefunds asks the processor every minute until both the fare's and the tip's refunds succeed (REFUNDED) or either fails or is canceled (REFUND_FAILED, not retried). The tip's refund reference is kept in a new tip_refund_ref column. Receipts, the admin screens and the guides show both states; the simulated processor's 4000 0000 0000 7726 card refunds slowly. - A customer created at the processor while the account was being closed is deleted again instead of being kept for a missing user. - A driver's first state report and a driving application's submit hold the profile when there is no row of their own to hold yet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: drop a CSS compiler cache committed by mistake theme.css.checksums is the CSS CLI's incremental cache, left beside the stylesheet by a compile run by hand; it does not belong in the sample and made the Initializr template drift. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Perf overlay: the Intel Windows x64 runner's hello RAM and translator time The first run of this branch on the Intel Family 6 Model 207 runner, which the overlay had no rows for; the reason is recorded in the overlay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Perf overlay: bimodal Intel Windows hello RAM, arm64 stringBuilding time A second run on the Intel Windows x64 runner measured hello RAM at 0.71 against the 1.11 the first had given: the row is now the median of all ten rounds with the 0.35 memory tolerance Windows arm64 already uses. Linux arm64 stringBuilding time follows the frame-retire change, as the Intel Windows runner's does. Reasons are in the overlay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Open the test ComboBox popup on the EDT; bimodal AMD Windows hello RAM ComboBoxPopupTestSupport clicked the combo from a thread of its own while the @FormTest body pumped the EDT, so the popup was built and measured off the dispatch thread. ComboBoxPopupWidthTest failed on that race in CI on this branch and on desktop-compat-layer (80 against 64) and never alone. The AMD Windows x64 runner's hello RAM is bimodal like the Intel one's: 0.81 against the 1.154 recorded from two higher runs. Baseline the middle of the three run medians with the 0.35 tolerance the other runners carry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Perf overlay: macOS arm64 objectAllocation RAM Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Input validation: give every iOS step the budget of the XCUITest idle wait The iOS tap step timed out 0.45s before XCUITest synthesized the tap: the step is armed at READY, the driver was still launching, and its wait for the app to idle then took 31.6s. The same wait already cost the browser step its first focus tap, and keytype and browserkeytype have missed the same way, so every iOS step gets the 90s the browser step had. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * JavaAPI: java.net.URLEncoder and URLDecoder with the JDK's semantics Backend code is written against the JDK, and the compiled backend had no URLEncoder/URLDecoder at all. Pure Java, so both runtimes answer the same bytes; UrlCodecTest compares the JDK and ParparVM output directly. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ORM: persist private, package-private and protected entity fields Every non-static, non-transient field is persistent now, whatever its access (the JPA rule). The generated model is compiled against copies of the declaring classes with those fields made public, and OrmEnhancer then rewrites each GETFIELD/PUTFIELD in the generated classes into a call to a static accessor woven into the declaring class -- mapped superclasses, embeddables and dependency jars included. No reflection, so it works on ParparVM. Java transient now opts a field out like @DbTransient; a non-public final field without a mapping annotation is skipped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ORM: backend defaults table and column names to snake_case A table or column the entity does not name explicitly is now named the way Spring Boot's CamelCaseToUnderscoresNamingStrategy names it on the backend (RideEvent -> ride_event, fareCents -> fare_cents). The app keeps the field name, because shipped SQLite files were created with it. Explicit @Entity(table) and @Column(name) are used as written on both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Backend: inject @Repository interfaces as beans; Optional repository results An injection point whose type is a @Repository interface that no bean provides now receives the generated implementation, built once per interface from Repositories.create over the injected transaction Session, as Spring Data makes a repository a bean. It runs in the caller's @Transactional method and refuses outside one, the same contract as the injected Session. Repository methods may return Optional<T> for a single result (derived finds and declared @Query selects), answering Optional.empty() when there is no row. The snake-case naming test now ignores tables of entities other tests registered in the process-wide registry, which made it order dependent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ParparVM: translate a record's implicit equals, hashCode and toString javac writes each as an invokedynamic of java.lang.runtime.ObjectMethods, which the translator refused, so any record without hand-written overrides failed iOS (and every native) translation. The backend packager lowered them beforehand; an application's records, such as DTOs shared with a server, had nothing. The translator now replaces the call with a static helper doing what ObjectMethods builds, with JDK float/double bit semantics. RecordMethodsTest compares JDK and ParparVM output for a record with every primitive kind, a String, an enum, a nested record, a list, null components, NaN and -0.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Backend: records as JSON transfer objects The backend codecs read a class's fields through public access or JavaBeans accessors and built it with its no-arg constructor. A record has neither, so a record DTO in a shared @RestClient contract went over the wire as {} and could not be read at all. The codec now writes a record from its accessors and reads it into one local per component, building it through the canonical constructor; @JsonIgnore on a component passes its default. The legacy cn1.restServer codec moves public fields only, so it now refuses a record by name instead of transferring an empty object. RecordDtoTest drives a record contract (enum, nested record, List of records, List<String>, primitives, an ignored component) end to end: the client's generated mappers and RestClient implementation, the server's generated <Api>Server and controller, and a running backend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Backend packager: a Java 17 dependency passes over JDK_8_HOME A Java 8 backend module took JDK_8_HOME's javac for its native compile even when a dependency -- a shared contract module at release 17, so its transfer objects can be records -- was version 61 bytecode. JDK 8 cannot read that, so the compiled backend failed with "class file has wrong version 61.0" while the JVM build and tests passed. The legacy JDK 8 override now applies only when every dependency class is Java 8 too; module descriptors and META-INF entries, which Java 8 libraries commonly carry, do not count. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ORM repositories: Object[] rows from a declared JPQL @Query select A declared JPQL select may now return Object[], List<Object[]> or Optional<Object[]>, one array per row, as Spring Data returns a multi-column projection: select a.x, count(a) ... group by a.x, or several sums at once. Derived queries and native selects still refuse it -- a derived find answers entities, and a native select answers one scalar column. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: repositories, private entity fields and a RideState enum The backend's data access is now @Repository interfaces under wayline.repository, injected into the services, with no Session or SQL left in the sample: derived queries where the method name says it all, JPQL @Query for the rest, and @Modifying @Query statements that answer the number of rows they changed for every atomic claim (a ride move, an offer, a tip or refund claim, a guess at a phone code). A ride move's five shapes are five fixed statements, and the matcher's search is one fixed query with the product and preference filters applied in Java. Cross-entity cleanup is the AccountCleanup component over repositories. Entities keep their fields private behind getters and setters and map to snake_case columns; the migrations are renamed to match. RideStates' string constants become the RideState enum in the shared module, used by the backend, the client and the DTOs. Enum columns read back from Object[] rows go through Rows.state, which never casts blind. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: SMS and payment providers chosen by setting, no silent fallback wayline.sms.provider picks Twilio, Vonage or MessageBird, each with its own credentials; the console sender prints codes and is refused outside a development profile. wayline.payments.provider picks stripe or simulated. Unset, a development profile gets the console and simulated cards, and any other profile the real provider. A provider whose settings are missing logs a configuration error at start-up and on every call, naming the missing settings, and fails each call with an IOException, so phone verification answers 503 instead of a production server quietly logging codes. StripePayments is documented as an untested stub against live Stripe. UrlText is gone; form bodies and paths use java.net.URLEncoder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: shared transfer objects are Java 17 records The shared module compiles at Java 17, the app's level, and every *Dto is now a record. The generated client mappers and the server's JSON codec both build a record through its canonical constructor and read it through its accessors, so the wire names are unchanged. Component docs moved to @param tags on the record. Call sites use the accessors and the canonical constructor. RideDto gains a none() factory for the no-ride answer, and Drivers a describe(driver, rides) overload for the admin statistics. Also fixes RiderForm.request(), which never sent the pets preference. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a driver going off line stays off line Drivers.store() added the time since the last report before changing the driver's row. Adding it is a @Modifying update, which flushes and then clears the session, so the row it had just found was detached and the off-line report was never written: a driver who had been on line moments before stayed on line. The e2e DriverModeTest found it, failing on its first step. The time is now counted first and added last, after the row has been changed. MatchingTest.aDriverWhoGoesOffLineIsOffLine fails without the fix. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline guide: include the sample's own sources, not copies The developer guide quoted 23 classes from a second copy of the sample under docs/demos, which had already drifted: UrlText, LoggingSmsSender, Session repositories, RideStates and wl_ tables no longer exist in scripts/wayline. - Delete the copies; the guide now includes 19 tagged regions of scripts/wayline itself. The two framework-only illustrations (a second database) move to standalone demo classes outside any wayline package. - Rewrite the prose around the real code: injected @Repository interfaces, record DTOs, the RideState enum, snake_case tables, private entity fields, wayline.sms.provider (console/twilio/vonage/messagebird) and wayline.payments.provider (simulated/stripe) with configuration errors and no silent fallback. - validate-guide-snippets.py accepts ../../scripts/wayline/ as an include root; the guide and website workflows trigger on scripts/wayline/**. - sync-initializr-wayline.py strips the tag markers, so the Initializr template is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ORM: bulk statements leave the session alone, as JPA and Spring Data do executeUpdate() on a JPQL or native query, and every @Modifying repository method, cleared the session after the statement. An entity a service had read before the statement was then detached, and a change made to it afterwards was silently never written -- the Wayline driver going off line who stayed on line. JPA's Query.executeUpdate does not clear the persistence context, and Spring Data's @Modifying clears it only when asked. Now: - executeUpdate (JPQL and native) flushes first and leaves the session as it is. Managed entities keep their pre-statement values; refresh() or clear() reads what the statement wrote. Flush writes only changed columns and a removed row fails with OptimisticLockException, so a stale managed entity cannot overwrite the bulk change or resurrect a deleted row. - @Modifying gains clearAutomatically (default false), which the repository generator honours by clearing after the statement, and flushAutomatically (default false), accepted for source compatibility: the flush before a bulk statement always happens, as the AUTO flush mode does. Wayline moves that re-read their entity afterwards (rides, applications, documents, phone-code guesses) are marked clearAutomatically = true; the hold/counter statements keep the default. Tests that re-read after a bulk statement now clear first, and the generated-repository test covers both the default (a change after the statement persists) and clearAutomatically. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Guide prose gates and Initializr template parity after the @Modifying change Vale and LanguageTool flagged five uncontracted forms, an Oxford comma and three British 'afterwards' in the ORM, backend-data and Wayline chapters, and wayline-modules.zip still held the sample's sources from before clearAutomatically was added to its repositories. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: card setups capped and swept, removed cards detached, refunds that overlap stay consistent - Card setups: an account may have five open at once (429 past that, checked before the processor is asked and again with the account held), /api/payments/methods/setup is rate limited per user, and Payments.sweepSetups deletes finished setups and ones abandoned for two hours. - Removing a card detaches it at the processor first, through the new PaymentProvider.detachCard (Stripe: POST /v1/payment_methods/{id}/detach; a card already detached or gone counts as detached). - Refunds: a failed refund gives its claim back only while the payment is unrefunded, and a recorded refund writes the ride's status too, both on the ride's row first, so overlapping refunds leave the ride agreeing with its payment and a refunded fare never returns to the driver's balance. - EarningsDto carries todayRides, counted with the day's earnings, for the driver screen's "Today, N trips". - The app keeps a settings change marked unsent until the server takes it, retries it, and an account load sends it instead of overwriting it. - Wayline guide: drop the second-database section (and its demo classes ArchiveDatabase and ArchivedRides). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: the admin's view of a driver shows what the driver earned Statistics.user summed every completed ride's share and every tip, so a pending, failed or refunded card ride and a tip whose charge had not come back showed as earned while the balance left them out. It now takes the figure from Earnings.earned, the sum the balance is made of, and the separate query is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a card the limit refuses is detached at the processor The provider attaches the card when a setup finishes, before the server counts the account's cards again. A refusal rolled the row back and left the card attached with nothing to remove it through; it is now detached after the rollback, and a failed detach is logged without changing the 409 the rider gets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * JavaAPI: URLEncoder and URLDecoder check the charset when it is named A charset was only used when a character needed converting, so an unknown name was accepted for plain text where the JDK throws UnsupportedEncodingException. The name is now checked at entry, by a table of the charsets every runtime converts, since the native getBytes writes UTF-8 for a name it does not know instead of refusing it. US-ASCII and ISO-8859-1 are converted in Java too, so they answer the JDK's bytes on every runtime. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * JavaAPI: charset names are looked up in Java, and refused as the JDK refuses them String.getBytes(String), new String(byte[], [off, len,] String), InputStreamReader and OutputStreamWriter handed the charset name to the runtime's native, which never refused one. For a name it did not know the C native wrote UTF-8 and read UTF-8 on Apple targets and ISO-8859-1 elsewhere; UTF-16 and ISO-8859-2 worked only where NSString exists (Linux and Windows wrote UTF-8 and read Latin-1 for them); the JavaScript port's encoder ignored the name and always wrote UTF-8, and its decoder read ISO-8859-1 and US-ASCII as windows-1252. A null name meant UTF-8. com.codename1.impl.charset.CharsetSupport now holds the one list of charset names (canonical names plus the JDK's aliases for UTF-8, ISO-8859-1, US-ASCII, UTF-16, UTF-16BE, UTF-16LE and ISO-8859-2). String, the reader and writer, Charset.forName and URLEncoder/URLDecoder all look the name up there first: null is a NullPointerException and any other unknown name, including the empty one, an UnsupportedEncodingException, on every runtime. Only UTF-8 still reaches the conversion natives, plus the compact Latin-1 fast path for ISO-8859-1 and US-ASCII; every other charset is converted in Java, so UTF-16 and ISO-8859-2 work identically on every target. Comparing with the JDK found two UTF-8 bugs in both native implementations: an unpaired surrogate was written as U+FFFD where the JDK writes '?', and an encoded surrogate (ED A0..BF ..) was replaced a byte at a time where the JDK replaces the sequence once. The JavaScript decoder also stripped a leading U+FEFF. All fixed. OutputStreamWriter writes UTF-16's byte order mark once per stream rather than once per write. CharsetCodecTest runs CharsetCodecApp on the JDK, on the clean C target and on the JavaScript target under Node, and requires identical output. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Charsets a feed or page declares fall back to UTF-8 instead of throwing The previous commit made String, InputStreamReader and OutputStreamWriter refuse a charset name the class library does not convert, as the JDK does. For a name the APPLICATION passes that is right. For a name the DATA declares it was a regression: a feed labelled Shift_JIS or KOI8-R used to decode on iOS and the JavaScript port, approximately, and would now fail there while the simulator and Android, whose JDKs know the name, kept working -- a difference nobody could see before shipping. com.codename1.io.DeclaredCharset is the one place that takes a declared name: it accepts a bare name, a charset= parameter or a whole Content-Type value (quotes, white space and other parameters dropped), reads or writes in that charset when the platform has it, and otherwise uses UTF-8, the way a browser treats a label it does not know, logging each unsupported name once. A media type with no charset parameter declares nothing. Call sites that take a charset from the data now go through it: - RSSService: the Content-Type header and the XML declaration. The declaration was parsed by an indexOf whose -1 check could never fail, so a declaration with no encoding handed text from the version attribute to InputStreamReader, and single quotes were not recognised; a quoted header value was used with its quotes. Both are parsed properly now, and an XML declaration cut off by the end of the stream no longer loops forever. - AsyncDocumentRequestHandlerImpl and WebBrowser: the request body of an HTML form post, whose encoding is the form's enctype. - HTMLComponent.streamReady: only the charset a media type carries is looked up; an unsupported one still goes through HTMLCallback's ERROR_ENCODING before falling back, as before. CSSParser already caught the refusal for @charset and @media and continued. Every other core reader or writer names UTF-8 or a charset the application passed in, and those keep throwing. windows-1252 -- the label the web most often gets wrong -- is now converted by CharsetSupport, under its JDK aliases, and CharsetCodecApp compares it with the JDK on the C and JavaScript targets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * MapView animates in a desktop Window, not only in a Form getComponentForm() is null inside a Window, so move() never registered the map and wheel zoom, double-tap zoom and the glide after a fling stopped after one frame. It now registers with getTopLevelContainer() and deregisters from the top level it remembered. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: an offer asks again whether the chosen driver still fits Choosing a driver and offering the ride are two transactions. A driver who went off line, drove out of reach, lost their approval or was blocked in between still got the offer and held the rider for the whole timeout. The offer now re-runs the matcher's checks once it holds the driver, and the search chooses again (up to three times) when it refuses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: time on line across midnight is split between the two days Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: the pricing row exists from the start, so saves only update it Two admins saving prices before anyone had both inserted id 1 and one failed. V6 seeds the row (updated_at 0 means the settings' prices are still in force) and a save is one blind UPDATE. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline tests: PaymentsTest's people get names of their own PaymentsTest registered the same accounts as PricingAndStatsTest, RideFlowTest, MatchingTest and ModerationTest. Whether that failed depended on which classes the compiled run put in one context; adding a test class made PricingAndStatsTest fail with 409 on a name PaymentsTest had already taken. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Website CI: stop wrangler as a process group, on a free port The redirects step of run 38724184374 tested a server it did not start. build.sh runs check-javadoc-urls.sh on its default port 8788 and stopped it with `kill $!`, which kills npx and leaves wrangler's node, esbuild and workerd children behind. The later redirects step also used 8788: its readiness curl and all 140 redirect cases were answered by that leftover within a second, before the new wrangler had written its first log line (log named 11-14-54_317, redirects done at 11:14:54.136); the new proxy workerd then died on "Address already in use; 127.0.0.1:8788", and when the leftover went away test_search.mjs got ERR_CONNECTION_REFUSED. The runner listed two orphaned workerd processes at the end of the job, and green runs list orphaned node/esbuild from the same check. Reproduced locally with wrangler 4.129.0: an orphaned server answers the curl and the new one logs the identical bind failure. The file watcher is not involved: writing into the served directory does not restart workerd. scripts/website/pages-dev-server.sh now starts wrangler in its own process group and stops the whole group, picks a free port when none is given, refuses a port that already answers, and only reports ready while its own process is alive. check-javadoc-urls.sh and the workflow's redirects step use it; neither pins a port any more. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Initializr template parity after the review fixes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * XMLParser: the read-ahead buffer belongs to the parser, and eventParser empties it XMLParser read through a STATIC 8KB buffer that only parse() reset. When an eventParser run was ended early by its callback -- RSSService stops at its item limit by throwing FinishParsing -- the unread rest of that document stayed in the buffer, and the next eventParser call anywhere in the process consumed it before its own input. The next feed came back with the previous feed's leftover items, or with none. RSSServiceCharsetTest caught it in CI: there AdditionalServicesCoverageTest's limit-2 feed of three items runs immediately before it, and the next parse returned the title "3". The local macOS run ordered the classes differently, which is why it passed there; replaying CI's order reproduces both failures. The buffer is now an instance field, allocated on first read, and both entry points reset it. That also stops parsers on different threads from sharing one buffer, and a parse started from inside another parser's callback from wiping out the outer parse's read-ahead. XMLParserBufferTest covers both cases and fails on the old parser. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: the minimal project layout, without platform modules The javase, android and ios modules held nothing but what the archetype generates (the desktop stub and the default NativeTheme.res), and Wayline has no native interfaces. common now builds every platform itself through its cn1-host-* profiles, as a project generated with the default -DplatformModules=none does: the native theme moves to common/src/desktop/resources, the javase profile is no longer active by default, and common's pom drops the designer-jar arguments the archetype no longer has. build-android-app.sh and build-ios-app.sh look for the generated Gradle and Xcode projects in common/target when the application has no android or ios module, so CN1_APP_DIR can name a minimal project. The scripts' JDK notes say JDK 17 or newer, and server.sh no longer lists a native toolchain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline guides: written for the developer who generated the project The reader starts from the Initializr's ride-hailing template and has never seen the Codename One repository, so the chapters no longer point at scripts/wayline, the CI workflow, the template sync script or tests that stay in the repository. The server needs JDK 17 or newer, and the native build is one command; the toolchain list is gone. The module table reflects the minimal layout, with no platform modules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Backend: send push notifications through the Codename One push service com.codename1.backend.push adds CloudPush, which posts a schema-3 envelope to the V3 messages API with a push-scoped server API key; PushNotification, the server's builder for that envelope (including the widget and Live Activity surface commands, whose state is serialized with sorted keys as the app does); PushTarget, which normalizes provider aliases and reads classic cn1- device keys; and PushResult, which reports refusals and Retry-After as values rather than exceptions. Core's PushMessage is not shared because it parses through JSONParser, which the server does not compile. Tested against a loopback stub of the service. Documented in the backend web chapter, with a cross-link from the push chapter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ORM: the client ManagedSessionTest reads bulk results after clear() 65900f8bd0 made executeUpdate (JPQL and native) leave the session as it is, as JPA and Spring Data do, and updated the backend's ManagedSessionTest to match. The client copy in maven/javase runs the same scenarios against the client ORM and still expected the session to be emptied: nine tests read a still-managed entity after a bulk statement and saw its pre-statement value. Apply the same changes here: a clear() before every re-read that expects the bulk result, and the contains() check now asserts the entity stays managed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: push notifications for every step of a ride The app registers with PushClient when it comes to the foreground and hands its provider token to the server for whoever is signed in; signing out takes it back first, and closing the account forgets every device. A tapped notification opens the home that shows the ride, as rider or driver. The server sends through the backend push API once a ride change has committed: the rider hears of the driver accepting, arriving, starting and completing the trip, a cancellation and no drivers found; the driver of a new offer (living only as long as the offer) and of a rider's cancellation. Each message carries the ride id, state and role, with a collapse key per ride and role. The Notifications switches in settings are honoured: ride updates and receipts silence the notification only. The server side of the rider's Live Activity is here too: the app records the activity id against the ride, each state change carries the new state or ends the activity, and a moving car updates the minutes at most every wayline.push.activity.seconds, claimed with a conditional update. wayline.push.provider is cloud, console or recording (the test profile), and a production server missing its app id or key logs [config] and keeps serving rides. PushTest covers registration, every step, cancellations, the Live Activity, the settings and a phone changing hands. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: the ride on the lock screen while the driver is on the way RideCard starts a Live Activity when a driver accepts: the driver, the car, the plate, the minutes to the pickup and a bar through on the way, arrived, the trip and its end. The rider screen moves it on with every change it sees, off the event thread, and posts the activity id so the server can keep it current by push once the app is put away. A completed ride stays with its last state; a canceled one is dismissed. surfaces.json declares live activities only, and ios.surfaces.frequentUpdates asks iOS for the update rate a moving car needs. It shows on the iPhone lock screen and Dynamic Island, as an ongoing notification on Android, and in a window on the desktop and in the simulator; a browser shows nothing. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: an online driver keeps reporting from the background Shift begins when the server says the driver is online and ends when they go offline, sign out or switch to the rider's side. While the app is in the background it reports the position through the same driver status call the screen uses, when the car has moved 25 m and at least every 20 s, well inside the minute after which the server stops offering rides. Locator asks for precise, frequent fixes only while a shift is on, and puts the position search down in the background when there is none, so the location background mode does not keep a rider's map running. iOS keeps the app running through the location background mode, with the Always prompt's text in NSLocationAlwaysAndWhenInUseUsageDescription. Android runs a foreground service of the location type with a "You're online" notification. The simulator and the browser report nothing from the background. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline guides: notifications, the ride on the lock screen, background driving The users guide says what reaches a phone that is not looking: the notifications of each step, the Live Activity and where it shows, what the Notifications switches now silence, and the driver who keeps reporting with the app in the background. The implementors guide adds a section for each: how the app registers and the server decides what to send, turning on the Codename One push service, the Live Activity on both sides, and the shift with its build hints, every listing included from the project's sources. External Surfaces gets an anchor to link to. The Initializr template is synced with the sample. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ParparVM: RecordMethodsTest gets the application it runs The test's RecordMethodsApp was committed as a license header alone, so the JDK leg had no class to run. It now holds records of every primitive kind, a String, a nested record, a list, an enum, null components, NaN and -0.0, and prints their equals, hashCode and toString on one RESULT line. A record with an enum component prints no hashCode, since an enum hashes by identity. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: Android builds out of the box, with push switched on by the Firebase file A build that uses PushClient stops without google-services.json or agconnect-services.json, so a freshly generated project could not build for Android. The template sets android.messagingService=none until the developer adds the file; the Implementors guide says to delete that line then. The catalog now documents the hint's values, none among them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: settings file restored after a local Android build rewrote it; guide prose A local Android build stored the sample's codenameone_settings.properties back through Properties.store, which dropped its comments, reordered it and added a machine-local keystore path; that copy was committed and broke the Initializr template parity check. The file is restored with only the android.messagingService line added. Four sentences LanguageTool flagged in the push and Live Activity sections are reworded. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: hold the ride while a Live Activity attaches, cap moved push devices, sign out of the old server on switch Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Perf overlay: bimodal AMD family 26 Windows x64 hello RAM Hello RAM is bimodal on every runner: one run's rounds read about 1.0 to 1.2, another's about 0.75 to 0.85. On AMD family 26 model 2 the gate failed unchanged code at 1.02 against 0.75. Baseline is the median of all ten rounds from runs 38688282220 and 38758240099 (0.999), memory tolerance 0.35 as the other Windows hello rows carry. Time is kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * BackendWebApp: unlink a symbolic link in the output instead of emptying its target Replacing the staged web app, or a copy destination, walked the old tree with listFiles(), which follows a link to a directory, so a link pointing outside the tree had the external directory's contents deleted. A dangling link was left behind. Links are now removed as links and never descended into. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Screenshot suite: the two native video tests get five times the default budget VideoIODecodedFrames timed out at 90s on the cross-compiled Windows build (run 38758239027) and its PNG arrived during the test after next, matching its reference: slow under a runner stall, not hung. Neither video test is retry-safe, so the budget is the only slack they have. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * DeclaredCharset: take the charset from a parameter named charset, not from a substring A search for "charset=" anywhere in a Content-Type also matched a parameter whose name ends in charset (x-charset=windows-1252) and text inside another parameter's quoted value, and RSSService then decoded the feed in that charset. The declaration is now parsed into parameters on their delimiters, outside quoted strings, and only a parameter named charset declares one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * OutputStreamWriter: hold a high surrogate across writes for every charset The UTF-8 path already joined a pair split across two writes; the getBytes path used for every other charset encoded each half alone, so UTF-16 wrote two U+FFFD and a single byte charset two '?' where the JDK writes the character, or one '?'. The held half survives a flush and is replaced at close, as the JDK's encoder does. CharsetCodecApp compares the split writes with the JDK for every charset. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: push registration holds the account, stale ride changes say nothing - PushDevices.register holds the account's profile row before reading or writing devices: refused once the account is closed (no orphan device), and concurrent registrations serialize so the cap cannot be overrun. - RidePushes.compose sends nothing when the ride's committed state (or an offer's driver) no longer matches the change it was called for; the later transition's own call ends any Live Activity. - PhoneVerification: comment on why the previous code's count already includes post-resend guesses (takeGuess increments both counters). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Charsets: back to the platform's behaviour; only UTF-8 and ISO-8859-1 are promised Reverts the charset rework (CharsetSupport, DeclaredCharset, the String/reader/writer/Charset lookups, the native and JavaScript codec changes, the OutputStreamWriter surrogate holding and their tests). This class library is not the JDK: UTF-8 and ISO-8859-1 are the charsets it supports everywhere, and any other name is whatever the platform makes of it. URLEncoder and URLDecoder say so instead of checking the name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a closed account keeps no application; desktop magnify steps are gestures Applications.hold() ignored a zero profile hold, so a save or upload authorized before Accounts.erase committed recreated the application and stored identity documents after forget() ran. It answers 404 now, as PushDevices.register does. JavaSE's trackpad magnify reports 1.14/0.88 steps with no gesture phases, while Component.pinch() is the scale since the gesture began. MapView read every step as the same one step and never left its pinch. Each step is now delimited as a gesture of its own. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Initializr: resync the Wayline template with the application closure fix Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: an unresolved card tip keeps its card; flags and stale profiles follow closure - Payments: removing a card or closing the account also waits on a card tip whose charge nobody can vouch for. Its retry charges the ride's card under the same key, so with the card gone a tip that may have been charged was cleared as refused. - Accounts.flag holds the profile first, so a flag racing the account's closure cannot record a moderation row after erase() forgot them. - Session.refreshUser drops an answer from a server the app has since been moved off. - BackendWebApp: following symbolic links in the copied web output is intended; the comment says why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a sign-in from a server left behind installs nothing; closed accounts get no new rows Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a half-done refund stays recorded; maps drop overzoom tiles the view left Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline and Initializr templates are MIT No Attribution; brand tints follow the scheme; label halos take their room Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: answers from an ended session are dropped; device state belongs to an account on one server Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a restore from an ended session is dropped; the hosted browser app keeps its server Backend.dispatch decorates a chosen status and its own 404 as the listener does; the backend goals read cn1.backend.webapp.output; a shaded jar's application classes are scanned beside the runtime it carries. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a Live Activity is forgotten once its end is sent; shadowed dependency classes are not scanned An end the push provider refused stays marked and is sent again by a sweep, for as long as iOS would keep the activity on screen. The dependency scan claims every class name before its annotation test, so the definition the JVM loads first always wins. A shared module's calls are checked unrewritten, because the server runtime has no rewrites either. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: the hardening a production deployment adds is listed, not built Keyed phone-code digests, retried push unregistration, sign-out ending a ride's Live Activity and an activity per device are listed in the implementor's guide; the code says why the sample stops short of them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a live ticket is not held against account closure; it expires within a minute and opens nothing Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a document's pixel size is checked from its header; Gradle's backend tasks share the web-app output Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: server-switch and token races are left to heal, and the code says why Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a Live Activity is forgotten when the push service confirms its end; a pool thread keeps the generation it was made in The push sender reports acceptance through a callback, so an end the service refuses on its own thread, or never answers, stays for the sweep. RunnableWrapper takes a worker's generation when the worker is created, under the pool lock, not when it is first scheduled. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a customer orphaned by a lost answer and a rename is left at the processor, and the code says why Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a driver owed money cannot close the account; leaving driver mode says so to the server Closing an account is refused while the driver's earnings balance is above zero, since the retired name could never cash it out. Leaving the driver's side while the session is still there reports the driver off line, and a driver-status answer arriving after navigation no longer restarts the shift. Sign-out revocation and charges past the retry window are left as they are, and the code says why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: an unsent-change mark is cleared only for its own account; the settlement sweep takes the oldest rides first A save answered after another account signed in no longer erases that account's unsent mark. The payment sweep reads its page oldest first, so a backlog cannot keep old rides behind new ones until they age out. A stale account load still completes, and the JavaScript port's XHR listeners are plain worker closures freed with the request; the code says why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Maps: an overzoomed ancestor that failed waits out its back-off for every piece of it The failure of a level fetched for overzoomed pieces was recorded only against the pieces then waiting, so each further piece of the same tile -- one per sibling within a paint when the source refuses at once, or every piece a pan brings into view -- asked the source for it again with no back-off. It is now recorded under the ancestor's own key and consulted before the ancestor is asked for. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a seeded card tip carries its charge; the browser build gets the outer build's profiles The demo fortnight's card tips had no tip reference, so the driver's earnings and a refund skipped them while the receipts showed them. The nested JavaScript build of backend-webapp now receives the profiles turned on and off with -P. The demo seeding marker stays an account, and the code says why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * JavaScript port: location requests share two callbacks instead of minting one each A callback handed to the page keeps an entry in the runtime's worker callback table for good, so a new GeoCallback per getCurrentLocation and per watch was never released. The manager now owns one callback for one-shot answers, taken by whoever is waiting, and one for watches. URLDecoder leaves an unknown encoding to the first escape, and the code says why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Wayline: a closed driver's old rides take no tips; a phone-code guess holds the profile first A tip for a ride whose driver has closed the account is refused, since it would be credited to a name nobody can cash out. A guess at the phone code takes the profile hold before the code row, the order a closure takes them in. Withdrawing the driver role with earnings owed stays allowed, and the code says why. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Backend packaging reads the source encoding from the compile execution first backend-package and backend-test recompile the module's sources, and took their encoding from the compiler plugin's own configuration only, so a module declaring <encoding> on its compile execution was recompiled with a different charset than the lifecycle used. The execution already selected for the other compiler options is now read first. The tip-in-flight comment is corrected, and URLEncoder says why an unknown encoding waits for the first escape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ORM: the backend's Spring Boot naming has no switch back, and the code says why Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * JavaScript port: a one-shot timer releases its callback when it fires Window.setTimeout handed every Java handler a permanent worker callback id, and the host kept a proxy for it, so each timeout leaked both. A one-shot timer now forgets both sides when it fires or is cleared, and the semantic-refresh timer reuses one stable handler. A browser bundle with a link back to its own ancestor is refused when the link is reached instead of being copied into itself. The Gradle task's comment now points at the never-up-to-date registration, and the duplicate of that registration is gone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Adds
com.codename1.io.ProcessBuilderandProcessfor Windows, macOS, and Linux desktop applications and backend applications. The JavaSE-style API works without initializing Display or a server, with host-JDK and shared ParparVM adapters. Mobile/browser ports report unsupported and fail explicitly.The API supports literal argument lists, working directories, environment changes, separate or merged stdout/stderr, binary stdin, exit status, interruptible timed waits, termination, and explicit cleanup. Native pipes use nonblocking/overlapped I/O, children are independently reaped, and backend virtual threads park between polls. The one-host regression exposed a scheduler bug: capture the nap-table entry's key before removing it, because the native map clears removed entries.
Documents platform behavior, resource ownership, and intentional JavaSE differences: native OS path strings, lazy environment snapshots, AutoCloseable cleanup, and no file redirection, inheritIO, pipelines, or ProcessHandle in this subset.
Fixes #5992.
Validation
verifywithProcessBuilderTest,ButtonGroupTest: 11 tests passed, SpotBugs passed, zero Checkstyle findings.All native execution was local. No native CI jobs, labels, or workflow changes were added.