diff --git a/.gitattributes b/.gitattributes index a28fef80..e6949018 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,2 @@ * text=auto eol=lf Cargo.lock -diff linguist-generated -pnpm-lock.yaml -diff linguist-generated -packages/client/src/bindings.ts -diff linguist-generated=true -.github/actions/publish-artifacts/dist/index.js -diff linguist-generated=true -.github/actions/clippy/dist/index.js -diff linguist-generated=true diff --git a/.sqlx/query-a3bd6cf3048a6a5ed9d29e6bbb7f517676fe715c8af45eb5c58d69073e2d0304.json b/.sqlx/query-010f5dcda59ec32eaad1b9c3e2e9807f547a1376372c8b201653a36d6dd14cbc.json similarity index 65% rename from .sqlx/query-a3bd6cf3048a6a5ed9d29e6bbb7f517676fe715c8af45eb5c58d69073e2d0304.json rename to .sqlx/query-010f5dcda59ec32eaad1b9c3e2e9807f547a1376372c8b201653a36d6dd14cbc.json index 032726f5..33514fa6 100644 --- a/.sqlx/query-a3bd6cf3048a6a5ed9d29e6bbb7f517676fe715c8af45eb5c58d69073e2d0304.json +++ b/.sqlx/query-010f5dcda59ec32eaad1b9c3e2e9807f547a1376372c8b201653a36d6dd14cbc.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n\t\tINSERT INTO java_versions (absolute_path, major, version, vendor, os_arch)\n\t\tVALUES (?, ?, ?, ?, ?)\n\t\tON CONFLICT(absolute_path) DO UPDATE SET\n\t\t\tmajor = excluded.major,\n\t\t\tversion = excluded.version,\n\t\t\tvendor = excluded.vendor,\n\t\t\tos_arch = excluded.os_arch\n\t\tRETURNING absolute_path, major, version, vendor, os_arch\n\t\t", + "query": "\n\t\tINSERT INTO java_versions (absolute_path, major, version, vendor, os_arch, is_jdk)\n\t\tVALUES (?, ?, ?, ?, ?, ?)\n\t\tON CONFLICT(absolute_path) DO UPDATE SET\n\t\t\tmajor = excluded.major,\n\t\t\tversion = excluded.version,\n\t\t\tvendor = excluded.vendor,\n\t\t\tos_arch = excluded.os_arch,\n\t\t\tis_jdk = excluded.is_jdk\n\t\tRETURNING absolute_path, major, version, vendor, os_arch, is_jdk as \"is_jdk: bool\"\n\t\t", "describe": { "columns": [ { @@ -57,18 +57,30 @@ "name": "os_arch" } } + }, + { + "name": "is_jdk: bool", + "ordinal": 5, + "type_info": "Integer", + "origin": { + "Table": { + "table": "java_versions", + "name": "is_jdk" + } + } } ], "parameters": { - "Right": 5 + "Right": 6 }, "nullable": [ false, false, false, false, + false, false ] }, - "hash": "a3bd6cf3048a6a5ed9d29e6bbb7f517676fe715c8af45eb5c58d69073e2d0304" + "hash": "010f5dcda59ec32eaad1b9c3e2e9807f547a1376372c8b201653a36d6dd14cbc" } diff --git a/.sqlx/query-c1d3cf930d5f38e8f1046da1a8f895ee1de2d3fe9a40ecb47731618962d2a4ad.json b/.sqlx/query-0d9fb5d2fa8a788770e946241ea2f62f4b794c0fdda3ccbde49384689911aeba.json similarity index 75% rename from .sqlx/query-c1d3cf930d5f38e8f1046da1a8f895ee1de2d3fe9a40ecb47731618962d2a4ad.json rename to .sqlx/query-0d9fb5d2fa8a788770e946241ea2f62f4b794c0fdda3ccbde49384689911aeba.json index e65480d4..5da3a9d7 100644 --- a/.sqlx/query-c1d3cf930d5f38e8f1046da1a8f895ee1de2d3fe9a40ecb47731618962d2a4ad.json +++ b/.sqlx/query-0d9fb5d2fa8a788770e946241ea2f62f4b794c0fdda3ccbde49384689911aeba.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT absolute_path, major, version, vendor, os_arch FROM java_versions \n ORDER BY major DESC, version DESC\n ", + "query": "\n SELECT absolute_path, major, version, vendor, os_arch, is_jdk as \"is_jdk: bool\"\n FROM java_versions\n ORDER BY major DESC, version DESC\n ", "describe": { "columns": [ { @@ -57,6 +57,17 @@ "name": "os_arch" } } + }, + { + "name": "is_jdk: bool", + "ordinal": 5, + "type_info": "Integer", + "origin": { + "Table": { + "table": "java_versions", + "name": "is_jdk" + } + } } ], "parameters": { @@ -67,8 +78,9 @@ false, false, false, + false, false ] }, - "hash": "c1d3cf930d5f38e8f1046da1a8f895ee1de2d3fe9a40ecb47731618962d2a4ad" + "hash": "0d9fb5d2fa8a788770e946241ea2f62f4b794c0fdda3ccbde49384689911aeba" } diff --git a/.sqlx/query-b153f762849649456dd97b6a5cd35fb7dafc3d5539441328e03442cea195483a.json b/.sqlx/query-33771b7003e64c8f19d15d663de773afa568d626c60a37bbc32cc932746ad49b.json similarity index 75% rename from .sqlx/query-b153f762849649456dd97b6a5cd35fb7dafc3d5539441328e03442cea195483a.json rename to .sqlx/query-33771b7003e64c8f19d15d663de773afa568d626c60a37bbc32cc932746ad49b.json index 7551bc03..caaad113 100644 --- a/.sqlx/query-b153f762849649456dd97b6a5cd35fb7dafc3d5539441328e03442cea195483a.json +++ b/.sqlx/query-33771b7003e64c8f19d15d663de773afa568d626c60a37bbc32cc932746ad49b.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n\t\tSELECT absolute_path, major, version, vendor, os_arch\n\t\tFROM java_versions\n\t\tWHERE major = ?\n\t\tORDER BY version DESC\n\t\tLIMIT 1\n\t\t", + "query": "\n\t\tSELECT absolute_path, major, version, vendor, os_arch, is_jdk as \"is_jdk: bool\"\n\t\tFROM java_versions\n\t\tWHERE major = ?\n\t\tORDER BY version DESC\n\t\tLIMIT 1\n\t\t", "describe": { "columns": [ { @@ -57,6 +57,17 @@ "name": "os_arch" } } + }, + { + "name": "is_jdk: bool", + "ordinal": 5, + "type_info": "Integer", + "origin": { + "Table": { + "table": "java_versions", + "name": "is_jdk" + } + } } ], "parameters": { @@ -67,8 +78,9 @@ false, false, false, + false, false ] }, - "hash": "b153f762849649456dd97b6a5cd35fb7dafc3d5539441328e03442cea195483a" + "hash": "33771b7003e64c8f19d15d663de773afa568d626c60a37bbc32cc932746ad49b" } diff --git a/.sqlx/query-bbbc24e8d4f13a39ebce8e8598f4adbc864909984313ea1c065ba226465b23ca.json b/.sqlx/query-bbbc24e8d4f13a39ebce8e8598f4adbc864909984313ea1c065ba226465b23ca.json new file mode 100644 index 00000000..b79fa719 --- /dev/null +++ b/.sqlx/query-bbbc24e8d4f13a39ebce8e8598f4adbc864909984313ea1c065ba226465b23ca.json @@ -0,0 +1,62 @@ +{ + "db_name": "SQLite", + "query": "\n\t\tSELECT DISTINCT ca.cluster_id, ca.hash, ca.cluster_file_name, ca.enabled\n\t\tFROM cluster_artifacts ca\n\t\tJOIN provider_releases pr ON pr.hash = ca.hash\n\t\tWHERE ca.cluster_id = ?\n\t\t\tAND pr.provider = ?\n\t\t\tAND pr.project_id = ?\n\t\t\tAND ca.hash <> ?\n\t\t", + "describe": { + "columns": [ + { + "name": "cluster_id", + "ordinal": 0, + "type_info": "Integer", + "origin": { + "Table": { + "table": "cluster_artifacts", + "name": "cluster_id" + } + } + }, + { + "name": "hash", + "ordinal": 1, + "type_info": "Text", + "origin": { + "Table": { + "table": "cluster_artifacts", + "name": "hash" + } + } + }, + { + "name": "cluster_file_name", + "ordinal": 2, + "type_info": "Text", + "origin": { + "Table": { + "table": "cluster_artifacts", + "name": "cluster_file_name" + } + } + }, + { + "name": "enabled", + "ordinal": 3, + "type_info": "Integer", + "origin": { + "Table": { + "table": "cluster_artifacts", + "name": "enabled" + } + } + } + ], + "parameters": { + "Right": 4 + }, + "nullable": [ + false, + false, + false, + false + ] + }, + "hash": "bbbc24e8d4f13a39ebce8e8598f4adbc864909984313ea1c065ba226465b23ca" +} diff --git a/.sqlx/query-c570e309195b6063cf0fbee866d68972de05107769dab983524fd2e74a7ae31a.json b/.sqlx/query-f5992c9cec6a6d7015cda4c04b463bd5fd9c42ac38b434fa8a0c0fe4f7517cf2.json similarity index 76% rename from .sqlx/query-c570e309195b6063cf0fbee866d68972de05107769dab983524fd2e74a7ae31a.json rename to .sqlx/query-f5992c9cec6a6d7015cda4c04b463bd5fd9c42ac38b434fa8a0c0fe4f7517cf2.json index 5b597ea9..27530fbf 100644 --- a/.sqlx/query-c570e309195b6063cf0fbee866d68972de05107769dab983524fd2e74a7ae31a.json +++ b/.sqlx/query-f5992c9cec6a6d7015cda4c04b463bd5fd9c42ac38b434fa8a0c0fe4f7517cf2.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "\n SELECT absolute_path, major, version, vendor, os_arch FROM java_versions \n WHERE absolute_path = ?\n ", + "query": "\n SELECT absolute_path, major, version, vendor, os_arch, is_jdk as \"is_jdk: bool\"\n FROM java_versions\n WHERE absolute_path = ?\n ", "describe": { "columns": [ { @@ -57,6 +57,17 @@ "name": "os_arch" } } + }, + { + "name": "is_jdk: bool", + "ordinal": 5, + "type_info": "Integer", + "origin": { + "Table": { + "table": "java_versions", + "name": "is_jdk" + } + } } ], "parameters": { @@ -67,8 +78,9 @@ false, false, false, + false, false ] }, - "hash": "c570e309195b6063cf0fbee866d68972de05107769dab983524fd2e74a7ae31a" + "hash": "f5992c9cec6a6d7015cda4c04b463bd5fd9c42ac38b434fa8a0c0fe4f7517cf2" } diff --git a/packages/oneclient_core/src/java_store.rs b/packages/oneclient_core/src/java_store.rs index 19825701..78ea52df 100644 --- a/packages/oneclient_core/src/java_store.rs +++ b/packages/oneclient_core/src/java_store.rs @@ -30,6 +30,7 @@ fn row_to_runtime(row: JavaVersionRow) -> JavaRuntime { version: row.version, vendor: JavaVendor::from_str(&row.vendor).unwrap_or(JavaVendor::Other(row.vendor)), os_arch: row.os_arch, + is_jdk: row.is_jdk, } } @@ -43,6 +44,7 @@ impl JavaStore for SqlJavaStore { &runtime.version, &runtime.vendor.to_string(), &runtime.os_arch, + runtime.is_jdk, ) .await .map_err(StoreError::new)?; diff --git a/packages/oneclient_db/migrations/20260802120000_java_is_jdk.sql b/packages/oneclient_db/migrations/20260802120000_java_is_jdk.sql new file mode 100644 index 00000000..0de5e00b --- /dev/null +++ b/packages/oneclient_db/migrations/20260802120000_java_is_jdk.sql @@ -0,0 +1,5 @@ +-- Whether a recorded runtime is a development kit rather than a bare runtime +-- image. Probing for it means spawning the java process, so it is remembered +-- alongside the version instead. Rows written before this migration default to +-- 0 and are corrected the next time they are probed. +ALTER TABLE `java_versions` ADD COLUMN `is_jdk` INTEGER NOT NULL DEFAULT 0; diff --git a/packages/oneclient_db/src/dao/java.rs b/packages/oneclient_db/src/dao/java.rs index 39081203..98d79183 100644 --- a/packages/oneclient_db/src/dao/java.rs +++ b/packages/oneclient_db/src/dao/java.rs @@ -10,24 +10,27 @@ pub async fn insert( version: &str, vendor: &str, os_arch: &str, + is_jdk: bool, ) -> Result { sqlx::query_as!( JavaVersionRow, r#" - INSERT INTO java_versions (absolute_path, major, version, vendor, os_arch) - VALUES (?, ?, ?, ?, ?) + INSERT INTO java_versions (absolute_path, major, version, vendor, os_arch, is_jdk) + VALUES (?, ?, ?, ?, ?, ?) ON CONFLICT(absolute_path) DO UPDATE SET major = excluded.major, version = excluded.version, vendor = excluded.vendor, - os_arch = excluded.os_arch - RETURNING absolute_path, major, version, vendor, os_arch + os_arch = excluded.os_arch, + is_jdk = excluded.is_jdk + RETURNING absolute_path, major, version, vendor, os_arch, is_jdk as "is_jdk: bool" "#, absolute_path, i64::from(major), version, vendor, os_arch, + is_jdk, ) .fetch_one(pool) .await @@ -41,7 +44,8 @@ pub async fn get_by_path( let row = sqlx::query_as!( JavaVersionRow, r#" - SELECT absolute_path, major, version, vendor, os_arch FROM java_versions + SELECT absolute_path, major, version, vendor, os_arch, is_jdk as "is_jdk: bool" + FROM java_versions WHERE absolute_path = ? "#, absolute_path, @@ -59,7 +63,7 @@ pub async fn get_latest_by_major( let row = sqlx::query_as!( JavaVersionRow, r#" - SELECT absolute_path, major, version, vendor, os_arch + SELECT absolute_path, major, version, vendor, os_arch, is_jdk as "is_jdk: bool" FROM java_versions WHERE major = ? ORDER BY version DESC @@ -90,7 +94,8 @@ pub async fn list_all(pool: &SqlitePool) -> Result, DbError> let rows = sqlx::query_as!( JavaVersionRow, r#" - SELECT absolute_path, major, version, vendor, os_arch FROM java_versions + SELECT absolute_path, major, version, vendor, os_arch, is_jdk as "is_jdk: bool" + FROM java_versions ORDER BY major DESC, version DESC "#, ) diff --git a/packages/oneclient_db/src/models/java.rs b/packages/oneclient_db/src/models/java.rs index 6293f4e3..246cee22 100644 --- a/packages/oneclient_db/src/models/java.rs +++ b/packages/oneclient_db/src/models/java.rs @@ -7,4 +7,5 @@ pub struct JavaVersionRow { pub version: String, pub vendor: String, pub os_arch: String, + pub is_jdk: bool, } diff --git a/packages/oneclient_java/assets/java/JavaInfo.class b/packages/oneclient_java/assets/java/JavaInfo.class index 0b9e4e9d..a76328e4 100644 Binary files a/packages/oneclient_java/assets/java/JavaInfo.class and b/packages/oneclient_java/assets/java/JavaInfo.class differ diff --git a/packages/oneclient_java/assets/java/JavaInfo.java b/packages/oneclient_java/assets/java/JavaInfo.java index 1e89916b..b846ad7a 100644 --- a/packages/oneclient_java/assets/java/JavaInfo.java +++ b/packages/oneclient_java/assets/java/JavaInfo.java @@ -14,11 +14,7 @@ public final class JavaInfo { } } - // Minecraft needs AWT. Stripped, headless and hand-jlinked images drop - // java.desktop and only blow up once the game reaches for it. System.out.println("java.awt=" + hasClass("java.awt.Toolkit")); - // A kit ships a compiler, a runtime image does not. On 8 this finds the - // one in tools.jar, on 9+ the jdk.compiler module. System.out.println("java.jdk=" + hasCompiler()); System.exit(returnCode); diff --git a/packages/oneclient_java/src/checker.rs b/packages/oneclient_java/src/checker.rs index f6bc6615..b4d89dd8 100644 --- a/packages/oneclient_java/src/checker.rs +++ b/packages/oneclient_java/src/checker.rs @@ -1,7 +1,4 @@ -use std::{ - collections::HashMap, - path::{Path, PathBuf}, -}; +use std::{collections::HashMap, path::PathBuf}; use async_tempfile::TempDir; use tokio::sync::OnceCell; @@ -10,19 +7,6 @@ use crate::error::{JavaError, JavaResult}; const JAVA_INFO_CLASS: &[u8] = include_bytes!("../assets/java/JavaInfo.class"); -/// Tools that only ever ship with a development kit, never with a runtime image. -const JAVAC_BIN: &str = if cfg!(windows) { "javac.exe" } else { "javac" }; -const JMOD_BIN: &str = if cfg!(windows) { "jmod.exe" } else { "jmod" }; - -/// The native library behind `java.awt`. An image linked without `java.desktop` -/// simply does not ship it. -#[cfg(target_os = "windows")] -const AWT_LIBRARY: &str = "awt.dll"; -#[cfg(target_os = "macos")] -const AWT_LIBRARY: &str = "libawt.dylib"; -#[cfg(all(unix, not(target_os = "macos")))] -const AWT_LIBRARY: &str = "libawt.so"; - #[derive(Debug, Clone, PartialEq, Eq)] pub struct JavaCheckInfo { pub version: String, @@ -84,15 +68,12 @@ pub async fn check_java_runtime(absolute_path: String) -> JavaResult JavaResult bool { - is_jdk_home(&java_home(absolute_path, None)) -} - -/// Whether `home` is a development kit rather than a runtime image. -/// -/// Directory names lie in both directions (`.../jdk-21/jre`, runtimes unpacked -/// into a folder someone called `jdk`), so this only looks for artefacts a -/// runtime image never carries: the compiler, `jmod`, the JDK 8 `tools.jar`, -/// and the JNI headers. -pub(crate) fn is_jdk_home(home: &Path) -> bool { - let bin = home.join("bin"); - - bin.join(JAVAC_BIN).is_file() - || bin.join(JMOD_BIN).is_file() - || home.join("jmods").is_dir() - || home.join("lib").join("tools.jar").is_file() - || home.join("include").join("jni.h").is_file() -} - -/// The installation root. -/// -/// `java.home` as the probe reports it is authoritative; when the compiled -/// probe class predates that property we fall back to the executable's own -/// location, resolving symlinks first so a `/usr/bin/java` shim lands in the -/// real home rather than in `/usr`. -fn java_home(absolute_path: &str, reported: Option<&String>) -> PathBuf { - if let Some(home) = reported.filter(|home| !home.is_empty()) { - return PathBuf::from(home); - } - - let executable = std::fs::canonicalize(absolute_path) - .unwrap_or_else(|_| PathBuf::from(absolute_path)); - - executable - .parent() - .and_then(Path::parent) - .map(Path::to_path_buf) - .unwrap_or(executable) -} - -/// Whether `java.awt` is there: the probe's own answer when it gave one, and -/// otherwise what the installation ships on disk. -fn has_awt_support(info: &HashMap, home: &Path) -> bool { - if let Some(reported) = probe_flag(info, "java.awt") { - return reported; - } - - // Java 9+ images record the modules they were linked with. - if let Some(modules) = release_modules(home) { - return modules.split_whitespace().any(|module| module == "java.desktop"); - } - - // Java 8, and anything else without a `release` file: AWT is a native - // library sitting next to the runtime. - awt_library_exists(home) -} - -/// The `MODULES` line of an image's `release` file, if it has one. -fn release_modules(home: &Path) -> Option { - let release = std::fs::read_to_string(home.join("release")).ok()?; - - release.lines().find_map(|line| { - let modules = line.strip_prefix("MODULES=")?; - Some(modules.trim_matches('"').to_string()) - }) -} - -fn awt_library_exists(home: &Path) -> bool { - // Windows keeps native libraries in `bin` and everyone else in `lib`; a - // JDK 8 also nests a whole runtime under `jre`. - [ - home.join("lib"), - home.join("bin"), - home.join("jre").join("lib"), - home.join("jre").join("bin"), - ] - .iter() - .any(|dir| dir.join(AWT_LIBRARY).exists()) -} - -/// Reads a boolean the probe printed, `None` when it printed no such line. -fn probe_flag(info: &HashMap, key: &str) -> Option { - info.get(key).map(|value| value.eq_ignore_ascii_case("true")) +/// Reads a boolean the probe printed; anything else counts as `false`. +fn probe_flag(info: &HashMap, key: &str) -> bool { + info.get(key) + .is_some_and(|value| value.eq_ignore_ascii_case("true")) } static TEMP_JAVA_INFO: OnceCell = OnceCell::const_new(); @@ -232,126 +128,14 @@ mod tests { .collect() } - fn touch(path: &Path) { - if let Some(parent) = path.parent() { - std::fs::create_dir_all(parent).expect("create parent"); - } - std::fs::write(path, b"").expect("write file"); - } - - #[tokio::test] - async fn a_runtime_image_is_not_mistaken_for_a_kit() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path(); - - touch(&home.join("bin").join("java")); - touch(&home.join("lib").join("modules")); - - assert!(!is_jdk_home(home)); - } - - #[tokio::test] - async fn a_kit_is_recognised_by_its_compiler() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path(); - - touch(&home.join("bin").join("java")); - touch(&home.join("bin").join(JAVAC_BIN)); - - assert!(is_jdk_home(home)); - } - - #[tokio::test] - async fn a_kit_is_recognised_by_its_headers_alone() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path(); - - touch(&home.join("bin").join("java")); - touch(&home.join("include").join("jni.h")); - - assert!(is_jdk_home(home)); - } - - #[tokio::test] - async fn a_legacy_kit_is_recognised_by_tools_jar() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path(); - - touch(&home.join("lib").join("tools.jar")); - - assert!(is_jdk_home(home)); - } - - #[tokio::test] - async fn the_directory_name_alone_proves_nothing() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path().join("jdk-21"); - - touch(&home.join("bin").join("java")); - - assert!(!is_jdk_home(&home)); + #[test] + fn a_flag_the_probe_never_printed_is_false() { + assert!(!probe_flag(&info(&[]), "java.awt")); } #[test] - fn the_probe_has_the_last_word_on_awt() { - let missing = Path::new("/nonexistent-java-home"); - - assert!(has_awt_support(&info(&[("java.awt", "true")]), missing)); - assert!(!has_awt_support(&info(&[("java.awt", "false")]), missing)); - } - - #[tokio::test] - async fn a_module_list_without_java_desktop_fails_the_check() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path(); - - std::fs::write( - home.join("release"), - "JAVA_VERSION=\"21.0.3\"\nMODULES=\"java.base java.logging\"\n", - ) - .expect("write release"); - - assert!(!has_awt_support(&info(&[]), home)); - } - - #[tokio::test] - async fn a_module_list_with_java_desktop_passes() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path(); - - std::fs::write( - home.join("release"), - "JAVA_VERSION=\"21.0.3\"\nMODULES=\"java.base java.desktop java.logging\"\n", - ) - .expect("write release"); - - assert!(has_awt_support(&info(&[]), home)); - } - - #[tokio::test] - async fn a_release_less_image_falls_back_to_the_native_library() { - let dir = polyio::tempdir().await.expect("tempdir"); - let home = dir.dir_path(); - - assert!(!has_awt_support(&info(&[]), home)); - - touch(&home.join("lib").join(AWT_LIBRARY)); - - assert!(has_awt_support(&info(&[]), home)); - } - - #[test] - fn a_missing_home_falls_back_to_the_executable_location() { - let home = java_home("/opt/jdk-21/bin/java", None); - - assert_eq!(home, PathBuf::from("/opt/jdk-21")); - } - - #[test] - fn a_reported_home_wins_over_the_executable_location() { - let reported = String::from("/opt/real-home"); - let home = java_home("/usr/bin/java", Some(&reported)); - - assert_eq!(home, PathBuf::from("/opt/real-home")); + fn a_flag_is_read_regardless_of_case() { + assert!(probe_flag(&info(&[("java.awt", "TRUE")]), "java.awt")); + assert!(!probe_flag(&info(&[("java.awt", "false")]), "java.awt")); } } diff --git a/packages/oneclient_java/src/data.rs b/packages/oneclient_java/src/data.rs index 038e335e..d7364c36 100644 --- a/packages/oneclient_java/src/data.rs +++ b/packages/oneclient_java/src/data.rs @@ -12,6 +12,10 @@ pub struct JavaRuntime { pub version: String, pub vendor: JavaVendor, pub os_arch: String, + /// Whether this is a development kit rather than a bare runtime image, as + /// the probe reported it when the runtime was recorded (see + /// [`crate::JavaCheckInfo::is_jdk`]). + pub is_jdk: bool, } diff --git a/packages/oneclient_java/src/service.rs b/packages/oneclient_java/src/service.rs index 8fda005f..9ccf5bad 100644 --- a/packages/oneclient_java/src/service.rs +++ b/packages/oneclient_java/src/service.rs @@ -149,7 +149,7 @@ impl JavaService { let recorded = self.store.latest_by_major(major).await?; if let Some(runtime) = &recorded - && checker::is_jdk_executable(&runtime.absolute_path) + && runtime.is_jdk { return Ok(runtime.clone()); } @@ -347,6 +347,7 @@ impl JavaService { vendor: JavaVendor::from_str(&info.vendor) .unwrap_or_else(|_| JavaVendor::Other(info.vendor.clone())), os_arch: info.os_arch.clone(), + is_jdk: info.is_jdk, }; Ok(self.store.upsert(&runtime).await?)