Skip to content

Fix UI build due to Ktor upgrade#4572

Merged
dsmiley merged 4 commits into
apache:mainfrom
dsmiley:FixUiBuildForDockerCi
Jul 1, 2026
Merged

Fix UI build due to Ktor upgrade#4572
dsmiley merged 4 commits into
apache:mainfrom
dsmiley:FixUiBuildForDockerCi

Conversation

@dsmiley

@dsmiley dsmiley commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

I observed the Docker nightly GHA based CI build is failing on main branch alone -- see here.

Claude's analysis:

Root Cause: The Ktor upgrade from 3.2.2 → 3.4.2 (commit 995b450) introduced node:net usage in the CIO engine's wasmJs target. CIO on wasmJs uses Node.js socket APIs,
which work for wasmJs-Node but not for wasmJs-Browser (which is what webpack builds for). Webpack rightfully refuses to bundle node:net in a browser target.

Proposed Fix: Move ktor-client-cio from commonMain dependencies to desktopMain only, and add a wasmJs-specific source set that uses the Ktor JS/WasmJs engine
(ktor-client-js) which uses fetch() — the correct HTTP API for browser environments.

This PR implements that change.

dsmiley added 2 commits June 30, 2026 10:54
Ktor 3.4+ CIO engine uses Node.js sockets (node:net) for wasmJs,
which is incompatible with browser webpack targets. Split the HTTP
client engine per platform: ktor-client-js (fetch API) for wasmJs
browser, ktor-client-cio for desktop/JVM only.
@dsmiley

dsmiley commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

I don't know why this problem is (apparently?) only happening on that particular Docker nightly CI build. I don't know how to validate/test this change, to be honest. I'm looking for review!

As an aside... I wish our build didn't require node/npm as it's another build/dependency system that requires configuration and that which can be problematic with some corporate environments with HTTP proxies, etc. Consequently I couldn't even really evaluate this PR on one of my machines, as I have a hack to my local config to not do the UI build because I can't there.

@janhoy

janhoy commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

I wish our build didn't require node/npm as it's another build/dependency system that requires configuration

Agree. I wonder if we could make the Kotlin AdminUI app a separate build in the monorepo, also with separate releases (standalone and js). Then our main build would somehow consume a pre-built artifact instead of building the UI app from scratch.

@janhoy janhoy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not tried to deeply understand the failure or the fix, but I asked Claude to do a code review on the PR and here it is:


The approach looks correct to me. Since getDefaultClient() in HttpClientUtils.kt calls HttpClient { ... } with no explicit engine, the engine is resolved by Ktor's auto-discovery from whatever is on each target's classpath. Moving ktor-client-cio to desktopMain keeps the CIO engine for the JVM/desktop target, and ktor-client-js provides the fetch-based engine for the wasmJs browser target — exactly what's needed.

The lockfile diff is a good confirmation the root cause is addressed: the ktor-network / ktor-network-tls wasm-js variants (which transitively brought in the node:net usage) are no longer on the wasmJs classpath. Tests use MockEngine via ktor-client-mock, so they're unaffected.

One minor ordering nit below. Otherwise LGTM.

Comment thread gradle/libs.versions.toml Outdated
ktor-client-auth = { module = "io.ktor:ktor-client-auth" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio" }
ktor-client-contentNegotiation = { module = "io.ktor:ktor-client-content-negotiation" }
ktor-client-js = { module = "io.ktor:ktor-client-js" }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: the aliases here should be in alphabetical order

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I thought the linter would also complain about this?

@jaykay12 jaykay12 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not reviewing the PR codewise.

But these changes do fix the broken ./gradlew dev for sure. Verified.

main branch this branch
Screenshot 2026-07-01 at 3 29 33 AM Screenshot 2026-07-01 at 3 31 04 AM

janhoy added a commit to janhoy/solr that referenced this pull request Jul 1, 2026
…nce apache#4572 merges)

Squashed changes from apache#4572 'Fix UI build due to Ktor upgrade' (dsmiley)
to unblock CI/testing of this branch. Without it the solr:ui wasmJs browser webpack
build fails on node:net, forcing -PdisableUiModule=true locally.

THIS COMMIT IS TEMPORARY and must be dropped/reverted once apache#4572 is merged to main
and this branch is rebased onto it.
…resources

The Compose resource accessor generation tasks were not reliably wired as
dependencies of the Kotlin compile tasks, notably compileKotlinWasmJs. On
incremental or reordered builds the compile could fire before the accessors
existed, failing with "Source file or directory not found" for the generated
commonMainResourceAccessors (Drawable0/String0.commonMain.kt). Wire every
compileKotlin* task to depend on all generateResourceAccessorsFor* tasks.

@malliaridis malliaridis left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. The change with the engine dependencies is correct and as far as I remember the better way.

I used the CIO engine for all targets as it was a single dependency that worked on all targets the best, with best feature support as well. By now things have changed over the time, and it may not be the best engine to use across all platforms.

About the asset issue, I was not aware, nor can I exactly follow the wiring here. But if it is confirmed to solve the issue, it's fine. Should not break anything at least.

I wish our build didn't require node/npm

Note that the AdminUI is using node under the hood, but still expects the build environment to be compatible with it. There is however another node integration in gradle/node.gradle which is probably replaceable.

I wonder if we could make the Kotlin AdminUI app a separate build in the monorepo, also with separate releases (standalone and js)

I will look into this. Normally it should be easy to do so by introducing a separate settings.gradle.kts file in that module and excluding it from the existing one. This would also allow us to split the module into UI feature modules in the long run, which I was considering too.

The tricky part with this is depending on the build artifacts of the admin UI without waiting for any build to happen. Probably via GitHub artifacts, but what about any other CI/CD pipelines? Will they be able to fetch the artifacts during builds?

I will investigate and create a draft PR for that. :)

@dsmiley dsmiley merged commit 7b9b3d3 into apache:main Jul 1, 2026
4 of 5 checks passed
@dsmiley dsmiley deleted the FixUiBuildForDockerCi branch July 1, 2026 14:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants