You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Broaden the simulated LSP session and register the Path watch types
The session that drives both the tracing agent and the JVM-vs-native
comparison left several code paths untouched, and four of its probes
compared an empty result against an empty result:
- completion on main.nf returned nothing, because member completion on a
complete expression has no answer to give
- previewDag was passed a process name where the second argument is a
workflow name, so it returned null and neither DataflowVisitor nor
MermaidRenderer ever ran
- documentLink returned nothing, because links come from include
statements and the workspace had a single file
- documentSymbol on the config file can only ever return nothing, as the
config service has no symbol provider
So: point completion at positions that resolve (an identifier, the top
level, and a member of the lowercase channel namespace), pass null to
previewDag for the entry workflow, add a module that usage.nf includes,
and drop the config documentSymbol probe. Also cover the handlers that
were never exercised: didChange, incoming/outgoingCalls, and the three
remaining commands. The comparison goes from 27 messages to 42.
That immediately failed, which is the point of it:
NoClassDefFoundError: Unable to configure java.nio.file.Path due to
missing dependency java.nio.file.WatchEvent$Modifier
Groovy configures the Path class node for the Path shim type and
enumerates its methods, one of which is register(WatchService, Kind[],
Modifier...). Nothing calls it, so native-image left the watch types out
of the image entirely and the first completion request that resolved a
Path failed with an internal error. Registering that closure fixes it.
Also correct the ADR: tracing contributes the reflective entries behind
Groovy's indy call sites and five META-INF/services files, not the JSSE
provider graph or JDK icu resources -- no config directory registers
anything for those. Since nothing exercises the plugin registry, the
HTTPS path it needs is covered by neither source, which is now recorded
as a residual risk.
Copy file name to clipboardExpand all lines: adr/20260804-graalvm-native-image-build.md
+3-1Lines changed: 3 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -70,7 +70,7 @@ Add a GraalVM 21 `native-image` build producing `nextflow-lsp` for linux-amd64 a
70
70
71
71
### Extracting reflection metadata
72
72
73
-
`generateNativeImageMetadata` scans the resolved runtime classpath and emits `reflect-config.json`, `resource-config.json` and `proxy-config.json`, registering ~630 classes. Registration flags are set per group rather than uniformly, since image size is driven by reachability; the per-group reasoning lives in comments in `build.gradle`. The tracing agent remains a secondary source, for the tail that resists enumeration: Groovy indy call sites reaching `MethodHandleNatives`, JDK-internal resources with version-specific paths, and the JSSE provider graph loaded reflectively for the plugin-registry HTTPS call. `native-image` merges the two, static config first.
73
+
`generateNativeImageMetadata` scans the resolved runtime classpath and emits `reflect-config.json`, `resource-config.json` and `proxy-config.json`, registering ~630 classes. Registration flags are set per group rather than uniformly, since image size is driven by reachability; the per-group reasoning lives in comments in `build.gradle`. The tracing agent remains a secondary source, for the tail that resists enumeration: the reflective entries behind Groovy's indy call sites, and the `META-INF/services` files that the JDK and Groovy load through `ServiceLoader`. `native-image` merges the two, static config first.
74
74
75
75
A scan is exhaustive where a traced session is accidental. The reflected-over sets are *closed* — Gson reflects over every type in `org.eclipse.lsp4j`, and Groovy's `configureClassNode` over every class handed to `ClassHelper.makeCached` — and those are properties of the jars, so scanning enumerates them completely and picks up dependency upgrades automatically. Traced coverage is instead a function of the script: the session used here reaches 2 of the 35 `nextflow.script.types.**` classes, and whatever it misses is not reported at build time, because the `--report-unsupported-elements-at-runtime` that Groovy's indy call sites force turns what would be build errors into runtime no-ops.
76
76
@@ -88,6 +88,8 @@ The JAR is the only available oracle. Unit tests run on the JVM and say nothing
88
88
89
89
-**A macOS-specific regression would go unnoticed**, since CI builds Linux only.
90
90
91
+
-**The plugin registry is not covered.** Resolving `include { ... } from 'plugin/...'` fetches over HTTPS, which brings in `HttpClient` and the JSSE provider graph — reflection-heavy territory, and no config directory registers anything for it today. The session deliberately stays offline, so this would first fail for a user rather than in CI.
0 commit comments