Repository navigation
Swing, SwingX and JavaFX compatibility layers: desktop Java apps as Codename One apps - #5980
shai-almog wants to merge 328 commits into
Conversation
…g nested resources twice The first end-to-end run of the Swing gallery sample. A bundled library names API no device can serve (java.beans persistence, AWT's heavyweight widgets); those types now exist marked @linkonly, which the compliance check accepts from a bundled library and still reports from the application's own classes. WeakHashMap, Externalizable and ClassLoader.loadClass get shims. The Gradle build left the nested copy of a flattened desktop resource in the upload. The sample uses the look and feel, ImageIO, clipboard, editable combo and HTML editor pane the hardening slice added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…atibility chapter Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s it is Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SwingGallerySampleTest compiles the sample as its own build does, remaps it with MigLayout bundled, requires zero compliance findings, and starts the generated main class on the headless implementation in a class loader that holds only the remapped classes: one frame, eight tabs, every tab and every layout tab painted. It found that a Swing component in no window answered a null font, where the desktop's is never null (getFont().deriveFont in a cell renderer). A project holding an Android and a desktop application now fails with a message that names both and the two ways out. The integration script checks every staged jar for toolkit references and prints what the layer adds to an upload. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ntrols resolve An FXML document was compiled in generate-sources, against the class path alone, so an element naming a class of the application itself was an unknown class. The documents are now compiled by the remap, as its first step: after javac, before anything is relocated, with the application's classes beside the class path, and by an in-process javac writing into the classes directory. The early step keeps the style sheets and writes a marker source carrying a digest of the documents, so an FXML-only edit still recompiles the module, and so a classes directory the remap already relocated is recognised and left alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A plain Maven JavaFX 17 project, written as a JavaFX developer writes one: controls, layouts, bindings, an FXML screen with an included document and a custom control, style sheets, shapes and a canvas, animation, dialogs, a task and menus. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…urces, shipped size A first end to end build of a project holding an Android application and a Swing one showed the conflict message added for it never fired: the Android remap runs first, so the main class extends the RELOCATED lifecycle and the unrelocated name alone never matched. Both names are recognized and the integration script now builds that project: it must stop naming both applications while the entry record exists, and stage with both runtimes relocated once the record is gone. The Gradle plugin filters the desktop resource directories out of the source set rather than out of processResources, whose exclude answers a value SpotBugs rightly asks about. Tests for the importer's library list, the pom updater and the loadClass rewrite; the sample's French bundle is escaped, as a properties file on a real JDK 8 has to be. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mirrors android-compat.yml: the module tests, then desktop-compat-test.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ors, stage icons What the JavaFX gallery sample needed and the layer lacked: TableView sorts by its headers and by getSortOrder (comparatorProperty, for a SortedList to bind to) and edits cells (TextFieldTableCell, the edit events of a column, TablePosition); Node.setClip clips drawing and picking to the box of the clip node; KeyCombination and KeyCodeCombination, MenuItem accelerators fired from a MenuBar of the scene, Scene.getAccelerators; Stage.getIcons, recorded; and a style sheet may say infinity for a length. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The idiomatic wrapper around FXMLLoader.load in a constructor; the device library has no such class and the compliance check refused the application. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The remap writes a desktop resource under its flat name and removes the nested copy from the classes directory, where Maven had put it. Gradle copies resources to a directory of their own, so every upload carried each resource twice and differed from Maven's. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…660c # Conflicts: # maven/build-engine/src/main/java/com/codename1/maven/Relocation.java # maven/codenameone-gradle-plugin/src/main/java/com/codename1/gradle/AppSupport.java
kind=library in cn1-desktop.properties never generates a main class; without a record, a project whose own main class is a compiled class is a library too, and the build says so at info level. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s JavaFX keeps them Form's constructor lays itself out when the theme installs a global toolbar, which reached StageForm.layoutContainer before its fields existed and threw. CellEditEvent reads its table from the position, which is transient as in JavaFX, and a descending sort exchanges the operands instead of negating. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Built by the build's own steps (resource compiler, javac, FXML compiled against the application's classes, relocation, compliance), then started on the headless implementation: every tab selected and painted, the FXML button fired through its controller, style sheet values read back. The workflow also compiles the pristine sample against OpenJFX on JDK 17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e application classes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SwingInterop.asComponent and FxInterop.asComponent answer a Codename One component that lays out, paints and takes pointer input for a Swing tree or a scene graph. Without a lifecycle of the layer nothing ends the application: closing the last window returns to the form it was shown over. setNativeWindows(false) keeps secondary windows inside the application's own window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tal builds The remap copies the relocated runtime into the application's own target/classes, where it shadows the jar on the next non-clean compile. A public class the remap does not move then names the RELOCATED Parent in its signature while the application source still names javafx.scene.Parent, and javac refuses the call. Declaring the parameter as Object and checking it with instanceof compiles against either copy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
hellocodenameone compiles common/src/main/desktop in library mode (no entry point generated, the Android layer stays active) and embeds thirteen static scenes in forms of its own: seven Swing/SwingX and six JavaFX, including a JOptionPane and an Alert that are captured while open and then answered from code, with the blocking call's return value asserted. DesktopCompatScenesTest drives the same sources headless: it compiles the FXML and the Java, remaps them in library mode, checks bytecode compliance, and shows, paints and answers every scene from the relocated classes. The feature is registered in port_status.json. No goldens are committed: each port's screenshot job reports the thirteen DesktopCompat* images as missing_expected until its artifact is copied into that port's golden directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Describes library mode (no entry point generated), SwingInterop.asComponent and FxInterop.asComponent, and opening frames, stages and dialogs from a Codename One application. The snippets are compiled demo sources, so the demo module gains the Swing runtime as a provided dependency. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… key note The diff-scoped header gate covers .css, and four style sheets added with the layers had none. JTable's class comment promised Home/End/Page/F2 handling that rt/KeyMap documents no port can deliver. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…L compile The screenshot scenes test was written against the DesktopResourceCompiler that took the compile classpath; the JavaFX merge moved FXML compilation into the remap and dropped that parameter, so build-engine's test sources no longer compiled and the PR SpotBugs line stopped at build-engine. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The parity tests compare each layer class with the class of the JDK the test runs on, and the layers model Java 8. On Java 17 and 21 the JDK itself answers differently in a handful of places -- CLDR number symbols, a URL host with a space, tight curve bounds, GroupLayout reaching sun.swing -- so those comparisons failed without the layer being wrong. They now call ReferenceJdk.assume with the reason and are reported as skipped there. ApiShapeTest gets a one-way allowance for GroupLayout.SequentialGroup, which the JDK made final after Java 17: the layer stays as open as the most permissive JDK an application can be compiled against. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves the compat-jdk java.io layer into vm/JavaAPI and Ports/CLDC11: BufferedInputStream/OutputStream, BufferedReader (without lines()), BufferedWriter, PrintWriter (printf/format over String.format), Closeable implemented by InputStream/OutputStream/Reader/Writer, UncheckedIOException, Externalizable/ObjectInput/ObjectOutput with their JDK members, and the JdkIo members readAllBytes, readNBytes and transferTo on InputStream and Reader. CLDC11 Writer becomes Appendable as JavaAPI's already is. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
java.io.File, FileInputStream/FileOutputStream, FileReader/FileWriter, FileFilter/FilenameFilter, the PrintWriter file constructors, java.nio.file and java.nio.file.attribute move into vm/JavaAPI and Ports/CLDC11, all going through JdkHost. JdkHost gains the file test/set/length/lastModified/create/ replace/canonicalPath/freeSpace operations; CoreJdkHost maps them onto FileSystemStorage, and PosixJdkHost implements them over PosixFileAccess. Behaviour change: a program translated without Codename One must install PosixJdkHost before touching files. The vm/tests fixtures and the IoBench benchmark now do (vm/benchmarks PosixHost). The stream-returning methods (Files.lines x2, list, walk x2, find, and BufferedReader.lines) are left out. ProcessBuilder takes directory(File), and RuntimeExec gains the File overloads. BufferedInputStream.read(byte[],int,int) now keeps reading while the underlying stream has bytes available, as the JDK does; the new parity test found the difference. Parity tests: NioPathParityTest, NioFilesParityTest and IoParityTest in maven/jdk-parity-tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The generated app module now declares the nio flavour of the desugared library (same 2.1.5 release), so java.nio.file works below API 26. The dependency line is built by a package-private static helper, coreLibraryDesugaringDependency, with a unit test. A desugared library the project already declares, in any flavour, still wins. The legacy android.useGradle8=false scaffolding has no desugaring at all, as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… CLDC11 and JavaAPI The 35 java.util.function interfaces the class library lacked (the Int/Long/Double forms, the To*/Obj* functions, BiPredicate, BooleanSupplier) are added to both Ports/CLDC11 and vm/JavaAPI, with the defaults the JDK declares. The eight that were there gain their defaults and statics: Function compose/andThen/identity, BiFunction.andThen, BinaryOperator now extends BiFunction and has minBy/maxBy, UnaryOperator.identity, Consumer/BiConsumer andThen, Predicate and/or/negate/not/ isEqual. Comparator gains comparingInt/Long/Double, thenComparing(key, comparator), thenComparingInt/Long/Double and nullsFirst/nullsLast (whose reversed() keeps null on its side and reverses the rest, as the JDK's does); CLDC11's Comparator gets the whole default set JavaAPI already had. This is what compat-jdk's JdkFunctions and its 35 interfaces provided under relocated names. No lambdas in the library: the composed objects are anonymous classes, so nothing reaches invokedynamic and no public nested type is added to an interface. Tests: vm/tests FunctionalApiIntegrationTest runs FunctionEdgeApp on the JVM and on ParparVM and compares (the Function/Comparator defaults cannot be renamed apart from the JDK collections that call them); maven/jdk-parity-tests relocates the 35 new interfaces and holds their defaults against the JDK's (PrimitiveFunctionParityTest). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…LDC11 JavaAPI's StreamImpl is replaced by compat-jdk's lazy pull pipelines (ObjPipeline, Int/Long/DoublePipeline, StreamState, PullIterator), ported without lambdas, together with IntStream/LongStream/DoubleStream, the Optional* and *SummaryStatistics value types, PrimitiveIterator, the full Collectors set and the Stream/BaseStream members. Ports/CLDC11 gets the same files, so core compiles against exactly what the device runs. Collection.stream()/parallelStream()/spliterator()/toArray(IntFunction), Iterator.remove()/forEachRemaining, Iterable.spliterator, List/Set/Map.of and copyOf, Map.entry/ofEntries, Map.Entry.comparingBy*, Arrays.stream and Optional.stream join the JDK-owned interfaces; a minimal Spliterator, Spliterators and StreamSupport carry Collection.stream() into the package. Two behaviours StreamImpl had and the compat pipeline lacked are kept: a terminal operation that throws closes every mapped stream flatMap still holds (latest first, close failures suppressed), and close() rethrows a sneaky checked exception unwrapped. isParallel() now reports what was asked for. Immutable sets and maps are hashed, not linked, so an app that never calls them does not retain LinkedHashMap/LinkedHashSet. Core regex regains Pattern.splitAsStream and Matcher.results(). The compat stream, primitive stream, collectors and immutable-collection differential tests run in jdk-parity-tests against the relocated JavaAPI classes; StreamPipelineApp holds the JDK-owned members on ParparVM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ctions The executors, CompletableFuture, ConcurrentHashMap, the copy-on-write collections, CountDownLatch and the scheduled executor move from compat-jdk into the class library, identical in vm/JavaAPI and Ports/CLDC11. - Thread-safe for real, since vm/backend runs them multi-threaded: the map and list synchronize on their own lock, futures complete under a monitor. - Executors.Pool replaces the fixed pool: workers start lazily up to the limit, honour the ThreadFactory, and the cached pool is unbounded with a keep-alive. FutureTask gains done(), set(), setException() and runAndReset(), so ExecutorCompletionService now learns of completions. - A wait on the UI thread (Future.get, CompletableFuture.get/join, CountDownLatch.await, awaitTermination) goes through JdkHost.blockUi. Waits are interruptible. - invokeAll cancels in reverse order on failure, here and in compat-jdk's Executors: cancelling the first task freed a worker that started the next one before the loop reached it. Tests: ConcurrencyContractTest (deterministic invokeAll order, proven to fail with the old order; blockUi routing; concurrent mutation), and the compat ExecutorsTest and CopyOnWriteArraySetDifferentialTest moved to jdk-parity-tests; ConcurrentApiApp compares ParparVM against the JVM. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… CLDC11 Brings vm/JavaAPI's java.time up to the member set compat-jdk's JdkTime and JdkDates provided, so desktop and Android code can use the device classes directly: - DayOfWeek, Month, TemporalUnit/ChronoUnit, TemporalQuery, TemporalAmount, a real Temporal and the chrono interfaces. - Duration/Period/Instant/LocalDate/LocalTime/LocalDateTime/ZonedDateTime/ OffsetDateTime/Clock members (from, parse, until, truncatedTo, overlap offsets, Instant.MIN/MAX, OffsetDateTime.MIN/MAX, Clock.withZone/offset). - DateTimeFormatter: SMART resolution of 24:00 and clock hour 0, ISO_INSTANT over the full Instant range, ISO_INSTANT parse with an override zone. - java.util.Date: from/toInstant and the JDK accessors. - TimeZoneSupport folded into java.time. Ports/CLDC11/src/java/time is now byte-identical to JavaAPI's. TimeParityTest in maven/jdk-parity-tests replaces compat-jdk's TimeDifferentialTest against the relocated JavaAPI classes, with the JDK 8 defects JavaAPI does not copy special-cased. TimeEdgeApp exercises the new API through the translator. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…JavaAPI and CLDC11 Format gets the JDK shape (format(Object, StringBuffer, FieldPosition), parseObject(String, ParsePosition), a final format(Object)). NumberFormat, DecimalFormat, DecimalFormatSymbols, ChoiceFormat, MessageFormat, FieldPosition and ParsePosition move in from compat-jdk, identical in both trees: NumberFormat and MessageFormat now extend Format, DecimalFormat's exact comparison uses a private base-1e9 magnitude instead of a core BigInteger, and DecimalFormatSymbols reads the device's separators and currency from JdkHost.localeNumberSymbols(). MessageFormat gains parse, getFormats and the setFormat family. DateFormat gains the Format adapters and parse(String, ParsePosition) while keeping its native style formatting. Parsing at an offset exposed two SimpleDateFormat bugs that are fixed here: number and month reads tested index 0 instead of the read offset, and a field the pattern does not parse took the current time instead of the epoch, as the JDK does. jdk-parity-tests relocates java/text/ and runs DecimalFormatParityTest, MessageFormatParityTest (now covering parse and the format setters) and DecimalFormatSymbolsHostTest against the JDK on 8 and 17. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… core resource support JavaAPI and CLDC11 gain the members the switch-over from compat-jdk relies on: List's sequenced methods, CharSequence chars/codePoints, Throwable printStackTrace(PrintWriter), lazy Files.lines/list/walk/find, BufferedReader.lines, ServiceLoader.findFirst and load(ModuleLayer, Class), URLEncoder/URLDecoder. JavaAPI's java.util.regex is gone: desktop regex is relocated to com.codename1.util.regex. Throwable now prints the JDK's shape on a device: toString() as the first line (a never-thrown throwable has no native trace and printed "null"; a thrown one printed only its class name) and "Caused by: " before each cause. Core Resources answers META-INF/services files from the generated registry (cn1ServicesFile); the JavaSE and Android ports install CompatResourceSupport (cn1res URLs and a flat resource loader whose services lookups see device semantics) and UncaughtExceptions keeps the EDT hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Relocation keeps java.* names except regex (com.codename1.util.regex), ProcessBuilder/Process (com.codename1.io), Runtime.exec, String's regex members and resource lookups. ApplicationRegistry generates com.codename1.generated.compat.CompatRegistry, which the lifecycles, the generated main and library mode install. Tests load JdkHost from the class library and install the registry the way an application does. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
swing-compat, javafx-compat, android-compat and fxml-compiler use java.* and core com.codename1.impl.compat directly; the layers carry the placeholder CompatRegistry. compat-testing compiles the JavaSE port's JdkHost and installs JDK resource support in the headless implementation. android-compat's com.codename1.compat.jdk tests go with the module they tested; the bulk ParparVM conformance port covers that behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Its API lives in Ports/CLDC11 and vm/JavaAPI under the real java.* names. Reactor, CI workflows, SpotBugs gate list, cast-semantics scope, benchmark scripts and CLAUDE.md updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, JavaSE vs ParparVM Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d on ART Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every one of these answered differently from the JDK on ParparVM and was found by running the class-library checks on both: - Thread.interrupt now wakes Object.wait and Thread.sleep. The waiter publishes the monitor it waits on (ThreadLocalData.waitingOn) and the interrupter broadcasts that monitor's condition, taking its mutex with trylock and retrying so it can never deadlock against a thread holding lockCriticalSection; a pre-set interrupt throws before waiting. sleep is cut into 50ms slices that stop on the flag. The JS runtime's wait throws for a pre-set interrupt the same way. - String.getBytes, new String(bytes, name), OutputStreamWriter and InputStreamReader refuse an unknown charset name with UnsupportedEncodingException instead of silently using UTF-8, and honour aliases in any case (latin1, iso-8859-1, ISO8859_1). PrintWriter asks Charset for the same reason. - File permission setters chmod (they answered false and did nothing), Files.move no longer half-copies a source it cannot remove, URI rejects illegal characters in authority/path/query/fragment, Random.nextBytes uses the JDK's documented algorithm, and DecimalFormat produces the JDK's digits through LegacyDoubleDigits, a rewrite of OpenJDK's FloatingDecimal digit generation that keeps its Oracle notice (NOTICE, header exclusions). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-parity-tests BulkConformanceIntegrationTest compiles one program of named checks, runs it on HotSpot, translates and builds it ONCE with ParparVM, runs it, and diffs the two outputs check by check (282 checks in 36 groups). It replaces: - the vm/tests per-API integration tests (CatchRethrow, CollectionSemantics, FunctionalApi, LangMembers, StreamApi, StringBuilderGrowth, StringFormat, SystemMembers, TimeApi), each of which paid for its own translation and native build; their fixture programs move under bulk/ unchanged in what they check; - maven/jdk-parity-tests, which ran vm/JavaAPI relocated on the JVM rather than translated. Its 259 tests are ported check for check, except the Optional relocation self-check (meaningless without relocation) and CoreJdkHostInstallTest, which tests core code and moves to core-unittests. Delays.pending() assertions become the public effect they stood for (the dropped work becomes collectable), since Delays is package-private. Checks that a JDK may legitimately answer differently (host-backed behaviour, an internal ordering the JDK races on) run as cn1Only with expectations. Weak-reference checks drop their referents on a thread that has ended: ParparVM scans native stacks conservatively, so a stale word on a live stack may keep a referent, which the JDK contract allows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…piler FileClass, PosixJdkHost, Lock, ReadWriteLock and StampedLock integration tests each compiled JavaAPI, translated and ran a native build over the same compiler matrix. HostLocksIntegrationTest builds one program holding all five per configuration and keeps every assertion: it compiles, the CMake project is emitted and builds, the run exits 0 (FileTestApp exits 1 on any failure) and prints POSIX-HOST-OK. PosixHostApp runs first because it checks the JdkHost defaults before anything is installed. The lock programs are still built and not run, as before (their run was switched off for a crash on Linux runners), behind a branch no command line takes so the dead-code pass keeps them. ExecutorIntegrationTest was @disabled and ran nothing; its two programs are now the bulk check Executors.aSubclassOfAbstractExecutorServiceRunsWhatItIsSubmitted. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SwitchoverMembersApp becomes one check of the bulk conformance program instead of a translation of its own; the bulk compile prefers JDK 21 for its sequenced List calls. Comments no longer name the deleted compat-jdk. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A translated backend program that wrote a file before touching Backend got 'No file system': the PosixJdkHost install sat only in Backend's static initializer. The clean target's generated main() now calls FileIo.installJdkHost first when the backend runtime is translated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- vm/tests: javac takes its arguments through an @argfile; the JavaAPI compile outgrew Windows' 32K command line (CreateProcess error=206). - Resources.loadClass answers from the generated registry instead of Class.forName (Error Prone BanClassForName). - ZonedDateTime: the zone in the doc example was read as a link. - Optional: /// comment; StandardCharsets and the regex package-info get the full header; the Harmony files are listed as excluded. - check-guide-api-names reads docs/demos, where the guide defines Level1. - SecurityChecks seeds SecureRandom from generateSeed (CodeQL). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- TimeArithmetic.multiplyExact: test MIN_VALUE * -1 before dividing; C's division traps (SIGFPE) on x86 for MIN_VALUE / -1. - floatToIntBits/doubleToLongBits natives answer the canonical NaN, as the JDK does, instead of whatever the hardware produced. - android-compat Context: directories are built from native paths (FileSystemStorage.toNativePath); the platform's java.io.File no longer receives a file: URL now that the JDK shim module is gone. - check-native-signatures: the backend compile sees JavaAPI's JdkHost. - PMD: @OverRide on the digest methods, foreach, Resources.exists close. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
When a parsed day, hour, or minute field overflows while being converted to seconds, these unchecked operations wrap to an unrelated duration. For example, Duration.parse("P106751991167301D") returns a large negative duration here, while the JDK reports a DateTimeParseException; use checked multiplication and addition throughout this parsing block and translate arithmetic overflow into a parse failure. The mirrored vm/JavaAPI implementation has the same issue.
ℹ️ 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".
…aths
- Regex: under CASE_INSENSITIVE the case classes (\p{Lower}, \p{Lu},
javaLowerCase, ...) match either case, as on the JDK since 16
(JDK-8214245); the differential test skips them on an older JDK.
- Time zones: far-future instants are folded into 2400-2799 before asking
libc; glibc answered standard time for distant years where the JDK and
macOS apply the recurring rule.
- Windows port: stripFileUrl accepts the standard file:///C:/ form, which
java.io.File hands over; it produced /C:/..., refused with error 123.
- Bulk executor check proves the repetition continues rather than timing
300 runs, which a loaded CI runner could not fit in 30 seconds.
- Review: Path.toUri ends a directory in '/', orTimeout/completeOnTimeout
require the unit, String.indent(MIN_VALUE), primitive stream terminals
release flatMap inner streams on failure, Files.createFile and CREATE_NEW
claim the path with the exclusive create, Duration.parse refuses
overflowing fields (with bulk cases).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cfb5423474
ℹ️ 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".
…on units - Regex: \b and \B use ASCII word characters, as JDK 19+ does; the differential test compares that only against a JDK that agrees. - Pattern.compile rejects flag bits no constant names. - Character.getNumericValue answers superscripts, subscripts, Roman numerals and circled numbers, and -2 for fractions; a bulk check sweeps those ranges against HotSpot. - LocalTime/Instant.truncatedTo accept any unit that divides a day. - Files.createDirectory reports an existing path as FileAlreadyExists, and temporary names retry on it instead of failing a racing caller. - WeakHashMap reads purge collected keys, amortized over the reads. - ZoneId.of: why an unknown region is not rejected. - Windows x64 hello RAM baseline for a runner CPU model with no row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Conflicts resolved: - Escape analysis: master landed the same fix (EXACT_CALL, lastClusterStore, resolveReceiverCall); took master's and kept the private-method nestmate resolution in resolveReceiverCall. - URLEncoder/URLDecoder (JavaAPI): took master's codec. - Linux/Windows ports: kept the core JDK host installer, added master's window size hints; Linux a11y keeps the pointer pass-through on master's batching. - Lock/FileClass integration tests: kept the deletion (covered by bulk runs). - Gate lists, spotbugs excludes and guide accept lists: kept both sides. CI fixes in the same commit: - Stream pipelines unbox through helpers, so the cast-semantics gate no longer sees a checkcast inside the try/catch(Throwable) blocks. - iOS packaging and Metal screenshot timeouts raised: the hello app now ships the Swing/JavaFX runtimes, about 22% more translated C. - Bulk conformance case 38 uses an empty charset name, which both runtimes refuse under master's lazier encoder. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Flutter vs Codename OneSame application, built both ways: Flutter's AOT compile of the gallery, and the identical Dart source transpiled to Java on Codename One. Lower is better for every metric, so a ratio above 1.00x means Codename One is ahead by that factor. android9 interleaved rounds; host load 0.54, 1.61, 1.4
Compute -- the VM workloads (
Gate: within tolerance against
ios9 interleaved rounds; host load 34.03, 38.6, 32.89
Compute -- the VM workloads ( Not measured: iOS compute is not measured: a device build needs signed hardware, and on the simulator Flutter runs its JIT debug engine rather than AOT code. The macOS row runs the same ParparVM and Dart AOT compilers on the same Apple silicon. Gate: within tolerance against
javascript9 interleaved rounds; host load 1.93, 1.22, 0.55
Compute -- the VM workloads (
Gate: OUTSIDE THE BASELINE against
linux9 interleaved rounds; host load 0.17, 2.74, 2.32
Compute -- the VM workloads (
Gate: OUTSIDE THE BASELINE against
macos9 interleaved rounds; host load 5.15, 11.21, 14.76
Compute -- the VM workloads (
Gate: within tolerance against
windows9 interleaved rounds
Compute -- the VM workloads (
Gate: within tolerance against
Codename One wins 26 of 26 measured metrics across 6 platform(s). |
What this adds
An existing Swing or JavaFX project builds as a Codename One application for every target, the way an Android module does with the Android compatibility layer. The sources are imported with
cn1:import-desktop-projectintocommon/src/main/desktopand built unmodified.maven/swing-compat:java.awt, Java2D,javax.swing,java.beans,javax.imageio, a SwingX subset and the FlatLaf entry points, written over Codename One components. Authored already relocated, because the JDK owns those package names; applications compile against the JDK's Swing.maven/javafx-compat: thejavafx.*subset (scene graph, controls, charts, layout panes, properties and bindings, animation, effects, Canvas), authored under the real names.maven/fxml-compiler: FXML and JavaFX CSS compiled at build time; nothing on a device parses XML or reflects.maven/compat-jdk: the JDK classes a device lacks (streams,java.util.function,java.nio.file, regex,CompletableFuture,java.timegaps and more), shared with the Android layer.maven/build-engine: one composed relocation pass over every layer, generated entry points and registries, records and pattern switches desugared, and the compliance check extended so that unsupported API is a build error reported under its original name and source line.scripts/desktop-compat-samples), screenshot tests inhellocodenameone, an integration test, a real-port interaction harness (maven/integration-tests/desktop-compat-realport) and a benchmark harness (scripts/desktop-compat-benchmarks).docs/developer-guide/Desktop-Interop.asciidoc, with measured size, memory and start-up tables.Verified locally
Not verified / known gaps
desktop-compat.ymladditions,desktop-compat-benchmarks.yml) have never run on GitHub. Windows is unmeasured; macOS runtime numbers needrun-macos-bench.sh.DesktopCompat*tests have to be seeded from the first CI run.🤖 Generated with Claude Code