[java] easier to switch between java 8 and java 11

Summary:
- make most behaviours independent of the java version so that either works fine without user intervention
  - modify regexp used to parse `javac` output to work for all versions
  - no need to be sure we are in Java 11 to match java 11-only method name in quandary
- for the rest, provide a command-line flag to specify the java version manually in case it differs from the version that infer was built against
  - this only affects the Maven integration for now

To do all that, also change the configure script to record the version of java instead of just a boolean for whether it's >= 10.

Reviewed By: ezgicicek

Differential Revision: D16493988

fbshipit-source-id: 622e91b25
master
Jules Villard 5 years ago committed by Facebook Github Bot
parent 8bdc03bba4
commit ddddea3eda

@ -40,8 +40,8 @@ INSTALL_NAME_TOOL = @INSTALL_NAME_TOOL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
IS_FACEBOOK_TREE = @IS_FACEBOOK_TREE@ IS_FACEBOOK_TREE = @IS_FACEBOOK_TREE@
IS_RELEASE_TREE = @IS_RELEASE_TREE@ IS_RELEASE_TREE = @IS_RELEASE_TREE@
JAVA_MAJOR_VERSION = @JAVA_MAJOR_VERSION@
JAVAC = @JAVAC@ JAVAC = @JAVAC@
JDK11_ENABLED = @JDK11_ENABLED@
LDD = @LDD@ LDD = @LDD@
LDFLAGS = @LDFLAGS@ LDFLAGS = @LDFLAGS@
libdir = @libdir@ libdir = @libdir@

@ -273,6 +273,18 @@ if test "x$enable_java_analyzers" = "xyes"; then
AC_ASSERT_OCAML_PKG([javalib]) AC_ASSERT_OCAML_PKG([javalib])
AC_ASSERT_OCAML_PKG([sawja]) 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]) AC_MSG_CHECKING([for JAVA_HOME])
cat - <<_ACEOF >conftest.java cat - <<_ACEOF >conftest.java
public class conftest { public class conftest {
@ -283,16 +295,15 @@ public class conftest {
} }
_ACEOF _ACEOF
rm -f conftest.class rm -f conftest.class
if $JAVAC conftest.java; then if "$JAVAC" conftest.java; then
rm -f conftest.java rm -f conftest.java
_USER_JAVA_HOME=$($JAVA -cp . conftest) _USER_JAVA_HOME=$($JAVA -cp . conftest)
if rm -f conftest.class; then if rm -f conftest.class; then
javac_version=`"$JAVAC" -version 2>&1 | head -n 1` [javac_version_10_or_more=`echo "$JAVA_MAJOR_VERSION" | grep -q -e '^1[0-9]' && echo yes`]
[JDK11_ENABLED=`echo "$javac_version" | grep -E -q '^javac\ (11|1[0-9])' && echo yes`] if test "x$javac_version_10_or_more" = "xyes"; then
if test "x$JDK11_ENABLED" = "xyes"; then
USER_JAVA_HOME=$_USER_JAVA_HOME USER_JAVA_HOME=$_USER_JAVA_HOME
AC_SUBST([JDK11_ENABLED]) else
else USER_JAVA_HOME=$_USER_JAVA_HOME/.. USER_JAVA_HOME=$_USER_JAVA_HOME/..
fi fi
else else
AC_MSG_ERROR([Could not run test program with $JAVA]) AC_MSG_ERROR([Could not run test program with $JAVA])

@ -385,6 +385,10 @@ JAVA OPTIONS
Specify a list of Java package prefixes for external Java Specify a list of Java package prefixes for external Java
packages. If set, the analysis will not report non-actionable packages. If set, the analysis will not report non-actionable
warnings on those packages. 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 CHECKER OPTIONS
--quandary-endpoints json --quandary-endpoints json
Specify endpoint classes for Quandary Specify endpoint classes for Quandary

@ -261,6 +261,10 @@ JAVA OPTIONS
--java-jar-compiler path --java-jar-compiler path
Specify the Java compiler jar used to generate the bytecode 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 ENVIRONMENT
INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE INFER_ARGS, INFERCONFIG, INFER_STRICT_MODE

@ -653,6 +653,10 @@ OPTIONS
Specify the Java compiler jar used to generate the bytecode Specify the Java compiler jar used to generate the bytecode
See also infer-capture(1). 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 --jobs,-j int
Run the specified number of analysis jobs simultaneously Run the specified number of analysis jobs simultaneously
See also infer-analyze(1). See also infer-analyze(1).
@ -1416,6 +1420,9 @@ INTERNAL OPTIONS
--java-jar-compiler-reset --java-jar-compiler-reset
Cancel the effect of --java-jar-compiler. Cancel the effect of --java-jar-compiler.
--java-version-reset
Cancel the effect of --java-version.
--job-id string --job-id string
Specify the job ID of this Infer run. Specify the job ID of this Infer run.

@ -653,6 +653,10 @@ OPTIONS
Specify the Java compiler jar used to generate the bytecode Specify the Java compiler jar used to generate the bytecode
See also infer-capture(1). 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 --jobs,-j int
Run the specified number of analysis jobs simultaneously Run the specified number of analysis jobs simultaneously
See also infer-analyze(1). See also infer-analyze(1).

@ -264,7 +264,7 @@ $(GENERATED_FROM_AUTOCONF): $(MAKEFILE_LIST)
-e 's|@IS_RELEASE_TREE[@]|$(IS_RELEASE_TREE)|g' \ -e 's|@IS_RELEASE_TREE[@]|$(IS_RELEASE_TREE)|g' \
-e "s|@INFER_GIT_COMMIT[@]|$$INFER_GIT_COMMIT|g" \ -e "s|@INFER_GIT_COMMIT[@]|$$INFER_GIT_COMMIT|g" \
-e "s|@INFER_GIT_BRANCH[@]|$$INFER_GIT_BRANCH|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_C_ANALYZERS[@]|$(BUILD_C_ANALYZERS)|g" \
-e "s|@BUILD_JAVA_ANALYZERS[@]|$(BUILD_JAVA_ANALYZERS)|g" \ -e "s|@BUILD_JAVA_ANALYZERS[@]|$(BUILD_JAVA_ANALYZERS)|g" \
-e "s|@BUILD_PLATFORM[@]|$(BUILD_PLATFORM)|g" \ -e "s|@BUILD_PLATFORM[@]|$(BUILD_PLATFORM)|g" \

@ -1591,6 +1591,12 @@ and java_jar_compiler =
~meta:"path" "Specify the Java compiler jar used to generate the bytecode" ~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 job_id = CLOpt.mk_string_opt ~long:"job-id" "Specify the job ID of this Infer run."
and jobs = and jobs =
@ -2907,6 +2913,8 @@ and iterations = !iterations
and java_jar_compiler = !java_jar_compiler and java_jar_compiler = !java_jar_compiler
and java_version = !java_version
and javac_classes_out = !javac_classes_out and javac_classes_out = !javac_classes_out
and job_id = !job_id and job_id = !job_id

@ -441,6 +441,8 @@ val iterations : int
val java_jar_compiler : string option val java_jar_compiler : string option
val java_version : int option
val javac_classes_out : string val javac_classes_out : string
val job_id : string option val job_id : string option

@ -47,7 +47,7 @@ let clang_enabled = is_yes "@BUILD_C_ANALYZERS@"
let java_enabled = is_yes "@BUILD_JAVA_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@" let xcode_enabled = is_not_no "@XCODE_SELECT@"

@ -27,7 +27,7 @@ val clang_enabled : bool
val java_enabled : bool val java_enabled : bool
val is_jdk11 : bool val java_version : int option
val xcode_enabled : bool val xcode_enabled : bool

@ -36,7 +36,11 @@ let infer_profile =
</profile>|} </profile>|}
infer_profile_name infer_profile_name
(Config.bin_dir ^/ InferCommand.infer_exe_name) (Config.bin_dir ^/ InferCommand.infer_exe_name)
(if Version.is_jdk11 then " <release>11</release>" else "")) ( match Config.java_version with
| Some version when version >= 9 ->
Printf.sprintf "<release>%d</release>" version
| _ ->
"" ))
let pom_worklist = ref [CLOpt.init_work_dir] let pom_worklist = ref [CLOpt.init_work_dir]

@ -119,16 +119,15 @@ let load_from_verbose_output javac_verbose_out =
let file_in = In_channel.create javac_verbose_out in let file_in = In_channel.create javac_verbose_out in
let class_filename_re = let class_filename_re =
Str.regexp Str.regexp
( if Version.is_jdk11 then "\\[wrote \\(.*\\)\\]" (Printf.sprintf
else
Printf.sprintf
(* the unreadable regexp below captures 3 possible forms: (* 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 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 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 *) 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 \ "\\[wrote \
\\(DirectoryFileObject\\[%s:\\(.*\\)\\|\\(\\(Regular\\|Simple\\)FileObject\\[\\(.*\\)\\)\\)\\]\\]" \\(DirectoryFileObject\\[%s:\\(.*\\)\\|\\(\\(Regular\\|Simple\\)FileObject\\[\\(.*\\)\\)\\]\\|\\(.*\\)\\)\\]"
Config.javac_classes_out ) Config.javac_classes_out)
in in
let source_filename_re = let source_filename_re =
Str.regexp "\\[parsing started \\(Regular\\|Simple\\)FileObject\\[\\(.*\\)\\]\\]" Str.regexp "\\[parsing started \\(Regular\\|Simple\\)FileObject\\[\\(.*\\)\\]\\]"
@ -143,12 +142,12 @@ let load_from_verbose_output javac_verbose_out =
| line -> | line ->
if Str.string_match class_filename_re line 0 then if Str.string_match class_filename_re line 0 then
let path = 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 -> with Caml.Not_found ->
(* either matched group 5 is found, or matched group 2 is found, see doc for [class_filename_re] above *) (* either matched group 5, 6, or 2 is found, see doc for [class_filename_re] above *)
Config.javac_classes_out ^/ Str.matched_group 2 line Str.matched_group 6 line )
in in
match Javalib.extract_class_name_from_file path with match Javalib.extract_class_name_from_file path with
| exception (JBasics.Class_structure_error _ | Invalid_argument _) -> | exception (JBasics.Class_structure_error _ | Invalid_argument _) ->

@ -551,7 +551,7 @@ module JavaSanitizer = struct
let sanitizer_matching_supertype typename = let sanitizer_matching_supertype typename =
match (Typ.Name.name typename, method_name) with match (Typ.Name.name typename, method_name) with
(* string concatenation is translated differently by invokedynamic in JDK11 *) (* string concatenation is translated differently by invokedynamic in JDK11 *)
| "java.lang.Object", "makeConcatWithConstants" when Version.is_jdk11 -> | "java.lang.Object", "makeConcatWithConstants" ->
Some StringConcatenation Some StringConcatenation
| "java.lang.StringBuilder", "append" -> | "java.lang.StringBuilder", "append" ->
Some StringConcatenation Some StringConcatenation

Loading…
Cancel
Save