* fix(cli): fall back to node_modules for @uatu/spec resolution
Drop the hard failure when the uatu source tree is not reachable from
the spec file. Users integrating uatu in their own app have @uatu/spec
installed via npm; esbuild now resolves it from node_modules.
* build(gradle): drop :sample-app include from root settings
The sample now has its own Gradle project in examples/sample-app/android.
* build(sample-app): vendor gradle wrapper
Users running the sample build the APK via ./gradlew from inside the
sample-app's own android/ directory, no repo-root wrapper required.
* build(sample-app): make gradle project standalone
Drop the project(':sdk-android') dependency in favor of the Maven
Central coordinate io.github.priyanshujain:sdk-android. The sample now
owns its settings.gradle.kts and gradle.properties, so it builds
without any pieces of the uatu source tree.
* chore(sample-app): declare @uatu/spec npm dependency
Mirrors what a downstream user would put in their own package.json.
Uses file: for pre-release development; becomes a normal semver pin
once @uatu/spec ships to npm.
* docs(sample-app): rewrite justfile and add README
Justfile drops repo_root; all recipes run against the local gradle
wrapper and uatu from PATH. README is scoped to what a user needs to
run the sample against their own device.
* docs(manual): update sample install steps to standalone layout
./gradlew :sample-app:installDebug no longer exists; the sample owns
its own wrapper under android/.
* feat(sdk): log when Uatu.start succeeds
Silent SDK start makes the "SDK didn't connect" failure mode
impossible to debug. One INFO line at start time is enough.
* fix(sidecar): launch via am start -W instead of monkey
monkey -p <pkg> -c LAUNCHER 1 is unreliable on API 36+: it reports no
error but silently fails to start the activity, so the SDK never runs
and the CLI times out on the SDK-accept handshake.
Resolve the launcher activity via `cmd package resolve-activity
--brief` and launch it with `am start -W -n`. -W makes the call block
until the activity is up, which also makes the subsequent SDK
accept timing deterministic.
* feat(cli): auto-resolve Android device; boot AVD if none connected
--avd becomes optional. Resolution order:
- use any already-connected adb device;
- else if --avd names an existing AVD, boot it and wait for boot;
- else if --avd is missing or names no AVD, error with a clear message.
Falls back to $ANDROID_HOME/emulator/emulator when the binary is not on
PATH, so a standard Android SDK install works without extra shell setup.
* docs(sample-app): AVD is optional; document both paths
just test runs against any connected device. If none, pass AVD=<name>
to have uatu boot the emulator for you.
* feat(cli): auto-discover Android SDK; auto-pick the lone AVD
adb and emulator are looked up via PATH, then $ANDROID_HOME,
$ANDROID_SDK_ROOT, ~/Library/Android/sdk, ~/Android/Sdk, and the
Homebrew cask path. The discovered platform-tools directory is
prepended to the sidecar's PATH so its adb subprocess calls work too.
When --avd isn't passed and no device is connected, the CLI picks the
sole local AVD and boots it. Multiple AVDs → error listing them.
* build(make): add `make install` that go-installs uatu onto PATH
Puts `uatu` into $GOBIN (or $GOPATH/bin) so the sample and any local
dev flow can call it without PATH= prefixes.
* docs(sample-app): zero-config just test; dotenv-load for persistence
Drop the expectation that users prefix commands with PATH=, ANDROID_HOME=,
or AVD=. `just test` now works as-is; optional knobs can be pinned in a
.env file alongside the justfile.
* fix(sample-app): auto-detect ANDROID_HOME for Gradle tasks
The Go CLI finds the SDK itself, but AGP still needs ANDROID_HOME to
resolve `sdk.dir`. The justfile now resolves it from env or canonical
install paths before invoking ./gradlew, so `just install` works out
of the box on a standard Android SDK setup.
* gitignore runs directory for sample app
3.5 KiB
Dokka / Java 25 publish failure
What fails
Running ./gradlew :sdk-android:publishToMavenLocal (or any task that triggers javaDocReleaseGeneration) on a JDK 25 host crashes with:
Execution failed for task ':sdk-android:javaDocReleaseGeneration'.
> A failure occurred while executing com.android.build.gradle.tasks.JavaDocGenerationTask$DokkaWorkAction
...
Caused by: java.lang.IllegalArgumentException: 25.0.2
at com.intellij.util.lang.JavaVersion.parse(JavaVersion.java:298)
Why it happens
The publish flow is:
com.vanniktech.maven.publish:0.30.0(declared insdk/android/build.gradle.kts:7) configures anAndroidSingleVariantLibrarywithpublishJavadocJar = true.- That wires AGP's
JavaDocGenerationTaskinto the release publication. The task runs Dokka in aWorkAction. - Dokka ships a vendored copy of IntelliJ's platform SDK. When it boots, it probes the JDK version by calling
com.intellij.util.lang.JavaVersion.parse(System.getProperty("java.version")). - On the host JDK the property is literally the string
"25.0.2". Dokka's bundledJavaVersion.parse(an older IntelliJ build) only understands the legacy patterns (1.8.0_x,9,11.0.x, etc.) and refuses version 25's format, throwingIllegalArgumentException: 25.0.2. - The worker dies, Gradle marks
javaDocReleaseGenerationfailed, and the whole publish lifecycle aborts before any POM or AAR is written.
Why it's latent in CI
CI runs on JDK 17 per build.gradle.kts compile targets and whatever actions/setup-java installs. "17.0.x" matches the old format, so the bundled JavaVersion.parse doesn't blow up. The bug only surfaces on developer machines running JDK 21+ where the version string format changed, and reliably on JDK 25.
Workaround
./gradlew :sdk-android:publishToMavenLocal -x javaDocReleaseGeneration
The AAR, sources jar, and POM publish cleanly; only the Javadoc jar is skipped. That produces a usable 0.0.0-dev artifact for local testing but is not a substitute for a real release publish, since Maven Central validation requires the Javadoc jar.
Possible fixes
-
Bump the
vanniktech.maven.publishplugin to a version that ships a newer Dokka. The0.30.0version pinned here is from mid-2024. Newer releases (0.33+) bundle Dokka 2.x, which has rewritten the JDK detection path and handles modern version strings. One line insdk/android/build.gradle.kts, no build config change. Requires verifying the plugin's breaking changes for the publish config. -
Pin a compatible Dokka directly. Add
id("org.jetbrains.dokka") version "1.9.20"(or later) so the plugin picks up Dokka's own fix for IntelliJJavaVersion.parse. Slightly more invasive; you now manage Dokka independently from the publish plugin. -
Force a JDK toolchain for the javadoc task. Add a
java { toolchain { languageVersion = JavaLanguageVersion.of(17) } }block scoped to the SDK module (or usetasks.withType<JavaDocGenerationTask> { javaLauncher.set(...) }). Gradle downloads JDK 17 and runs Dokka under it regardless of the host JDK. Robust but adds a toolchain dependency to every dev machine's first build. -
Don't generate a Javadoc jar. Flip
publishJavadocJar = falsein the vanniktech config. Kills the problem by removing the failing path. Not viable for Maven Central release (they require a Javadoc jar).
Recommendation
Option 1. Smallest diff, addresses the root cause, keeps the publish pipeline intact for Central releases, and newer plugin versions also bring AGP 8.x compatibility improvements.