diff --git a/Makefile.autoconf.in b/Makefile.autoconf.in index 549a6f9e0..1b79b224b 100644 --- a/Makefile.autoconf.in +++ b/Makefile.autoconf.in @@ -40,8 +40,8 @@ INSTALL_NAME_TOOL = @INSTALL_NAME_TOOL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ IS_FACEBOOK_TREE = @IS_FACEBOOK_TREE@ IS_RELEASE_TREE = @IS_RELEASE_TREE@ +JAVA_MAJOR_VERSION = @JAVA_MAJOR_VERSION@ JAVAC = @JAVAC@ -JDK11_ENABLED = @JDK11_ENABLED@ LDD = @LDD@ LDFLAGS = @LDFLAGS@ libdir = @libdir@ diff --git a/configure.ac b/configure.ac index f6204e5b9..7f28a6d5e 100644 --- a/configure.ac +++ b/configure.ac @@ -273,6 +273,18 @@ if test "x$enable_java_analyzers" = "xyes"; then AC_ASSERT_OCAML_PKG([javalib]) AC_ASSERT_OCAML_PKG([sawja]) + AC_MSG_CHECKING([for Java major version]) + JAVA_MAJOR_VERSION=`"$JAVAC" -version 2>&1 | head -n 1 | cut -d ' ' -f 2` + AS_IF([test "x`echo $JAVA_MAJOR_VERSION | cut -d '.' -f 1`" = "x1"], [ + # version 1.8.xx -> 8 + JAVA_MAJOR_VERSION=`echo $JAVA_MAJOR_VERSION | cut -d '.' -f 2` + ], [ + # otherwise pick the first number as the major version + JAVA_MAJOR_VERSION=`echo $JAVA_MAJOR_VERSION | cut -d '.' -f 1` + ]) + AC_MSG_RESULT([$JAVA_MAJOR_VERSION]) + AC_SUBST([JAVA_MAJOR_VERSION]) + AC_MSG_CHECKING([for JAVA_HOME]) cat - <<_ACEOF >conftest.java public class conftest { @@ -283,16 +295,15 @@ public class conftest { } _ACEOF rm -f conftest.class - if $JAVAC conftest.java; then + if "$JAVAC" conftest.java; then rm -f conftest.java _USER_JAVA_HOME=$($JAVA -cp . conftest) if rm -f conftest.class; then - javac_version=`"$JAVAC" -version 2>&1 | head -n 1` - [JDK11_ENABLED=`echo "$javac_version" | grep -E -q '^javac\ (11|1[0-9])' && echo yes`] - if test "x$JDK11_ENABLED" = "xyes"; then + [javac_version_10_or_more=`echo "$JAVA_MAJOR_VERSION" | grep -q -e '^1[0-9]' && echo yes`] + if test "x$javac_version_10_or_more" = "xyes"; then USER_JAVA_HOME=$_USER_JAVA_HOME - AC_SUBST([JDK11_ENABLED]) - else USER_JAVA_HOME=$_USER_JAVA_HOME/.. + else + USER_JAVA_HOME=$_USER_JAVA_HOME/.. fi else AC_MSG_ERROR([Could not run test program with $JAVA]) diff --git a/infer/man/man1/infer-analyze.txt b/infer/man/man1/infer-analyze.txt index 5e7715fc2..41afce65e 100644 --- a/infer/man/man1/infer-analyze.txt +++ b/infer/man/man1/infer-analyze.txt @@ -385,6 +385,10 @@ JAVA OPTIONS Specify a list of Java package prefixes for external Java packages. If set, the analysis will not report non-actionable warnings on those packages. + + --java-version int + The version of Java being used. Set it to your Java version if mvn + is failing. QUANDARY CHECKER OPTIONS --quandary-endpoints json Specify endpoint classes for Quandary diff --git a/infer/man/man1/infer-capture.txt b/infer/man/man1/infer-capture.txt index d4c353396..5d1abd152 100644 --- a/infer/man/man1/infer-capture.txt +++ b/infer/man/man1/infer-capture.txt @@ -261,6 +261,10 @@ JAVA OPTIONS --java-jar-compiler path Specify the Java compiler jar used to generate the bytecode + --java-version int + The version of Java being used. Set it to your Java version if mvn + is failing. + ENVIRONMENT INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE diff --git a/infer/man/man1/infer-full.txt b/infer/man/man1/infer-full.txt index f123f18eb..dca99428a 100644 --- a/infer/man/man1/infer-full.txt +++ b/infer/man/man1/infer-full.txt @@ -653,6 +653,10 @@ OPTIONS Specify the Java compiler jar used to generate the bytecode See also infer-capture(1). + --java-version int + The version of Java being used. Set it to your Java version if mvn + is failing. See also infer-analyze(1) and infer-capture(1). + --jobs,-j int Run the specified number of analysis jobs simultaneously See also infer-analyze(1). @@ -1416,6 +1420,9 @@ INTERNAL OPTIONS --java-jar-compiler-reset Cancel the effect of --java-jar-compiler. + --java-version-reset + Cancel the effect of --java-version. + --job-id string Specify the job ID of this Infer run. diff --git a/infer/man/man1/infer.txt b/infer/man/man1/infer.txt index 7ced905a5..a7957277a 100644 --- a/infer/man/man1/infer.txt +++ b/infer/man/man1/infer.txt @@ -653,6 +653,10 @@ OPTIONS Specify the Java compiler jar used to generate the bytecode See also infer-capture(1). + --java-version int + The version of Java being used. Set it to your Java version if mvn + is failing. See also infer-analyze(1) and infer-capture(1). + --jobs,-j int Run the specified number of analysis jobs simultaneously See also infer-analyze(1). diff --git a/infer/src/Makefile b/infer/src/Makefile index 6506b0f87..621df3f83 100644 --- a/infer/src/Makefile +++ b/infer/src/Makefile @@ -264,7 +264,7 @@ $(GENERATED_FROM_AUTOCONF): $(MAKEFILE_LIST) -e 's|@IS_RELEASE_TREE[@]|$(IS_RELEASE_TREE)|g' \ -e "s|@INFER_GIT_COMMIT[@]|$$INFER_GIT_COMMIT|g" \ -e "s|@INFER_GIT_BRANCH[@]|$$INFER_GIT_BRANCH|g" \ - -e "s|@JDK11_ENABLED[@]|$(JDK11_ENABLED)|g" \ + -e "s|@JAVA_MAJOR_VERSION[@]|$(JAVA_MAJOR_VERSION)|g" \ -e "s|@BUILD_C_ANALYZERS[@]|$(BUILD_C_ANALYZERS)|g" \ -e "s|@BUILD_JAVA_ANALYZERS[@]|$(BUILD_JAVA_ANALYZERS)|g" \ -e "s|@BUILD_PLATFORM[@]|$(BUILD_PLATFORM)|g" \ diff --git a/infer/src/base/Config.ml b/infer/src/base/Config.ml index cfe784671..ababf8183 100644 --- a/infer/src/base/Config.ml +++ b/infer/src/base/Config.ml @@ -1591,6 +1591,12 @@ and java_jar_compiler = ~meta:"path" "Specify the Java compiler jar used to generate the bytecode" +and java_version = + CLOpt.mk_int_opt ~long:"java-version" ?default:Version.java_version + ~in_help:InferCommand.[(Capture, manual_java); (Analyze, manual_java)] + "The version of Java being used. Set it to your Java version if mvn is failing." + + and job_id = CLOpt.mk_string_opt ~long:"job-id" "Specify the job ID of this Infer run." and jobs = @@ -2907,6 +2913,8 @@ and iterations = !iterations and java_jar_compiler = !java_jar_compiler +and java_version = !java_version + and javac_classes_out = !javac_classes_out and job_id = !job_id diff --git a/infer/src/base/Config.mli b/infer/src/base/Config.mli index ba896973f..b2446b3ce 100644 --- a/infer/src/base/Config.mli +++ b/infer/src/base/Config.mli @@ -441,6 +441,8 @@ val iterations : int val java_jar_compiler : string option +val java_version : int option + val javac_classes_out : string val job_id : string option diff --git a/infer/src/base/Version.ml.in b/infer/src/base/Version.ml.in index b3d1fed34..968e5d625 100644 --- a/infer/src/base/Version.ml.in +++ b/infer/src/base/Version.ml.in @@ -47,7 +47,7 @@ let clang_enabled = is_yes "@BUILD_C_ANALYZERS@" let java_enabled = is_yes "@BUILD_JAVA_ANALYZERS@" -let is_jdk11 = is_yes "@JDK11_ENABLED@" +let java_version = int_of_string_opt "@JAVA_MAJOR_VERSION@" let xcode_enabled = is_not_no "@XCODE_SELECT@" diff --git a/infer/src/base/Version.mli b/infer/src/base/Version.mli index dca0ba9d3..bfb5f462b 100644 --- a/infer/src/base/Version.mli +++ b/infer/src/base/Version.mli @@ -27,7 +27,7 @@ val clang_enabled : bool val java_enabled : bool -val is_jdk11 : bool +val java_version : int option val xcode_enabled : bool diff --git a/infer/src/integration/Maven.ml b/infer/src/integration/Maven.ml index 29a7b7e07..91b43a501 100644 --- a/infer/src/integration/Maven.ml +++ b/infer/src/integration/Maven.ml @@ -36,7 +36,11 @@ let infer_profile = |} infer_profile_name (Config.bin_dir ^/ InferCommand.infer_exe_name) - (if Version.is_jdk11 then " 11" else "")) + ( match Config.java_version with + | Some version when version >= 9 -> + Printf.sprintf "%d" version + | _ -> + "" )) let pom_worklist = ref [CLOpt.init_work_dir] diff --git a/infer/src/java/jClasspath.ml b/infer/src/java/jClasspath.ml index ad2fd5cc3..47bcd005a 100644 --- a/infer/src/java/jClasspath.ml +++ b/infer/src/java/jClasspath.ml @@ -119,16 +119,15 @@ let load_from_verbose_output javac_verbose_out = let file_in = In_channel.create javac_verbose_out in let class_filename_re = Str.regexp - ( if Version.is_jdk11 then "\\[wrote \\(.*\\)\\]" - else - Printf.sprintf - (* the unreadable regexp below captures 3 possible forms: + (Printf.sprintf + (* the unreadable regexp below captures 3 possible forms: 1. [wrote DirectoryFileObject[/path/to/classes_out:path/to/File.java]], leaves `path/to/File.java` in match group 2 2. [wrote RegularFileObject[path/to/File.java]], leaves `path/to/File.java` in match group 5 - 3. [wrote SimpleFileObject[path/to/File.java]], also leaves `path/to/File.java` in match group 5 *) - "\\[wrote \ - \\(DirectoryFileObject\\[%s:\\(.*\\)\\|\\(\\(Regular\\|Simple\\)FileObject\\[\\(.*\\)\\)\\)\\]\\]" - Config.javac_classes_out ) + 3. [wrote SimpleFileObject[path/to/File.java]], also leaves `path/to/File.java` in match group 5 + 4. [wrote path/to/File.java] leaves `path/to/File.java` in match group 6 (from java 11)*) + "\\[wrote \ + \\(DirectoryFileObject\\[%s:\\(.*\\)\\|\\(\\(Regular\\|Simple\\)FileObject\\[\\(.*\\)\\)\\]\\|\\(.*\\)\\)\\]" + Config.javac_classes_out) in let source_filename_re = Str.regexp "\\[parsing started \\(Regular\\|Simple\\)FileObject\\[\\(.*\\)\\]\\]" @@ -143,12 +142,12 @@ let load_from_verbose_output javac_verbose_out = | line -> if Str.string_match class_filename_re line 0 then let path = - if Version.is_jdk11 then Str.matched_group 1 line - else - try Str.matched_group 5 line + try Str.matched_group 5 line + with Caml.Not_found -> ( + try Config.javac_classes_out ^/ Str.matched_group 2 line with Caml.Not_found -> - (* either matched group 5 is found, or matched group 2 is found, see doc for [class_filename_re] above *) - Config.javac_classes_out ^/ Str.matched_group 2 line + (* either matched group 5, 6, or 2 is found, see doc for [class_filename_re] above *) + Str.matched_group 6 line ) in match Javalib.extract_class_name_from_file path with | exception (JBasics.Class_structure_error _ | Invalid_argument _) -> diff --git a/infer/src/quandary/JavaTrace.ml b/infer/src/quandary/JavaTrace.ml index 06b228b1f..f5dfd2fd7 100644 --- a/infer/src/quandary/JavaTrace.ml +++ b/infer/src/quandary/JavaTrace.ml @@ -551,7 +551,7 @@ module JavaSanitizer = struct let sanitizer_matching_supertype typename = match (Typ.Name.name typename, method_name) with (* string concatenation is translated differently by invokedynamic in JDK11 *) - | "java.lang.Object", "makeConcatWithConstants" when Version.is_jdk11 -> + | "java.lang.Object", "makeConcatWithConstants" -> Some StringConcatenation | "java.lang.StringBuilder", "append" -> Some StringConcatenation