summaryrefslogtreecommitdiffstats
path: root/src/modules/utils
diff options
context:
space:
mode:
authoryuri <1969yuri1969@gmail.com>2019-10-25 03:00:05 +0200
committerMatan Kushner <hello@matchai.me>2019-10-25 10:00:05 +0900
commitb7762a3e9185000b920a8777bd8aa1fb77eacc56 (patch)
tree0c8fd0c2ed888aa6bfadf3c90aa86ddae6a76bda /src/modules/utils
parentedf5176c37f7a309e72dc486f5659d2193d24336 (diff)
fix: Show Java version from OpenJ9 Java runtimes (#507)
This PR tries to improve the version detection across multiple Java VM vendors. The module captures both STDOUT and STDERR outputs of the java -Xinternalversion call. Eclipse OpenJ9, Azul Zulu, SapMachine, Amazon Corretto and GraalVM outputs are unit tested now.
Diffstat (limited to 'src/modules/utils')
-rw-r--r--src/modules/utils/java_version_parser.rs65
-rw-r--r--src/modules/utils/mod.rs1
2 files changed, 66 insertions, 0 deletions
diff --git a/src/modules/utils/java_version_parser.rs b/src/modules/utils/java_version_parser.rs
new file mode 100644
index 000000000..cf9445dfe
--- /dev/null
+++ b/src/modules/utils/java_version_parser.rs
@@ -0,0 +1,65 @@
+use nom::{
+ branch::alt,
+ bytes::complete::{tag, take_until, take_while1},
+ combinator::rest,
+ sequence::{preceded, tuple},
+ IResult,
+};
+
+fn is_version(c: char) -> bool {
+ c >= '0' && c <= '9' || c == '.'
+}
+
+fn version(input: &str) -> IResult<&str, &str> {
+ take_while1(&is_version)(input)
+}
+
+fn zulu(input: &str) -> IResult<&str, &str> {
+ let zulu_prefix_value = preceded(take_until("("), tag("("));
+ preceded(zulu_prefix_value, version)(input)
+}
+
+fn jre_prefix(input: &str) -> IResult<&str, &str> {
+ preceded(take_until("JRE ("), tag("JRE ("))(input)
+}
+
+fn j9_prefix(input: &str) -> IResult<&str, &str> {
+ preceded(take_until("VM ("), tag("VM ("))(input)
+}
+
+fn suffix(input: &str) -> IResult<&str, &str> {
+ rest(input)
+}
+
+fn parse(input: &str) -> IResult<&str, &str> {
+ let prefix = alt((jre_prefix, j9_prefix));
+ let version_or_zulu = alt((version, zulu));
+ let (input, (_, version, _)) = tuple((prefix, version_or_zulu, suffix))(input)?;
+
+ Ok((input, version))
+}
+
+/// Parse the java version from `java -Xinternalversion` format.
+///
+/// The expected format is similar to:
+/// "JRE (1.8.0_222-b10)"
+/// "JRE (Zulu 8.40.0.25-CA-linux64) (1.8.0_222-b10)"
+/// "VM (1.8.0_222-b10)".
+///
+/// Some Java vendors might not follow this format.
+pub fn parse_jre_version(input: &str) -> Option<&str> {
+ parse(input).map(|result| result.1).ok()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_parse_eclipse_openj9() {
+ let java_8 = "Eclipse OpenJ9 OpenJDK 64-bit Server VM (1.8.0_222-b10) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 8.0.222.0, built on Jul 17 2019 21:29:18 by jenkins with g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)";
+ let java_11 = "Eclipse OpenJ9 OpenJDK 64-bit Server VM (11.0.4+11) from linux-amd64 JRE with Extensions for OpenJDK for Eclipse OpenJ9 11.0.4.0, built on Jul 17 2019 21:51:37 by jenkins with g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)";
+ assert_eq!(parse(java_8), Ok(("", "1.8.0")));
+ assert_eq!(parse(java_11), Ok(("", "11.0.4")));
+ }
+}
diff --git a/src/modules/utils/mod.rs b/src/modules/utils/mod.rs
new file mode 100644
index 000000000..9e69310b2
--- /dev/null
+++ b/src/modules/utils/mod.rs
@@ -0,0 +1 @@
+pub mod java_version_parser;