blob: fbccd88de5e768b6ca9903e34a1e07059586c0c1 [file] [log] [blame] [view]
Googler032aab22017-09-14 16:49:56 +02001---
2layout: documentation
3title: Java and Bazel
4---
5
6# Java and Bazel
7
8This page contains resources that help you use Bazel with Java projects. It
9links to a tutorial, build rules, and other information specific to building
10Java projects with Bazel.
11
12## Contents
13
14- [Working with Bazel](#working-with-bazel)
15- [Migrating to Bazel](#migrating-to-bazel)
16- [Best practices](#best-practices)
17 - [Directory structure](#directory-structure)
18 - [BUILD files](#build-files)
laurentlb749165f2017-12-14 03:41:55 -080019- [Java and new rules](#java-and-new-rules)
Googler032aab22017-09-14 16:49:56 +020020
21## Working with Bazel
22
23The following resources will help you work with Bazel on Java projects:
24
25* [Tutorial: Building a Java Project](tutorial/java.html)
Jingwen Chen0f4544d2018-12-14 16:28:16 -080026* [Java rules](be/java.html)
Googler032aab22017-09-14 16:49:56 +020027
28## Migrating to Bazel
29
30If you currently build your Java projects with Maven, follow the steps in the
31migration guide to start building your Maven projects with Bazel:
32
33* [Migrating from Maven to Bazel](migrate-maven.html)
34
35## Best practices
36
37In addition to [general Bazel best practices](best-practices.html), below are
38best practices specific to Java projects.
39
40### Directory structure
41
42Prefer Maven's standard directory layout (sources under `src/main/java`, tests
43under `src/test/java`).
44
45### BUILD files
46
47Follow these guidelines when creating your BUILD files:
48
49* Use one BUILD file per package containing Java sources.
50
51* Every BUILD file should contain one `java_library` rule that looks like this:
52
53 ```python
54 java_library(
55 name = "directory-name",
56 srcs = glob(["*.java"]),
Alpha0cfc7b22018-05-02 05:04:18 -070057 deps = [...],
Googler032aab22017-09-14 16:49:56 +020058 )
59 ```
60* The name of the library should be the name of the directory containing the
61 BUILD file.
62
Jingwen Chen0f4544d2018-12-14 16:28:16 -080063* The sources should be a non-recursive [`glob`](be/functions.html#glob)
Googler032aab22017-09-14 16:49:56 +020064 of all Java files in the directory.
65
66* Tests should be in a matching directory under `src/test` and depend on this
67 library.
68
laurentlb749165f2017-12-14 03:41:55 -080069## Java and new rules
Googler032aab22017-09-14 16:49:56 +020070
laurentlb749165f2017-12-14 03:41:55 -080071**Note**: Creating new rules is for advanced build and test scenarios.
72You do not need it when getting started with Bazel.
Googler032aab22017-09-14 16:49:56 +020073
laurentlb749165f2017-12-14 03:41:55 -080074The following modules, configuration fragments, and providers will help you
Jingwen Chen0f4544d2018-12-14 16:28:16 -080075[extend Bazel's capabilities](skylark/concepts.html)
laurentlb749165f2017-12-14 03:41:55 -080076when building your Java projects:
Googler032aab22017-09-14 16:49:56 +020077
78* Modules:
79
80 * [`java_annotation_processing`](skylark/lib/java_annotation_processing.html)
81 * [`java_common`](skylark/lib/java_common.html)
82 * [`java_compilation_info`](skylark/lib/java_compilation_info.html)
83 * [`java_output`](skylark/lib/java_output.html)
84 * [`java_output_jars`](skylark/lib/java_output_jars.html)
85 * [`java_proto_common`](skylark/lib/java_proto_common.html)
86 * [`JavaRuntimeClasspathProvider`](skylark/lib/JavaRuntimeClasspathProvider.html)
87 * [`JavaRuntimeInfo`](skylark/lib/JavaRuntimeInfo.html)
gregceacab2c22020-05-28 18:11:32 -070088 * [`JavaToolchainStarlarkApiProvider`](skylark/lib/JavaToolchainStarlarkApiProvider.html)
Googler032aab22017-09-14 16:49:56 +020089
90* Configuration fragments:
91
92 * [`java`](skylark/lib/java.html)
93
94* Providers:
95
gregceacab2c22020-05-28 18:11:32 -070096 * [`java`](skylark/lib/JavaStarlarkApiProvider.html)
Googler032aab22017-09-14 16:49:56 +020097 * [`JavaInfo`](skylark/lib/JavaInfo.html)
jingwen6bc292d2020-05-08 21:14:41 -070098
99## Configuring the JDK
100
101Bazel is configured to use a default OpenJDK 11 for building and testing
102JVM-based projects. However, you can switch to another JDK using the
103[`--java_toolchain`](command-line-reference.html#flag--java_toolchain) and
104[`--javabase`](command-line-reference.html#flag--javabase) flags.
105
106In short,
107
108* `--java_toolchain`: A [`java_toolchain`](be/java.html#java_toolchain)
109 target that defines the set of Java tools for building target binaries.
110* `--javabase`: A [`java_runtime`](be/java.html#java_runtime) target defining
111 the Java runtime for running target JVM binaries.
112
113The
114[`--host_java_toolchain`](command-line-reference.html#flag--host_java_toolchain)
115and [`--host_javabase`](command-line-reference.html#flag--host_javabase)
116variants are meant for building and running host binaries that Bazel
117uses for building target binaries. These host binaries belong to
118`--java_toolchain`, which includes `JavaBuilder` and `Turbine`.
119
120Bazel's default flags essentially look like this:
121
122```
123$ bazel build \
124 --host_javabase=@bazel_tools//tools/jdk:remote_jdk11 \
125 --javabase=@bazel_tools//tools/jdk:remote_jdk11 \
126 --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 \
127 --java_toolchain=@bazel_tools//tools/jdk:toolchain_java11 \
128 //my/java:target
129```
130
131`@bazel_tools` comes with a number of `java_toolchain` targets. Run the
132following command to list them:
133
134```
135$ bazel query 'kind(java_toolchain, @bazel_tools//tools/jdk:all)'
136```
137
138Similarly for `java_runtime` targets:
139
140```
141$ bazel query 'kind(java_runtime, @bazel_tools//tools/jdk:all)'
142```
143
144For example, if you'd like to use a locally installed JDK installed at
145`/usr/lib/jvm/java-13-openjdk`, use the `absolute_javabase` `java_runtime`
146target and the `toolchain_vanilla` `java_toolchain` target, and define
147`ABSOLUTE_JAVABASE` as the absolute path to the JDK.
148
149
150```
151bazel build \
152 --define=ABSOLUTE_JAVABASE=/usr/lib/jvm/java-13-openjdk \
153 --javabase=@bazel_tools//tools/jdk:absolute_javabase \
154 --host_javabase=@bazel_tools//tools/jdk:absolute_javabase \
155 --java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla \
156 --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla \
157 //my/java_13:target
158```
159
160Optionally, you can add the flags into your project's `.bazelrc` file to
161avoid having to specify them every time:
162
163```
164build --define=ABSOLUTE_JAVABASE=/usr/lib/jvm/java-13-openjdk
165build --javabase=@bazel_tools//tools/jdk:absolute_javabase
166build --host_javabase=@bazel_tools//tools/jdk:absolute_javabase
167build --java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla
168build --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_vanilla
169```
170
171You can also write your own `java_runtime` and `java_toolchain` targets. As a
172tip, use `bazel query --output=build @bazel_tools//tools/jdk:all` to see how
173the built-in runtime and toolchain targets are defined.