Test java_language_version and java_runtime_version flags.

Closes #12723.

PiperOrigin-RevId: 348055430
diff --git a/src/test/shell/bazel/bazel_java14_test.sh b/src/test/shell/bazel/bazel_java14_test.sh
index 53e57e8..60efe51 100755
--- a/src/test/shell/bazel/bazel_java14_test.sh
+++ b/src/test/shell/bazel/bazel_java14_test.sh
@@ -97,6 +97,7 @@
     cat $(rlocation io_bazel/src/test/shell/bazel/testdata/jdk_http_archives) >> WORKSPACE
 }
 
+# Java source files version shall match --java_language_version_flag version.
 function test_java14_record_type() {
   mkdir -p java/main
   cat >java/main/BUILD <<EOF
@@ -118,7 +119,18 @@
   }
 }
 EOF
-  bazel run java/main:Javac14Example --java_language_version=14 --java_runtime_version=14 --test_output=all --verbose_failures &>"${TEST_log}"
+  bazel run java/main:Javac14Example --java_language_version=14 --java_runtime_version=14 \
+     --test_output=all --verbose_failures &>"${TEST_log}" \
+      || fail "Running with --java_language_version=14 failed"
+  expect_log "0"
+
+  bazel run java/main:Javac14Example --java_language_version=11 --java_runtime_version=11 \
+     --test_output=all --verbose_failures &>"${TEST_log}" \
+      && fail "Running with --java_language_version=11 unexpectedly succeeded."
+
+  bazel run java/main:Javac14Example --java_language_version=15 --java_runtime_version=15 \
+     --test_output=all --verbose_failures &>"${TEST_log}" \
+      || fail "Running with --java_language_version=15 failed"
   expect_log "0"
 }
 
diff --git a/src/test/shell/bazel/bazel_java15_test.sh b/src/test/shell/bazel/bazel_java15_test.sh
index 3986bc8..b17d44c 100755
--- a/src/test/shell/bazel/bazel_java15_test.sh
+++ b/src/test/shell/bazel/bazel_java15_test.sh
@@ -98,6 +98,7 @@
     cat $(rlocation io_bazel/src/test/shell/bazel/testdata/jdk_http_archives) >> WORKSPACE
 }
 
+# Java source files version shall match --java_language_version_flag version.
 function test_java15_text_block() {
   mkdir -p java/main
   cat >java/main/BUILD <<EOF
@@ -119,7 +120,17 @@
   }
 }
 EOF
-  bazel run java/main:Javac15Example --java_language_version=15 --java_runtime_version=15 --test_output=all --verbose_failures &>"${TEST_log}"
+  bazel run java/main:Javac15Example --java_language_version=14 --java_runtime_version=14 \
+     --test_output=all --verbose_failures &>"${TEST_log}" \
+     && fail "Running with --java_language_version=14 unexpectedly succeeded."
+
+  bazel run java/main:Javac15Example --java_language_version=11 --java_runtime_version=11 \
+     --test_output=all --verbose_failures &>"${TEST_log}" \
+     && fail "Running with --java_language_version=11 unexpectedly succeeded."
+
+  bazel run java/main:Javac15Example --java_language_version=15 --java_runtime_version=15 \
+     --test_output=all --verbose_failures &>"${TEST_log}" \
+     || fail "Running with --java_language_version=15 failed"
   expect_log "^Hello,\$"
   expect_log "^World\$"
 }
diff --git a/src/test/shell/bazel/bazel_java_test_defaults.sh b/src/test/shell/bazel/bazel_java_test_defaults.sh
index da863ac..980b121 100755
--- a/src/test/shell/bazel/bazel_java_test_defaults.sh
+++ b/src/test/shell/bazel/bazel_java_test_defaults.sh
@@ -57,7 +57,8 @@
   export MSYS2_ARG_CONV_EXCL="*"
 fi
 
-
+# Java source files version shall match --java_language_version_flag version.
+# Output class files shall be created in corresponding version (JDK 8, class version is 52).
 function test_default_java_toolchain_target_version() {
   mkdir -p java/main
   cat >java/main/BUILD <<EOF
@@ -72,6 +73,8 @@
 )
 default_java_toolchain(
   name = "default_toolchain",
+  source_version = "8",
+  target_version = "8",
   visibility = ["//visibility:public"],
 )
 EOF
@@ -84,6 +87,7 @@
 }
 EOF
   bazel run java/main:JavaBinary \
+      --java_language_version=8 \
       --java_runtime_version=11 \
       --extra_toolchains=//java/main:default_toolchain_definition \
       --verbose_failures -s &>"${TEST_log}" \
@@ -93,7 +97,9 @@
   expect_log "major version: 52"
 }
 
-function test_tools_jdk_toolchain_java11() {
+# Java source files version shall match --java_language_version_flag version.
+# Output class files shall be created in corresponding version (JDK 11, class version is 55).
+function test_java_language_version_output_classes() {
   mkdir -p java/main
   cat >java/main/BUILD <<EOF
 java_binary(
@@ -112,14 +118,19 @@
   }
 }
 EOF
-  bazel run java/main:JavaBinary \
-      --java_language_version=11 \
-      --java_runtime_version=11 \
+  bazel run java/main:JavaBinary --java_language_version=11 --java_runtime_version=11 \
       --verbose_failures -s &>"${TEST_log}" \
-      || fail "Building with @bazel_tools//tools/jdk:toolchain_java11 failed"
+      || fail "Building with --java_language_version=11 failed"
   expect_log "strip_trailing_java11"
   javap -verbose -cp bazel-bin/java/main/JavaBinary.jar JavaBinary | grep major &>"${TEST_log}"
   expect_log "major version: 55"
+
+  bazel run java/main:JavaBinary --java_language_version=15 --java_runtime_version=15 \
+      --verbose_failures -s &>"${TEST_log}" \
+      || fail "Building with --java_language_version=15 failed"
+  expect_log "strip_trailing_java11"
+  javap -verbose -cp bazel-bin/java/main/JavaBinary.jar JavaBinary | grep major &>"${TEST_log}"
+  expect_log "major version: 59"
 }
 
 function test_tools_jdk_toolchain_nojacocorunner() {
diff --git a/src/test/shell/bazel/bazel_with_jdk_test.sh b/src/test/shell/bazel/bazel_with_jdk_test.sh
index 8e800cc..b9ba99d 100755
--- a/src/test/shell/bazel/bazel_with_jdk_test.sh
+++ b/src/test/shell/bazel/bazel_with_jdk_test.sh
@@ -120,6 +120,9 @@
       fail "'bazel license' did not print an expected string from LICENSE"
 }
 
+# JVM selection: Do not automatically use remote JDK for execution JVM if local
+# JDK is not found. Print an error message guiding the user how to use remote JDK.
+# Rationale: Keeping build systems stable upon Bazel releases.
 
 function test_bazel_reports_missing_local_jdk() {
   # Make a JAVA_HOME with javac and without java
diff --git a/src/test/shell/integration/bazel_java_test.sh b/src/test/shell/integration/bazel_java_test.sh
index f31f82f..47a6930 100755
--- a/src/test/shell/integration/bazel_java_test.sh
+++ b/src/test/shell/integration/bazel_java_test.sh
@@ -44,7 +44,9 @@
   expect_log "java-home: .*/embedded_tools/jdk"
 }
 
-function test_toolchain_javabase() {
+# Javabuilder shall be executed using JDK defined in java_toolchain's java_runtime attribute.
+# Java targets shall be executed using JDK matching --java_runtime_version version.
+function test_java_runtime() {
   cat << EOF >> WORKSPACE
 load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
 local_java_repository(
@@ -77,24 +79,44 @@
   expect_not_log "exec external/embedded_jdk/bin/java"
   expect_log "exec external/remotejdk11_.*/bin/java"
 
-  bazel aquery --output=text --tool_java_runtime_version='host_javabase' \
-    //java:javalib >& $TEST_log
+  bazel aquery --output=text --java_runtime_version='host_javabase' //java:javalib >& $TEST_log
   expect_log "exec external/remotejdk11_.*/bin/java"
   expect_not_log "exec external/host_javabase/bin/java"
+}
 
-  bazel aquery --output=text \
-    //java:javalib >& $TEST_log
+# Javabuilder shall be executed using JDK defined in java_toolchain's java_runtime attribute.
+# Rationale: Javabuilder uses JDK internals for compilation. This ensures
+# compatibility between JDK and Javabuilder, and ability to compile desired source.
+# Testing: Javabuilder in target configuration.
+function test_toolchain_java_runtime_set_from_toolchain() {
+  mkdir java
+  cat << EOF > java/BUILD
+java_library(
+    name = "javalib",
+    srcs = ["HelloWorld.java"],
+)
+EOF
+  touch java/HelloWorld.java
+
+  mkdir -p foobar/bin
+  touch foobar/bin/java
+
+  bazel aquery --output=text --java_language_version=8  //java:javalib >& $TEST_log
   expect_log "exec external/remotejdk11_.*/bin/java"
 
-  # If we change language version to 15, we expect runtime to change
-  bazel aquery --incompatible_use_toolchain_resolution_for_java_rules --output=text \
-     --tool_java_runtime_version='host_javabase' --java_language_version=15 \
-    //java:javalib >& $TEST_log
-  expect_not_log "exec external/remotejdk11_.*/bin/java"
+  bazel aquery --output=text --java_language_version=11  //java:javalib >& $TEST_log
+  expect_log "exec external/remotejdk11_.*/bin/java"
+
+  bazel aquery --output=text --java_language_version=14  //java:javalib >& $TEST_log
+  expect_log "exec external/remotejdk14_.*/bin/java"
+
+  bazel aquery --output=text  --java_language_version=15 //java:javalib >& $TEST_log
   expect_log "exec external/remotejdk15_.*/bin/java"
 }
 
-function test_host_javabase() {
+# Javabuilder shall be executed using JDK defined in java_toolchain's java_runtime attribute, not tool_java_runtime.
+# Testing: Javabuilder in exec configuration.
+function test_exec_toolchain_java_runtime_not_set_from_tool_java_runtime_version() {
   cat << EOF >> WORKSPACE
 load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
 local_java_repository(
@@ -139,21 +161,19 @@
   expect_log "exec external/remotejdk11_.*/bin/java"
   expect_not_log "exec external/host_javabase/bin/java"
 
-  # If we don't specify anything, we expect the embedded JDK to be used.
+  # If we don't specify anything, we expect the remote JDK to be used.
   # Note that this will change in the future but is the current state.
   bazel aquery --output=text 'deps(//java:sample,1)' >& $TEST_log
   expect_not_log "exec external/embedded_jdk/bin/java"
   expect_log "exec external/remotejdk11_.*/bin/java"
 
-  bazel aquery --output=text --tool_java_runtime_version='host_javabase' \
-    'deps(//java:sample,1)' >& $TEST_log
+  bazel aquery --output=text --tool_java_runtime_version='host_javabase' 'deps(//java:sample,1)' >& $TEST_log
   expect_log "exec external/remotejdk11_.*/bin/java"
   expect_not_log "exec external/host_javabase/bin/java"
 
-
-  bazel aquery --output=text \
-    'deps(//java:sample,1)' >& $TEST_log
-  expect_log "exec external/remotejdk11_.*/bin/java"
+  bazel aquery --output=text --tool_java_language_version=14 --tool_java_runtime_version='host_javabase' 'deps(//java:sample,1)' >& $TEST_log
+  expect_log "exec external/remotejdk14_.*/bin/java"
+  expect_not_log "exec external/host_javabase/bin/java"
 }
 
 
@@ -290,8 +310,7 @@
   # erroneously match the expected regexes.
 
   # Test the genrule with no java dependencies.
-  bazel cquery --max_config_changes_to_show=0 --implicit_deps \
-    'deps(//:without_java)' >& $TEST_log
+  bazel cquery --max_config_changes_to_show=0 --implicit_deps 'deps(//:without_java)' >& $TEST_log
   expect_not_log "foo"
   expect_not_log "bar"
   expect_not_log "embedded_jdk"
@@ -299,8 +318,7 @@
   expect_not_log "remotejdk11_"
 
   # Test the genrule that specifically depends on :bar_runtime.
-  bazel cquery --max_config_changes_to_show=0 --implicit_deps \
-    'deps(//:with_java)' >& $TEST_log
+  bazel cquery --max_config_changes_to_show=0 --implicit_deps 'deps(//:with_java)' >& $TEST_log
   expect_not_log "foo"
   expect_log "bar"
   expect_not_log "embedded_jdk"
@@ -309,8 +327,8 @@
 
   # Setting the javabase should not change the use of :bar_runtime from the
   # roolchains attribute.
-  bazel cquery --max_config_changes_to_show=0 --implicit_deps \
-    'deps(//:with_java)' --tool_java_runtime_version=foo_javabase >& $TEST_log
+  bazel cquery --max_config_changes_to_show=0 --implicit_deps 'deps(//:with_java)' \
+     --tool_java_runtime_version=foo_javabase >& $TEST_log
   expect_not_log "foo"
   expect_log "bar"
   expect_not_log "embedded_jdk"