# HG changeset patch # User Jiri Vanek # Date 1550243011 -3600 # Node ID 6a1effecd739758fb1d7d9e102e8be66e9bd5203 # Parent 0ec171908528cb70b953fa3d9652d7781c8b5ed1 Native launchers got support for modular jdk (via @MODULARJDK_ARGS_LOCATION file) * rust-launcher/src/hardcoded_paths.rs: introduced MODULARJDK_ARGS_LOCATION recognition * rust-launcher/src/jars_helper.rs: now are able search in bin, and this reads MODULARJDK_ARGS_LOCATION * rust-launcher/src/main.rs: now reads java -version, and if modular, put MODULARJDK_ARGS_LOCATION to args * rust-launcher/src/os_access.rs: removed duplicated code form windows in java spawn, extracted args creation so it could be reused for java version recognition * rust-launcher/src/property.rs: added note about Unicode failure in case properties (thus jre location) contains \u values diff -r 0ec171908528 -r 6a1effecd739 ChangeLog --- a/ChangeLog Wed Feb 13 19:14:35 2019 +0100 +++ b/ChangeLog Fri Feb 15 16:03:31 2019 +0100 @@ -1,3 +1,13 @@ +2019-02-15 Jiri Vanek + + Native launchers got support for modular jdk (via @MODULARJDK_ARGS_LOCATION file) + * rust-launcher/src/hardcoded_paths.rs: introduced MODULARJDK_ARGS_LOCATION recognition + * rust-launcher/src/jars_helper.rs: now are able search in bin, and this reads MODULARJDK_ARGS_LOCATION + * rust-launcher/src/main.rs: now reads java -version, and if modular, put MODULARJDK_ARGS_LOCATION to args + * rust-launcher/src/os_access.rs: removed duplicated code form windows in java spawn, extracted args creation + so it could be reused for java version recognition + * rust-launcher/src/property.rs: added note about Unicode failure in case properties (thus jre location) contains \u values + 2019-02-13 Alex Kashchenko Os trait implemented for windows diff -r 0ec171908528 -r 6a1effecd739 rust-launcher/src/hardcoded_paths.rs --- a/rust-launcher/src/hardcoded_paths.rs Wed Feb 13 19:14:35 2019 +0100 +++ b/rust-launcher/src/hardcoded_paths.rs Fri Feb 15 16:03:31 2019 +0100 @@ -18,6 +18,7 @@ const TAGSOUP_JAR: Option<&'static str> = option_env!("TAGSOUP_JAR"); const RHINO_JAR: Option<&'static str> = option_env!("RHINO_JAR"); const ITW_LIBS: Option<&'static str> = option_env!("ITW_LIBS"); +const MODULARJDK_ARGS_LOCATION: Option<&'static str> = option_env!("MODULARJDK_ARGS_LOCATION"); pub fn get_jre() -> &'static str { @@ -63,6 +64,10 @@ pub fn get_rhino() -> Option<&'static str> { RHINO_JAR } +pub fn get_argsfile() -> &'static str { + MODULARJDK_ARGS_LOCATION.unwrap_or("MODULARJDK_ARGS_LOCATION-dev-unspecified") +} + #[derive(PartialEq)] pub enum ItwLibSearch { @@ -137,6 +142,7 @@ assert_ne!(String::from(super::get_splash()).trim(), String::from("SPLASH_PNG-dev-unspecified")); assert_ne!(String::from(super::get_netx()).trim(), String::from("NETX_JAR-dev-unspecified")); assert_ne!(String::from(super::get_itwlibsearch()).trim(), String::from("ITW_LIBS-dev-unspecified")); + assert_ne!(String::from(super::get_argsfile()).trim(), String::from("MODULARJDK_ARGS_LOCATION-dev-unspecified")); } #[test] @@ -149,6 +155,7 @@ assert_ne!(String::from(super::get_splash()).trim(), String::from("")); assert_ne!(String::from(super::get_netx()).trim(), String::from("")); assert_ne!(String::from(super::get_itwlibsearch()).trim(), String::from("")); + assert_ne!(String::from(super::get_argsfile()).trim(), String::from("")); } #[test] diff -r 0ec171908528 -r 6a1effecd739 rust-launcher/src/jars_helper.rs --- a/rust-launcher/src/jars_helper.rs Wed Feb 13 19:14:35 2019 +0100 +++ b/rust-launcher/src/jars_helper.rs Fri Feb 15 16:03:31 2019 +0100 @@ -16,7 +16,24 @@ "../linux-deps-runtime", "../win-deps-runtime", "../win-deps-all", - "."]; + ".", + "bin", + "../bin"]; + +pub fn resolve_argsfile(logger: &os_access::Os) -> std::path::PathBuf { + resolve_jar(hardcoded_paths::get_argsfile(), logger) +} + +pub fn resolve_jsobject(logger: &os_access::Os) -> Option { + match hardcoded_paths::get_jsobject() { + Some(js) => { + Some(resolve_jar(js, logger)) + } + None => { + None + } + } +} pub fn resolve_splash(logger: &os_access::Os) -> std::path::PathBuf { diff -r 0ec171908528 -r 6a1effecd739 rust-launcher/src/main.rs --- a/rust-launcher/src/main.rs Wed Feb 13 19:14:35 2019 +0100 +++ b/rust-launcher/src/main.rs Fri Feb 15 16:03:31 2019 +0100 @@ -139,7 +139,17 @@ os.log("itw-rust-debug: splash excluded"); } } - + if is_modular_jdk(os, &java_dir) { + all_args.push(resolve_argsfile(os)); + let js_object_candidate = get_jsobject_patchmodule(os); + match js_object_candidate { + Some(js_object_path) => { + all_args.push(js_object_path.0); + all_args.push(js_object_path.1); + } + _none => {} + } + } all_args.push(bootcp); all_args.push(String::from("-classpath")); all_args.push(cp); @@ -152,6 +162,78 @@ all_args } +fn is_modular_jdk(os: &os_access::Os, jre_dir: &std::path::PathBuf) -> bool { + if jdk_version(os, jre_dir) > 8 { + os.log("itw-rust-debug: modular jdk"); + true + } else { + os.log("itw-rust-debug: non-modular jdk"); + false + } +} + +fn jdk_version(os: &os_access::Os, jre_dir: &std::path::PathBuf) -> i32 { + let vec = vec!["-version".to_string()]; + //this of course fails during tests + let output_result = os_access::create_java_cmd(os, jre_dir, &vec).output(); + match output_result { + Ok(output) => { + for line in String::from_utf8(output.stderr).expect("java version was supopsed to return output").lines() { + if line.contains("version") + && (line.contains("\"1") + || line.contains("\"2") + || line.contains("\"3")) { + if line.contains("\"1.7.0") || line.contains("\"1.7.1") { + os.log("itw-rust-debug: detected jdk 7"); + return 7 + } else if line.contains("\"1.8.0") { + os.log("itw-rust-debug: detected jdk 8"); + return 8 + } else { + //currently this serves only to determine module/non modular jdk + os.log("itw-rust-debug: detected jdk 9 or up"); + return 9 + } + } + } + os.log("itw-rust-debug: unrecognized jdk! Fallback to 8!"); + return 8; + } + _Error => { + os.log("itw-rust-debug: failed to launch jdk recognition. fallback to 8"); + return 8 + } + } +} + +fn resolve_argsfile(os: &os_access::Os) -> String { + let args_location = dirs_paths_helper::path_to_string(&jars_helper::resolve_argsfile(os)); + let mut owned_string: String = args_location.to_owned(); + let splash_switch: &str = "@"; + owned_string.insert_str(0, splash_switch); + let r = String::from(owned_string); + r +} + + +fn get_jsobject_patchmodule(os: &os_access::Os) -> Option<(String, String)> { + let js_object_candidate = jars_helper::resolve_jsobject(os); + match js_object_candidate { + Some(js_object_path) => { + let args_location = dirs_paths_helper::path_to_string(&js_object_path); + let mut owned_string: String = args_location.to_owned(); + let splash_switch: &str = "jdk.jsobject="; + owned_string.insert_str(0, splash_switch); + let r = String::from(owned_string); + let tuple = ("--patch-module".to_string(), r); + return Some(tuple) + } + None => { + return None + } + } +} + fn get_splash(os: &os_access::Os) -> Option { let headless = is_headless_enforced(); let splash_forbidden = is_splash_forbidden(); diff -r 0ec171908528 -r 6a1effecd739 rust-launcher/src/os_access.rs --- a/rust-launcher/src/os_access.rs Wed Feb 13 19:14:35 2019 +0100 +++ b/rust-launcher/src/os_access.rs Fri Feb 15 16:03:31 2019 +0100 @@ -3,7 +3,32 @@ use std::env; use std::fmt::Write; +pub fn create_java_cmd(os: &Os,jre_dir: &std::path::PathBuf, args: &Vec) -> std::process::Command { + let mut bin_java = jre_dir.clone(); + bin_java.push("bin"); + bin_java.push("java"); + let mut cmd = std::process::Command::new(&bin_java); + for ar in args.into_iter() { + cmd.arg(ar); + } + let mut info = String::new(); + write!(&mut info, "itw-rust-debug: command {}", format!("{:?}", cmd)).expect("unwrap failed"); + os.log(&info); + return cmd; +} +fn spawn_java_process(os: &Os, jre_dir: &std::path::PathBuf, args: &Vec) -> std::process::Child { + let mut cmd = create_java_cmd(os, jre_dir, args); + cmd.stdin(std::process::Stdio::inherit()); + cmd.stdout(std::process::Stdio::inherit()); + cmd.stderr(std::process::Stdio::inherit()); + let res = cmd.spawn(); + match res { + Ok(child) => child, + Err(_) => panic!("Error spawning JVM process, \ + java executable: [{}], arguments: [{:?}]", jre_dir.clone().into_os_string().to_str().expect("path should unwrap"), args) + } +} pub trait Os { // logging "api" can change @@ -86,25 +111,7 @@ } fn spawn_java_process(&self, jre_dir: &std::path::PathBuf, args: &Vec) -> std::process::Child { - let mut bin_java = jre_dir.clone(); - bin_java.push("bin"); - bin_java.push("java"); - let mut cmd = std::process::Command::new(&bin_java); - for ar in args.into_iter() { - cmd.arg(ar); - } - cmd.stdin(std::process::Stdio::inherit()); - cmd.stdout(std::process::Stdio::inherit()); - cmd.stderr(std::process::Stdio::inherit()); - let mut info = String::new(); - write!(&mut info, "itw-rust-debug: command {}", format!("{:?}", cmd)).expect("unwrap failed"); - self.log(&info); - let res = cmd.spawn(); - match res { - Ok(child) => child, - Err(_) => panic!("Error spawning JVM process, \ - java executable: [{}], arguments: [{:?}]", bin_java.into_os_string().to_str().expect("path should unwrap"), args) - } + spawn_java_process(self, jre_dir, args) } fn get_home(&self) -> Option { @@ -193,25 +200,8 @@ } fn spawn_java_process(&self, jre_dir: &std::path::PathBuf, args: &Vec) -> std::process::Child { - let mut bin_java = jre_dir.clone(); - bin_java.push("bin"); - bin_java.push("java"); - let mut cmd = std::process::Command::new(&bin_java); - for ar in args.into_iter() { - cmd.arg(ar); - } - cmd.stdin(std::process::Stdio::inherit()); - cmd.stdout(std::process::Stdio::inherit()); - cmd.stderr(std::process::Stdio::inherit()); - let mut info = String::new(); - write!(&mut info, "itw-rust-debug: command {}", format!("{:?}", cmd)).expect("unwrap failed"); - self.log(&info); - let res = cmd.spawn(); - match res { - Ok(child) => child, - Err(_) => panic!("Error spawning JVM process, \ - java executable: [{}], arguments: [{:?}]", bin_java.into_os_string().to_str().expect("path should unwrap"), args) - } + //there was an intention, which caused all the os trait, to implement this better. However developer (alex) faield and gave up + spawn_java_process(self, jre_dir, args) } fn get_home(&self) -> Option { diff -r 0ec171908528 -r 6a1effecd739 rust-launcher/src/property.rs --- a/rust-launcher/src/property.rs Wed Feb 13 19:14:35 2019 +0100 +++ b/rust-launcher/src/property.rs Fri Feb 15 16:03:31 2019 +0100 @@ -63,6 +63,15 @@ } } +//error[E0658]: use of unstable library feature 'str_escape': return type may change to be an iterator (see issue #27791) +// +// let a = kvv.value.escape_unicode(); +//For more information about this error, try `rustc --explain E0658`. +//https://icedtea.classpath.org/bugzilla/show_bug.cgi?id=3697 +fn escape_unicode(src: String) -> String { + src +} + fn check_file_for_property(file: File, key: &str) -> Option { let bf = BufReader::new(file); for lineresult in bf.lines() { @@ -76,7 +85,7 @@ None => {} Some(kvv) => { if kvv.key.eq(key) { - return Some(kvv.value); + return Some(escape_unicode(kvv.value)); } } }