Document Java toolchains.

Closes #12672.

PiperOrigin-RevId: 348045516
diff --git a/site/docs/bazel-and-java.md b/site/docs/bazel-and-java.md
index 476c70d..ef4c616 100644
--- a/site/docs/bazel-and-java.md
+++ b/site/docs/bazel-and-java.md
@@ -1,7 +1,8 @@
----
+--------------------------------------------------------------------------------
+
 layout: documentation
-title: Java and Bazel
----
+
+## title: Java and Bazel
 
 # Java and Bazel
 
@@ -13,15 +14,53 @@
 
 The following resources will help you work with Bazel on Java projects:
 
-*  [Tutorial: Building a Java Project](tutorial/java.html)
-*  [Java rules](be/java.html)
+*   [Tutorial: Building a Java Project](tutorial/java.html)
+*   [Java rules](be/java.html)
 
 ## Migrating to Bazel
 
 If you currently build your Java projects with Maven, follow the steps in the
 migration guide to start building your Maven projects with Bazel:
 
-*  [Migrating from Maven to Bazel](migrate-maven.html)
+*   [Migrating from Maven to Bazel](migrate-maven.html)
+
+## Java versions
+
+There are two relevant versions of Java that are set with configuration flags:
+ - the version of the source files in the repository
+ - the version of the Java runtime that is used to execute the code and to test it
+
+Without an additional configuration, Bazel assumes all Java source files in the
+repository are written in a single Java version. To specify the version of the
+sources in the repository add `build --java_language_version={ver}` to
+`.bazelrc` file, where `{ver}` is for example `11`. Bazel repository owners
+should set this flag so that Bazel and its users can reference the source code's
+Java version number. For more details, see
+[Java language version flag](user-manual.html#flag--java_language_version).
+
+Bazel uses one JDK for compilation and another JVM to execute and test the code.
+
+By default Bazel compiles the code using a JDK it downloads and it executes and
+tests the code with the JVM installed on the local machine. Bazel searches for
+the JVM using `JAVA_HOME` or path.
+
+The resulting binaries are compatible with locally installed JVM in system
+libraries, which means the resulting binaries depend on what is installed on the
+machine.
+
+To create a hermetic compile, you can use command line flag
+`--java_runtime_version=remotejdk_11`. The code is compiled for, executed, and
+tested on the JVM downloaded from a remote repository. For more details, see
+[Java runtime version flag](user-manual.html#flag--java_runtime_version).
+
+There is a second pair of JDK and JVM used to build and execute tools, which are
+used in the build process, but are not in the build results. That JDK and JVM
+are controlled using `--tool_java_language_version` and
+`--tool_java_runtime_version`. Default values are 11 and `remotejdk_11`,
+respectively.
+
+For more details, see
+[configuring Java toolchains](#Configuring-the-Java-toolchains).
 
 ## Best practices
 
@@ -37,100 +76,121 @@
 
 Follow these guidelines when creating your BUILD files:
 
-*  Use one BUILD file per package containing Java sources.
+*   Use one BUILD file per directory containing Java sources, because this
+    improves build performance.
 
-*  Every BUILD file should contain one `java_library` rule that looks like this:
+*   Every BUILD file should contain one `java_library` rule that looks like
+    this:
 
-   ```python
-   java_library(
-       name = "directory-name",
-       srcs = glob(["*.java"]),
-       deps = [...],
-   )
-   ```
-*  The name of the library should be the name of the directory containing the
-   BUILD file.
+    ```python
+    java_library(
+        name = "directory-name",
+        srcs = glob(["*.java"]),
+        deps = [...],
+    )
+    ```
 
-*  The sources should be a non-recursive [`glob`](be/functions.html#glob)
-   of all Java files in the directory.
+*   The name of the library should be the name of the directory containing the
+    BUILD file. This makes the label of the library shorter, that is use
+    `"//package"` instead of `"//package:package"`.
 
-*  Tests should be in a matching directory under `src/test` and depend on this
-   library.
+*   The sources should be a non-recursive [`glob`](be/functions.html#glob) of
+    all Java files in the directory.
+
+*   Tests should be in a matching directory under `src/test` and depend on this
+    library.
 
 ## Creating new rules for advanced Java builds
 
-**Note**: Creating new rules is for advanced build and test scenarios.
-You do not need it when getting started with Bazel.
+**Note**: Creating new rules is for advanced build and test scenarios. You do
+not need it when getting started with Bazel.
 
 The following modules, configuration fragments, and providers will help you
-[extend Bazel's capabilities](skylark/concepts.html)
-when building your Java projects:
+[extend Bazel's capabilities](skylark/concepts.html) when building your Java
+projects:
 
-*  Modules:
+*   Main Java provider: [`java_common`](skylark/lib/java_common.html)
+*   Main Java module: [`JavaInfo`](skylark/lib/JavaInfo.html)
+*   Configuration fragment: [`java`](skylark/lib/java.html)
+*   Other modules:
 
-   *  [`java_annotation_processing`](skylark/lib/java_annotation_processing.html)
-   *  [`java_common`](skylark/lib/java_common.html)
-   *  [`java_compilation_info`](skylark/lib/java_compilation_info.html)
-   *  [`java_output`](skylark/lib/java_output.html)
-   *  [`java_output_jars`](skylark/lib/java_output_jars.html)
-   *  [`java_proto_common`](skylark/lib/java_proto_common.html)
-   *  [`JavaRuntimeClasspathProvider`](skylark/lib/JavaRuntimeClasspathProvider.html)
-   *  [`JavaRuntimeInfo`](skylark/lib/JavaRuntimeInfo.html)
-   *  [`JavaToolchainStarlarkApiProvider`](skylark/lib/JavaToolchainStarlarkApiProvider.html)
+    *   [`java_annotation_processing`](skylark/lib/java_annotation_processing.html)
+    *   [`java_compilation_info`](skylark/lib/java_compilation_info.html)
+    *   [`java_output`](skylark/lib/java_output.html)
+    *   [`java_output_jars`](skylark/lib/java_output_jars.html)
+    *   [`java_proto_common`](skylark/lib/java_proto_common.html)
+    *   [`JavaRuntimeInfo`](skylark/lib/JavaRuntimeInfo.html)
+    *   [`JavaToolchainInfo`](skylark/lib/JavaToolchainInfo.html)
 
-*  Configuration fragments:
+## Configuring the Java toolchains
 
-   *  [`java`](skylark/lib/java.html)
+Bazel uses two types of Java toolchains: - execution, used to execute and test
+Java binaries, controlled with `--java_runtime_version` flag - compilation, used
+to compile Java sources, controlled with `--java_language_version` flag
 
-*  Providers:
+### Execution toolchains
 
-   *  [`JavaInfo`](skylark/lib/JavaInfo.html)
+Execution toolchain is the JVM, either local or from a repository, with some
+additional information about its version, operating system, and CPU
+architecture.
 
-## Configuring the JDK
+Java execution toolchains may added using `local_java_repository` or
+`remote_java_repository` rules in the `WORKSPACE` file. Adding the rule makes
+the JVM available using a flag. When multiple definitions for the same operating
+system and CPU architecture are given, the first one is used.
 
-Bazel is configured to use a default OpenJDK 11 for building and testing
-JVM-based projects. However, you can switch to another JDK using the
-[`--java_toolchain`](command-line-reference.html#flag--java_toolchain) and
-[`--javabase`](command-line-reference.html#flag--javabase) flags.
+Example configuration of local JVM: ```python
+load("@bazel_tools//tools/jdk:local_java_repository.bzl",
+"local_java_repository")
 
-In short,
+local_java_repository( name = "additionaljdk", # Can be used with
+--java_runtime_version=additionaljdk or --java_runtime_version=11 version =
+11, # Optional, if not set it is autodetected java_home = "/usr/lib/jdk-15/", #
+Path to directory containing bin/java ) ```
 
-* `--java_toolchain`: A [`java_toolchain`](be/java.html#java_toolchain)
-  target that defines the set of Java tools for building target binaries.
-* `--javabase`: A [`java_runtime`](be/java.html#java_runtime) target defining
-  the Java runtime for running target JVM binaries.
+Example configuration of remote JVM: ```python
+load("@bazel_tools//tools/jdk:remote_java_repository.bzl",
+"remote_java_repository")
 
-The
-[`--host_java_toolchain`](command-line-reference.html#flag--host_java_toolchain)
-and [`--host_javabase`](command-line-reference.html#flag--host_javabase)
-variants are meant for building and running host binaries that Bazel
-uses for building target binaries. These host binaries belong to
-`--java_toolchain`, which includes `JavaBuilder` and `Turbine`.
+remote_java_repository( name = "openjdk_canary_linux_arm", prefix =
+"openjdk_canary", # Can be used with --java_runtime_version=openjdk_canary_11
+version = "11", # or --java_runtime_version=11 exec_compatible_with = [ #
+Specifies contraints this JVM is compatible with "@platforms//cpu:arm",
+"@platforms//os:linux", ], urls = ... # Other parameters are from
+http_repository rule. sha256 = ... strip_prefix = ... ) ```
 
-Bazel's default flags essentially look like this:
+### Compilation toolchains
 
-```
-$ bazel build \
-      --host_javabase=@bazel_tools//tools/jdk:remote_jdk11 \
-      --javabase=@bazel_tools//tools/jdk:remote_jdk11 \
-      --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 \
-      --java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 \
-      //my/java:target
-```
+Compilation toolchain is composed of JDK and multiple tools that Bazel uses
+during the compilation and that provides additional features, such as: Error
+Prone, strict Java dependenciess, header compilation, Android desugaring,
+coverage instrumentation, and genclass handling for IDEs.
 
-`@bazel_tools` comes with a number of `java_toolchain` targets. Run the
-following command to list them:
+You can reconfigure the compilation by adding `default_java_toolchain` macro to
+a `BUILD` file and registering it either by adding `register_toolchain` rule to
+the `WORKSPACE` file or by using
+[`--extra_toolchains`](user-manual.html#flag--extra_toolchains) flag.
 
-```
-$ bazel query 'kind(java_toolchain, @bazel_tools//tools/jdk:all)'
-```
+Example toolchain configuration: ```python
+load("@bazel_tools@bazel_tools//tools/jdk:default_java_toolchain.bzl",
+"default_java_toolchain")
 
-Similarly for `java_runtime` targets:
+default_java_toolchain( name = "repository_default_toolchain", configuration =
+DEFAULT_TOOLCHAIN_CONFIGURATION, # One of predefined configurations
 
-```
-$ bazel query 'kind(java_runtime, @bazel_tools//tools/jdk:all)'
-```
+\# Other parameters are from java_toolchain rule: java_runtime =
+"//tools/jdk:remote_jdk11", # JDK to use for compilation jvm_opts =
+JDK9_JVM_OPTS + ["--enable_preview"] # Additional JDK options misc =
+DEFAULT_JAVACOPTS + ["--enable_preview"] # Additional javac options
+source_version = "9", ) ```
 
-You can also write your own `java_runtime` and `java_toolchain` targets. As a
-tip, use `bazel query --output=build @bazel_tools//tools/jdk:all` to see how
-the built-in runtime and toolchain targets are defined.
+Predefined configurations:
+
+-   `DEFAULT_TOOLCHAIN_CONFIGURATION`: all features, supports JDK versions >= 9
+-   `VANILLA_TOOLCHAIN_CONFIGURATION`: no additional features, supports all JDKs
+-   `JVM8_TOOLCHAIN_CONFIGURATION`: all features, JDK version 8
+-   `PREBUILT_TOOLCHAIN_CONFIGURATION`: same as default, but only use prebuilt
+    tools (`ijar`, `singlejar`)
+-   `NONPREBUILT_TOOLCHAIN_CONFIGURATION`: same as default, but all tools are
+    built from sources (this may be useful on operating system with different
+    libc)
diff --git a/site/docs/platforms-intro.md b/site/docs/platforms-intro.md
index e96d8e1..8f10298 100644
--- a/site/docs/platforms-intro.md
+++ b/site/docs/platforms-intro.md
@@ -259,15 +259,17 @@
 it requires adding platform support for Android and iOS.
 
 ### Java
-Bazel's Java rules use platforms to select toolchains.
+
+Bazel's Java rules use platforms and configuration flags to select toolchains.
 
 This replaces legacy flags `--java_toolchain`, `--host_java_toolchain`,
 `--javabase`, and `--host_javabase`.
 
-[PR #8](https://github.com/bazelbuild/rules_java/pull/8) defines the Java-specific
-`constraint_value`s, toolchains, and other settings that make migration
-practical. This mode will be enabled by default after those changes are
-committed.
+To learn how to use the configuration flags, see the [Bazel and Java](bazel-and-java.md) manual.
+For additional information, see the [Design document](https://docs.google.com/document/d/1MVbBxbKVKRJJY7DnkptHpvz7ROhyAYy4a-TZ-n7Q0r4).
+
+If you are still using legacy flags, follow the migration process in [Issue #7849](https://github.com/bazelbuild/bazel/issues/7849).
+-->
 
 ### Android
 Bazel's Android rules do not yet support platforms to select Android toolchains.
diff --git a/site/docs/tutorial/java.md b/site/docs/tutorial/java.md
index c7b8cb3..de97c46 100644
--- a/site/docs/tutorial/java.md
+++ b/site/docs/tutorial/java.md
@@ -31,7 +31,7 @@
 
 ### Install the JDK
 
-1.  Install Java 8 JDK.
+1.  Install Java JDK (preferred version is 11, however versions between 8 and 15 are supported).
 
 2.  Set the JAVA\_HOME environment variable to point to the JDK.
     *   On Linux/macOS:
diff --git a/site/docs/user-manual.html b/site/docs/user-manual.html
index 26601a5..a2b4624 100644
--- a/site/docs/user-manual.html
+++ b/site/docs/user-manual.html
@@ -372,9 +372,58 @@
   <code>[targetname].sc</code>.
 </p>
 <p>
- This option is disabled by default.
+  This option is disabled by default.
 </p>
 
+<h4 id='flag--java_language_version'><code class='flag'>--java_language_version=<var>version</var></code></h4>
+<p>
+  This option specifies the version of Java sources. For example:
+</p>
+<pre>
+  % bazel build --java_language_version=8 java/com/example/common/foo:all
+</pre>
+<p>
+  compiles and allows only constructs compatible with Java 8 specification.
+   Default value is 11. -->
+  Possible values are: 8,  9, 10, --> 11 <!--begin-block:external , 14, and 15  and may be extended by registering custom Java
+  toolchains using <code>default_java_toolchain</code> macro-->.
+</p>
+
+<h4 id='flag--tool_java_language_version'><code class='flag'>--tool_java_language_version=<var>version</var></code>
+</h4>
+<p>
+  The Java language version used to build tools that are executed during a build.
+  Default value is 11.
+</p>
+
+<h4 id='flag--java_runtime_version'><code class='flag'>--java_runtime_version=<var>version</var></code></h4>
+<p>
+  This option specifies the version of JVM to use to execute the code and run the tests. For
+  example:
+</p>
+<pre>
+  % bazel run --java_runtime_version=remotejdk_11 java/com/example/common/foo:java_application
+</pre>
+<p>
+  downloads JDK 11 from a remote repository and run the Java application using it.
+</p>
+<p>
+  Default value is <code>localjdk</code>.
+  Possible values are: <code>localjdk</code>, <code>localjdk_<var>version</var></code>,
+  <code>remotejdk_11</code>,
+  <code>remotejdk_14</code>, and <code>remote_jdk15</code>.
+  You can extend the values by registering custom JVM using either
+  <code>local_java_repository</code> or
+  <code>remote_java_repostory</code> repository rules.
+</p>
+
+<h4 id='flag--tool_java_runtime_version'><code class='flag'>--tool_java_runtime_version=<var>version</var></code></h4>
+<p>
+  The version of JVM used to execute tools that are needed during a build.
+  Default value is <code>remotejdk_11</code>.
+</p>
+-->
+
 <h4 id='flag--jvmopt'><code class='flag'>--jvmopt <var>jvm-option</var></code></h4>
 <p>
   This option allows option arguments to be passed to the Java VM. It can be used
@@ -573,9 +622,16 @@
   once for each CPU specified with <code class='flag'>--fat_apk_cpu</code> for the
   <code>android_binary</code> rule, and once for the CPU specified with
   <code class='flag'>--cpu</code> for the <code>cc_binary</code> rule.
+</p>
 
 <p>
-The default is <code>armeabi-v7a</code>.
+  The default is <code>armeabi-v7a</code>.
+</p>
+<p>
+  One <code>.so</code> file is created and packaged in the APK for
+  each CPU specified with <code class='flag'>--fat_apk_cpu</code>. The <code>.so</code> file's name
+  prefixes the name of the <code>android_binary</code> rule with "lib". For example, if the name of
+  the <code>android_binary</code> is "foo", then the file is <code>libfoo.so</code>.
 </p>
   <p>
     One <code>.so</code> file will be created and packaged in the APK for
@@ -592,6 +648,10 @@
     <a href='#flag--android_crosstool_top'><code class='flag'>--android_crosstool_top</code></a>
     or <a href='#flag--crosstool_top'><code class='flag'>--crosstool_top</code></a> flags.
   </p>
+
+
+<h4 id='flag--per_file_copt'><code class='flag'>--per_file_copt
+    <var>[+-]regex[,[+-]regex]...@option[,option]...</var></code></h4>
 </p>
 
 <h4 id='flag--per_file_copt'><code class='flag'>--per_file_copt
@@ -926,7 +986,7 @@
 <p>
   These options specify the amount of local resources (RAM in MB and number of CPU logical cores)
   that Bazel can take into consideration when scheduling build and test activities. They take
-  an integer, or a keyword (HOST_RAM or HOST_CPUS) optionally followed by [-|*<float>float</float>]
+  an integer, or a keyword (HOST_RAM or HOST_CPUS) optionally followed by [-|*<code>float</code>]
   (for example, <code class='flag'>--local_cpu_resources=2</code>,
   <code class='flag'>--local_ram_resources=HOST_RAM*.5</code>,
   <code class='flag'>--local_cpu_resources=HOST_CPUS-1</code>).
@@ -2530,15 +2590,19 @@
 <h4 id='flag--start'><code class='flag'>--start=<i>start_type</i></code></h4>
 <p>
   How the app should be started after installing it. Supported <i>start_type</i>s are:
-  <ul>
-    <li><code>NO</code> Does not start the app. This is the default.</li>
-    <li><code>COLD</code> Starts the app from a clean state after install.</li>
-    <li><code>WARM</code> Preserves and restores the application state on incremental installs.</li>
-    <li><code>DEBUG</code> Waits for the debugger before starting the app in a clean state after install.</li>
-  </ul>
+</p>
+<ul>
+  <li><code>NO</code> Does not start the app. This is the default.</li>
+  <li><code>COLD</code> Starts the app from a clean state after install.</li>
+  <li><code>WARM</code> Preserves and restores the application state on incremental installs.</li>
+  <li><code>DEBUG</code> Waits for the debugger before starting the app in a clean state after
+    install.
+  </li>
+</ul>
+<p>
   Note that if more than one of <code class='flag'>--start=<i>start_type</i></code>,
   <code class='flag'>--start_app</code> or
-  <code class='flag'>--debug_app</code> is set, the last value will be used.
+  <code class='flag'>--debug_app</code> is set, the last value is used.
 </p>
 <h4 id='flag--adb'><code class='flag'>--adb <var>path</var></code></h4>
 <p>
@@ -2548,18 +2612,20 @@
   <a href='#flag--android_sdk'><code class='flag'>--android_sdk</code></a>.
 
 </p>
-<h4 id='flag--adb_arg'><code class='flag'>--adb_arg <var>arg</var></code></h4>
+<h4 id='flag--adb_arg'><code class='flag'>--adb_arg <var>serial</var></code></h4>
 <p>
   Extra arguments to <code>adb</code>. These come before the subcommand in the
   command line and are typically used to specify which device to install to.
   For example, to select the Android device or emulator to use:
+</p>
 <pre>% bazel mobile-install --adb_arg=-s --adb_arg=deadbeef
 </pre>
-will invoke <code>adb</code> as
+<p>
+  invokes <code>adb</code> as
+</p>
 <pre>
 adb -s deadbeef install ...
 </pre>
-</p>
 <h4 id='flag--incremental_install_verbosity'><code class='flag'>--incremental_install_verbosity <var>number</var></code></h4>
 <p>
   The verbosity for incremental install. Set to 1 for debug logging to be
@@ -2592,8 +2658,9 @@
     including counts and action counts. This includes both native and Starlark rules.
     If memory tracking is enabled, then the rules' memory consumption is also printed.</li>
   <li><code class='flag'>--skylark_memory</code> dumps a
-    <href a=https://github.com/google/pprof>pprof</href> compatible .gz file to the specified path.
-    You must enable memory tracking for this to work.</li>
+    <a href=https://github.com/google/pprof>pprof</a> compatible .gz file to the specified path.
+    You must enable memory tracking for this to work.
+  </li>
   <li><code class='flag'>--action_graph=/path/to/file</code> dumps the state of
     the internal Bazel action graph in proto format to
     <code>/path/to/file</code>. You have to run (at least) the analysis phase