Backend: Spring-style beans, transactions, scheduling, metrics and MCP, resolved at build time - #5908
Conversation
…P, resolved at build time The backend gains Spring's programming model under com.codename1.backend.annotations -- @Service/@Component/@repository, @Autowired, @value, @ConfigurationProperties, @bean, scopes, profiles and conditions, @transactional, @async, @scheduled, @ManagedResource/@Timed/@counted and @mcptool -- with every decision made by the build: a generated BackendWiring constructs and injects the beans with plain code, and aspects are woven into the annotated methods. No container, scan, proxy or reflection at run time. Runtime: thread-bound transactions that the pool, daos and sessions join, a cron and fixed-rate scheduler with an optional database lock, task executors including fd-less virtual-thread tasks with a per-host wake pipe, HTTP sessions (memory or JDBC store), OTLP metrics and management endpoints, and an MCP endpoint with development tools. Also fixes the sticky virtual-thread yield reason (yieldNow from a handler hung), a handler taking HttpServer.Request being refused, and adds the backend and full-stack references to the generated agent skill. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@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. |
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6dd51f4064
ℹ️ 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 172 screenshots: 172 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows x64Runner CPU: AMD64 Family 25 Model 17 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 regression is a ratio more than 15% (time) / 15% (RAM) above its baseline in
Result: no regression |
|
Compared 172 screenshots: 172 matched. Benchmark ResultsDetailed Performance Metrics
|
Cloudflare Preview
|
|
Compared 172 screenshots: 172 matched. ParparVM vs HotSpot (JDK 25): Linux x64Runner CPU: AMD EPYC 7763 64-Core Processor (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 regression is a ratio more than 15% (time) / 15% (RAM) above its baseline in
Result: no regression |
|
Compared 172 screenshots: 172 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 regression is a ratio more than 15% (time) / 15% (RAM) above its baseline in
Result: no regression |
|
Compared 172 screenshots: 172 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 regression is a ratio more than 15% (time) / 15% (RAM) above its baseline in
Result: no regression |
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
|
Compared 193 screenshots: 193 matched. |
- Sessions: the session cookie goes on a copy of the handler's Response, never into it (it may be a shared constant); cn1.session.secure refuses anything but auto/true/false. - TaskExecutor: virtual submissions are refused after shutdown and counted active before the hand-off; @async accessors re-fetch a shut-down executor. - MCP: only loopback or listed origins pass (the Host match let DNS rebinding through); byte/short tool arguments are range-checked; backend_call uses https against a TLS server. - Request metrics are recorded in a finally, so failures count and the route label is cleared. - Factory beans inherit their configuration class's @Profile and @ConditionalOnProperty; request-scoped beans' destroyMethod runs. - Scheduler lock: an INSERT failure with no existing row is rethrown. - OTLP histogram bucket_counts stays fixed64 (per metrics.proto), now held by a test decoding with the generated opentelemetry-proto classes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Compared 157 screenshots: 157 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
|
Compared 150 screenshots: 150 matched. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e31da12f35
ℹ️ 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 155 screenshots: 155 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
…lit the guide Review fixes: - Sessions, MCP tools and managed beans are per server (Backend.getSessions, Environment.registerTool/registerManaged, Builder.mcpTool); two servers in one process no longer share cookies, sessions or tools. - @SessionScope beans are kept by the server for the session's lifetime and destroyed on invalidate, expiry and stop; a negative session timeout fails. - Transactions: no process-wide default pool; a NESTED method before the first statement sets its savepoint after BEGIN. setRollbackOnly in the method that began the transaction rolls back without throwing. - Backend.stop runs destroy callbacks once; a failed start destroys built beans; management routes precede application handlers; session-store failures are logged as 500s; metrics shutdown is bounded by its timeout. - Weaving keeps synchronized on the body, so a synchronized @async method holds its monitor where it runs. - Injection points and lifecycle methods inherited from base classes are wired; @ConditionalOnMissingBean matches the bean's exposed types and takes explicit ones. Docs: the backend chapter is split into nine chapters (web, beans, data and transactions, sessions, scheduling, observability, MCP, operations) with diagrams and compiled samples. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Compared 223 screenshots: 223 matched. |
|
Compared 166 screenshots: 166 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 regression is a ratio more than 15% (time) / 15% (RAM) above its baseline in
Result: no regression |
|
Compared 155 screenshots: 155 matched. Benchmark Results
Build and Run Timing
Detailed Performance Metrics
|
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 28cad305bb
ℹ️ 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 154 screenshots: 154 matched. Benchmark Results
Detailed Performance Metrics
|
- Executors belong to the server that opened them: request, task, scheduler and start-up threads carry it, stopping one server no longer shuts down another's, and generated @async code looks the executor up per call. At the shutdown deadline queued tasks are dropped rather than run against destroyed beans, and running ones are interrupted; a virtual task a host cannot run falls back to its own executor. - Every server applies cn1.session.* (handler-only ones sent a TLS session cookie without Secure); a failing request still stores its session so its session beans are kept or destroyed. - Request beans are destroyed while their request is still current; @PreDestroy runs subclass before superclass; factory beans run inherited lifecycle methods. - Health reports STARTING until the start-up hook returns. - A cron time inside a DST gap is skipped instead of firing an hour late. - The metrics exporter can be reopened; histograms copy and validate their bounds and labels. - A managed resource must be a singleton and cannot overload operations. Co-Authored-By: Claude Opus 5.5 (1M context) <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: d4d761e707
ℹ️ 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".
…ations - Backend no longer names Management or McpServer. Only the builder's management() and mcp() do, and the generated entry point calls them only when the build asked (@enablemanagement / @EnableMcpServer / an @mcptool / a literal cn1.*.enabled=true in any application*.properties, or a dev build). The translator drops the uncalled builder method and the classes with it; BackendOtelTest now asserts from nm that a server that never asked carries neither, against a control that links both. - Typed settings annotations -- @serverconfig, @SessionConfig, @DataSourceConfig, @StaticFilesConfig, exporter settings on @opentelemetry, paths on the Enable* ones -- compiled in as the bottom configuration layer (Config.withCompiledDefaults), under the files and the environment. Values the runtime would refuse, and two classes disagreeing, are build errors naming the class. - OtlpTracerTest.partialSuccessIsCounted waited on a flush that could run before the request's span was queued (the span ends after the response is written); it now waits for the span first. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…as JSON A route may now return an entity or DTO (and collections or String-keyed maps of them) and take one as @RequestBody, as a Spring controller does through Jackson. The build writes a <Name>Cn1Json codec per class -- plain code, no reflection -- in the app's @mapped JSON form, so a class shared by app and backend round-trips: fields (public directly, others via bean accessors), @JsonProperty/@JsonIgnore (now shared with the backend), Date as epoch millis (read from millis or ISO-8601), byte[] base64, enums by name, subclasses written as themselves, unknown members ignored. - A body the codec refuses is a 400 naming the path ($.lines[0].quantity: expected ...); a response nesting past 64 objects (a cycle) is a 500 pointing at @JsonIgnore. - Generic type-variable fields, body classes without a no-arg constructor, interfaces, arrays other than byte[], and runtime types such as HttpServer.Response inside a list stay build errors, with the reason. - HttpServer renders a deferred JSON body before the write, into the same buffer, so a throw there (a Writable, a codec) is answered 500 and recorded as the handler's failure instead of dropping the connection unanswered. - The guide's order example is compiled from the guide's own files and run end to end by BackendBeansTest. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…host A virtual thread used to park only on the socket it served. An outbound read -- a PostgreSQL or MySQL query, a Web call, a TLS handshake -- did a blocking recv() on the host pthread, and with one host per core that many slow calls stopped the server answering anything. - Native: a per-virtual-thread wait record (descriptors, events, timeout) and cn1BackendVtWait/cn1BackendAwaitFd; resume answers WAITING (3) for it. Outbound Tcp descriptors stay non-blocking for life and every wait (connect, read, write, TLS handshake/read/write) parks on a virtual thread and polls anywhere else, so platform threads behave as before. SO_RCVTIMEO/SO_SNDTIMEO become the wait's deadline. Web drives libcurl through the multi interface on a virtual thread. - Host: WAITING registers the descriptors with the host's own poller for exactly the wait, wakes on readiness or deadline, and the stop drain keeps pumping tasks that wait on outbound I/O. - Docs/javadoc/skill: network databases, Web and TLS are fine on VIRTUAL; SQLite, file access, host-name resolution and Object.wait still block. - Tests: SelfTest (Tcp, Web, TLS handshake, TLS read, read deadline) and DbCheck (pg_sleep / SLEEP against a one-host server) prove another request is served while the call waits; both fail with the old blocking wait. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- The seven AvoidUsingHardCodedIP findings are loopback and wildcard literals that recognise or bind the local interface and dial nothing; each carries a //NOPMD with that reason, the convention ServerSocket and Credentials already use. The OwnRoute overrides get @OverRide. - SelfTest exercises JsonCodec on the translated runtime: range and fraction refusals with their paths, dates from millis and ISO-8601 with offsets and fractions, an impossible date refused, base64, writeDate. Co-Authored-By: Claude Opus 5.5 (1M context) <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: 903a18fb09
ℹ️ 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".
…and paths - An Object or raw Map/List field is written by its run-time class through a generated cn1app.JsonValues: a class the build writes goes through its codec, Date as millis, enums by name, JDK shapes through Json; any other class is a 500 instead of its toString(). - A TreeSet body needs a Comparable element; refused at build time otherwise. - readLong bounds a fractional-free double by 2^63 before converting, so 9223372036854775808.0 is refused instead of clamped to Long.MAX_VALUE. - MCP and management match the canonical path (pathFrom), as the routers, static files and relay do: /%6dcp is /mcp. - MCP answers an allowed origin's CORS preflight before authentication and names the origin on every reply to it (new Response.header). - The guide's order example uses one source block per include, which the snippet validator requires. Co-Authored-By: Claude Opus 5.5 (1M context) <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: 8a415127f0
ℹ️ 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".
…s, lease check - PINNING. ParparVM identifies a monitor's owner by its OS thread, which every virtual thread on a host shares, so a virtual thread that parked inside `synchronized` let the next one on that host into the same critical section. With outbound I/O now parking, that became likely. A virtual thread now counts the monitors it holds (one TLS load per monitorEnter/ Exit, zero off a virtual thread) and never switches out while the count is above zero: every park -- socket wait, collector handshake, nap -- asks cn1BackendCanPark/cn1VirtualThreadPinned and waits like a platform thread instead. SelfTest reproduces the interleave on one host: two requests waiting on a slow socket inside one monitor; with pinning disabled it sees two inside at once. - DataSource reserves pool capacity under its monitor and opens the connection outside it, and a virtual thread waits for a free connection by napping rather than wait(); DbCheck runs concurrent lazy opens on one host against real PostgreSQL. - @mcptool parameters other than scalars are read through the shared JSON codecs (List<Integer> holds Integers, DTOs are built, a bad value is a tool error naming its path), results are written through them, and shapes they cannot serve are build errors. The codec set is shared between the bean and router processors. - A scheduler claim that lands after its lease ran out is not run. - Response.header no longer fully qualifies an imported class (forbidden PMD). - The DB session purge's cross-replica limit is recorded as a Spring-matching decision. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
…stay parkable With virtual threads pinned while they hold a monitor, Database's synchronized methods pinned every query, and a PostgreSQL or MySQL wait held its host again -- DbCheck's "another request is served while a query waits" failed on one host. The exclusion a connection needs (one operation at a time, a transaction reserved to its caller) is now a reentrant gate: a flag taken and returned under a monitor held only for that instant. A virtual thread waiting for it naps; anything else waits on the monitor as before. Transaction ownership is keyed by the virtual thread, not Thread.currentThread(), which every virtual thread on a host shares, and a caller waiting on another's transaction gives the gate up meanwhile, as wait() gave up the monitor. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fbe9a07fc5
ℹ️ 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".
…rved - A body value read into float or Float is refused (400) when a float cannot hold it, instead of narrowing 1e100 to infinity or 1e-100 to zero; the same rule MCP float arguments already had. - @Timed/@counted names are checked against the server's own instruments at build time, by name and by Prometheus series. Taken at run time, the clash surfaced in the woven finally after the body's work had committed. - An Object or raw collection field holding a class with no codec stays a run-time 500 by design; the reasoning is in BackendJsonCodecs.check. Co-Authored-By: Claude Opus 5.5 (1M context) <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: e86694ec3a
ℹ️ 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".
…ntry fixes - Two classes whose JSON codec names fold together (Outer_Inner and Outer.Inner) are a build error instead of one codec silently replacing the other. - Every class the bean processor generates -- aspects, proxies, tool and managed adapters, codecs -- is checked against the project's own classes before it is compiled; an existing class of that name is a build error instead of being overwritten in the output directory. - Subclass dispatch walks ancestors on the compile classpath too, so a project subclass reaching the declared type through a dependency's class is written with its own fields. - A module whose only request is @enablemanagement gets an entry point. Each has a test asserting the failure or the outcome; the dispatch and entry-point tests fail with their fixes reverted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
CodenameOne/vm/backend/src/com/codename1/backend/Config.java
Lines 441 to 445 in 3666deb
When a lower-priority properties file defines a string setting and deployment deliberately supplies an empty system-property override, this treats the empty value as absent and silently reactivates the file value. For example, -Dcn1.static.root= cannot disable a static root compiled into application.properties, so files continue to be served despite the highest-priority layer explicitly clearing the setting; accept a present empty property here and let each setting's reader decide what empty means.
ℹ️ 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".
…cket fallbacks - An @ManagedOperation returning anything beyond a scalar or String is written through the JSON codecs; one returning a shape they cannot write is a build error. A DTO result was sent as its quoted toString(). - A websocket fallback router sees the server's sessions on the handshake (the upgrade bypasses the request wrapper), and what the handshake did to them is stored and released afterwards. - perf-baseline: calibrate linux-x64@amd-epyc-9v45-96-core-processor, a runner CPU model the gate had no row for (ratios within the spread of the existing AMD/Intel linux rows). Co-Authored-By: Claude Opus 5.5 (1M context) <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: 114c900cd0
ℹ️ 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".
…ounted servers - An @ManagedAttribute that is not a number or a boolean is a build error; it was listed under /manage/managed and silently missing from metrics. - A module that only serves static files (@StaticFilesConfig or cn1.static.root in a properties file) gets an entry point. - cn1.management.path=/ mounts the endpoints at the server root instead of being refused as not starting with /. Each has a test; the two outcome tests fail with their fix reverted. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Swish! 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". |
The arm64 gate flagged stringBuilding RAM at 0.32x against a 0.26x baseline. Not a regression: the VM, JavaAPI and benchmark are identical between this head and 3666deb, which read 0.27x, and master reads 0.26x on every run -- the same code, two readings, one row's RAM moving between runs. The baseline stays 0.26x; the row gets the 0.3 memory tolerance other noisy RAM rows carry, so +30% is still a regression. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…plates Master's Spring-style backend beans (#5908) land in build-engine, where the annotation processors moved: the dev-tools switch goes through BackendPackager for both plugins (-Pcn1.backend.devTools for Gradle), the bean tests run there with their SQLite driver, and the Gradle backend templates gain the Greeter service the archetype now injects into Api. Conversion's untouched-skeleton check expects that pair, and the Gradle backend checks call /greet so the wiring is exercised, not just /healthz. The skill's new backend references give the Gradle tasks beside the Maven goals. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
What
The backend now reads like a Spring application --
@Service,@Autowired,@Value,@ConfigurationProperties,@Bean, scopes,@Profile/@ConditionalOnProperty,@Transactional,@Async,@Scheduled,@ManagedResource/@Timed/@Counted,@McpTool-- all undercom.codename1.backend.annotations, and all resolved at build time:BackendBeanAnnotationProcessorresolves the bean graph and the entry point's generatedBackendWiringconstructs and injects every bean with straight-linenew/setter calls. Private@Autowiredfields get a woven setter. Missing, ambiguous or cyclic dependencies are build errors naming the injection point.@Transactional,@Async,@Timed,@Countedrewrite the method itself (body moved aside, the method delegates to a generated helper) -- no proxy, so self-calls, private methods andnew-built objects get them too.Transactions(all seven propagations, savepoints, read-only) thatDataSource, daos and managed sessions join;Scheduler(cron masks computed by the build, fixed rate/delay, DB lock across replicas);Tasks/TaskExecutorincluding fd-less virtual-thread tasks with a per-host wake pipe;HttpSessionwith memory and JDBC stores; OTLP metrics +/manageendpoints (health, JSON, Prometheus, jobs, managed beans); an MCP endpoint serving@McpToolmethods and, on dev profiles, development tools (backend_routes,backend_beans,backend_call,backend_requests,backend_sql, ...), excluded fromcn1:backend-packageby default.backend.mdandfull-stack-loop.mdreferences in the Initializr skill, archetype/Initializr backend sample with an injected service, new Backend guide sections with compiled snippets.Fixes found on the way
yieldNow()from a handler hung and IO parks after GC backpressure were misreported as runnable; each yield site now sets its reason.Future.get()on a virtual thread blocked the host and could wedge every host; it now yields cooperatively.HttpServer.Requestwas refused ($vs.in the nested type name).Verification
vm/testsbackend suites (HTTP 72/72, WebSocket, OTel, runtime self-test, DB/ORM on all three engines) pass; a sample packaged withcn1:backend-packageexercised every feature and survived a 7000-request concurrent soak.Known limits
Aspects apply to project classes only; request/session/lazy beans need a non-final class with a no-arg constructor (run once for the stand-in); no transaction isolation levels; session-bean
@PreDestroynot run on expiry;cn1app-archetype-test.shextended but not run locally.🤖 Generated with Claude Code