Repository navigation
feat(devloop): run on various application servers (#25851) (CP: 25.3) - #26066
Conversation
Fixes #25458 **Background — how the loop reaches the application.** The dev loop hot swaps by attaching two `-javaagent` jars to the JVM the application runs in and redefining classes through `Instrumentation`. For a server that runs inside the build's own JVM, that JVM is Maven's, so `MAVEN_OPTS` carries them and there is nothing else to arrange. Until now the loop could only run an application whose server shared the build's JVM. It now also runs WildFly, TomEE, Payara Server, Payara Micro, Open Liberty and Apache Tomcat, which each start a server of their own, with the agents travelling in a plugin parameter that reaches the forked JVM. Two fixes and an integration-test fixture come with it. **Context.** Nothing on Maven's command line and nothing in its environment reaches a JVM that Maven forked, so each forked container needs a channel of its own. Four of them expose one as a user property and Liberty as a property prefix; Cargo exposes none that any command line can set, which is why it is the one runtime that cannot work without the loop's build extension. - Added WildFly and TomEE as runtimes, with the JVM flags travelling in `wildfly.javaOpts` and `tomee-plugin.args`, module options folded into one token for WildFly, and backslashes doubled for TomEE alone - Added Payara Server and Payara Micro, both on the `start` goal, never `dev`, whose watcher redeploys in competition with every apply - Payara Server's `payara.javaCommandLineOptions` is a `List<String>`, which Maven splits on commas and the mojo then drops any piece without an `=` in it, so comma-bearing flags travel in a JVM argument file instead - Added Open Liberty, whose channel is one Maven property per flag (`liberty.jvm.<key>`), with `looseApplication` forced off so that Liberty's own application monitor stops competing with every apply - Added Apache Tomcat, driven through Codehaus Cargo, in one entry that answers for every container Cargo drives - Its flags go on the model as the `cargo.jvmargs` project property, because no parameter of its run goal carries a user property, and the build extension appends to a value a project set itself rather than replacing it - Switched the run goal off for the whole reactor and back on for the application's module for Cargo, both Payaras and WildFly: unlike Jetty's, their mojos do not skip a project that builds no deployment, and failed or blocked the build on the reactor root - A forked container now names `package` across the reactor as well, so a sibling module reaches `WEB-INF/lib` as a jar rather than as a directory - Gave a forked container a startup window of its own, since provisioning a server outruns the time an ordinary boot is given - Confirmed a resource against the bytes on the classpath before counting it as changed, so a rewritten-but-identical file is no longer a change - Tried both loopback literals when the application dials the daemon, after a Payara Micro boot left the application JVM preferring `::1` while the daemon listened on `127.0.0.1` and the application ran unregistered - Moved the agent's `Instrumentation` handle out of the system properties, which WildFly's transactions subsystem read as a string and died on - Added `test-devloop-cargo`, a third IT fixture running the shared dev-loop ITs against a WAR deployed on Tomcat 11, and wired it into the CI matrix - Adds a fixture per forked server the dev loop drives, each running the shared suite from flow-test-devloop-support in dev-bundle mode, and runs them in CI slots 9 and 10. Liberty is served under /devloop, so the ITs read a context path from the fixture pom. --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: mikhail <mikhail@vaadin.com> Co-authored-by: Mikhail Shabarov <61410877+mshabarov@users.noreply.github.com>
The loop's agents now reach a forked server's JVM, not only Maven's ownflowchart LR
subgraph Before
direction TB
B1["MavenGoalRuntime.invocation()"] -->|jvmFlags into MAVEN_OPTS| B2["Maven's own JVM"]
B2 -->|DevLoopAgent redefines classes| B3["Jetty app"]
end
subgraph After
direction TB
A1["MavenGoalRuntime.invocation()"] -->|embedded: jvmFlags into MAVEN_OPTS| A2["Maven's own JVM"]
A2 -->|DevLoopAgent redefines classes| A3["Jetty app"]
A1 -->|forked: jvmFlags into -D jvmFlagsProperty| A4["server plugin (new)"]:::changed
A4 -->|starts, passing the flags| A5["forked server JVM (new)"]:::changed
A5 -->|DevLoopAgent redefines classes| A6["WildFly / TomEE / Payara / Liberty / Tomcat app (new)"]:::changed
end
Before ~~~ After
classDef changed stroke:#c9a227,stroke-width:3px
Diagram Bot draws the mechanism this pull request touches; it does not review the change. Verify it against the diff.
|
|
This PR is eligible for auto-merging policy, so it has been approved automatically. If there are pending conditions, auto merge (with 'squash' method) has been enabled for this PR [Message is sent from bot] |
|



This PR cherry-picks changes from the original PR #25851 to branch 25.3.
Original PR description