1*6777b538SAndroid Build Coastguard Worker# Chromium's Java Toolchain 2*6777b538SAndroid Build Coastguard Worker 3*6777b538SAndroid Build Coastguard WorkerThis doc aims to describe the Chrome build process that takes a set of `.java` 4*6777b538SAndroid Build Coastguard Workerfiles and turns them into a `classes.dex` file. 5*6777b538SAndroid Build Coastguard Worker 6*6777b538SAndroid Build Coastguard Worker[TOC] 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker## Core GN Target Types 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard WorkerThe following have `supports_android` and `requires_android` set to false by 11*6777b538SAndroid Build Coastguard Workerdefault: 12*6777b538SAndroid Build Coastguard Worker* `java_library()`: Compiles `.java` -> `.jar` 13*6777b538SAndroid Build Coastguard Worker* `java_prebuilt()`: Imports a prebuilt `.jar` file. 14*6777b538SAndroid Build Coastguard Worker 15*6777b538SAndroid Build Coastguard WorkerThe following have `supports_android` and `requires_android` set to true. They 16*6777b538SAndroid Build Coastguard Workeralso have a default `jar_excluded_patterns` set (more on that later): 17*6777b538SAndroid Build Coastguard Worker* `android_library()` 18*6777b538SAndroid Build Coastguard Worker* `android_java_prebuilt()` 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard WorkerAll target names must end with "_java" so that the build system can distinguish 21*6777b538SAndroid Build Coastguard Workerthem from non-java targets (or [other variations](https://cs.chromium.org/chromium/src/build/config/android/internal_rules.gni?rcl=ec2c17d7b4e424e060c3c7972842af87343526a1&l=20)). 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard WorkerMost targets produce two separate `.jar` files: 24*6777b538SAndroid Build Coastguard Worker* Device `.jar`: Used to produce `.dex.jar`, which is used on-device. 25*6777b538SAndroid Build Coastguard Worker* Host `.jar`: For use on the host machine (`junit_binary` / `java_binary`). 26*6777b538SAndroid Build Coastguard Worker * Host `.jar` files live in `lib.java/` so that they are archived in 27*6777b538SAndroid Build Coastguard Worker builder/tester bots (which do not archive `obj/`). 28*6777b538SAndroid Build Coastguard Worker 29*6777b538SAndroid Build Coastguard Worker## From Source to Final Dex 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker### Step 1: Create interface .jar with turbine or ijar 32*6777b538SAndroid Build Coastguard Worker 33*6777b538SAndroid Build Coastguard WorkerWhat are interface jars?: 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker* They contain `.class` files with all private symbols and all method bodies 36*6777b538SAndroid Build Coastguard Worker removed. 37*6777b538SAndroid Build Coastguard Worker* Dependant targets use interface `.jar` files to skip having to be rebuilt 38*6777b538SAndroid Build Coastguard Worker when only private implementation details change. 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard WorkerFor prebuilt `.jar` files: we use [//third_party/ijar] to create interface 41*6777b538SAndroid Build Coastguard Worker`.jar` files from the prebuilt ones. 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard WorkerFor non-prebuilt `.jar` files`: we use [//third_party/turbine] to create 44*6777b538SAndroid Build Coastguard Workerinterface `.jar` files directly from `.java` source files. Turbine is faster 45*6777b538SAndroid Build Coastguard Workerthan javac because it does not compile method bodies. Although Turbine causes 46*6777b538SAndroid Build Coastguard Workerus to compile files twice, it speeds up builds by allowing `javac` compilation 47*6777b538SAndroid Build Coastguard Workerof targets to happen concurrently with their dependencies. We also use Turbine 48*6777b538SAndroid Build Coastguard Workerto run our annotation processors. 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker[//third_party/ijar]: /third_party/ijar/README.chromium 51*6777b538SAndroid Build Coastguard Worker[//third_party/turbine]: /third_party/turbine/README.chromium 52*6777b538SAndroid Build Coastguard Worker 53*6777b538SAndroid Build Coastguard Worker### Step 2a: Compile with javac 54*6777b538SAndroid Build Coastguard Worker 55*6777b538SAndroid Build Coastguard WorkerThis step is the only step that does not apply to prebuilt targets. 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker* All `.java` files in a target are compiled by `javac` into `.class` files. 58*6777b538SAndroid Build Coastguard Worker * This includes `.java` files that live within `.srcjar` files, referenced 59*6777b538SAndroid Build Coastguard Worker through `srcjar_deps`. 60*6777b538SAndroid Build Coastguard Worker* The `classpath` used when compiling a target is comprised of `.jar` files of 61*6777b538SAndroid Build Coastguard Worker its deps. 62*6777b538SAndroid Build Coastguard Worker * When deps are library targets, the Step 1 `.jar` file is used. 63*6777b538SAndroid Build Coastguard Worker * When deps are prebuilt targets, the original `.jar` file is used. 64*6777b538SAndroid Build Coastguard Worker * All `.jar` processing done in subsequent steps does not impact compilation 65*6777b538SAndroid Build Coastguard Worker classpath. 66*6777b538SAndroid Build Coastguard Worker* `.class` files are zipped into an output `.jar` file. 67*6777b538SAndroid Build Coastguard Worker* There is **no support** for incremental compilation at this level. 68*6777b538SAndroid Build Coastguard Worker * If one source file changes within a library, then the entire library is 69*6777b538SAndroid Build Coastguard Worker recompiled. 70*6777b538SAndroid Build Coastguard Worker * Prefer smaller targets to avoid slow compiles. 71*6777b538SAndroid Build Coastguard Worker 72*6777b538SAndroid Build Coastguard Worker### Step 2b: Compile with ErrorProne 73*6777b538SAndroid Build Coastguard Worker 74*6777b538SAndroid Build Coastguard WorkerThis step can be disabled via GN arg: `use_errorprone_java_compiler = false` 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker* Concurrently with step 1a: [ErrorProne] compiles java files and checks for bug 77*6777b538SAndroid Build Coastguard Worker patterns, including some [custom to Chromium][ep_plugins]. 78*6777b538SAndroid Build Coastguard Worker* ErrorProne used to replace step 1a, but was changed to a concurrent step after 79*6777b538SAndroid Build Coastguard Worker being identified as being slower. 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker[ErrorProne]: https://errorprone.info/ 82*6777b538SAndroid Build Coastguard Worker[ep_plugins]: /tools/android/errorprone_plugin/ 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker### Step 3: Desugaring (Device .jar Only) 85*6777b538SAndroid Build Coastguard Worker 86*6777b538SAndroid Build Coastguard WorkerThis step happens only when targets have `supports_android = true`. It is not 87*6777b538SAndroid Build Coastguard Workerapplied to `.jar` files used by `junit_binary`. 88*6777b538SAndroid Build Coastguard Worker 89*6777b538SAndroid Build Coastguard Worker* `//third_party/bazel/desugar` converts certain Java 8 constructs, such as 90*6777b538SAndroid Build Coastguard Worker lambdas and default interface methods, into constructs that are compatible 91*6777b538SAndroid Build Coastguard Worker with Java 7. 92*6777b538SAndroid Build Coastguard Worker 93*6777b538SAndroid Build Coastguard Worker### Step 4: Instrumenting (Device .jar Only) 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard WorkerThis step happens only when this GN arg is set: `use_jacoco_coverage = true` 96*6777b538SAndroid Build Coastguard Worker 97*6777b538SAndroid Build Coastguard Worker* [Jacoco] adds instrumentation hooks to methods. 98*6777b538SAndroid Build Coastguard Worker 99*6777b538SAndroid Build Coastguard Worker[Jacoco]: https://www.eclemma.org/jacoco/ 100*6777b538SAndroid Build Coastguard Worker 101*6777b538SAndroid Build Coastguard Worker### Step 5: Filtering 102*6777b538SAndroid Build Coastguard Worker 103*6777b538SAndroid Build Coastguard WorkerThis step happens only when targets that have `jar_excluded_patterns` or 104*6777b538SAndroid Build Coastguard Worker`jar_included_patterns` set (e.g. all `android_` targets). 105*6777b538SAndroid Build Coastguard Worker 106*6777b538SAndroid Build Coastguard Worker* Remove `.class` files that match the filters from the `.jar`. These `.class` 107*6777b538SAndroid Build Coastguard Worker files are generally those that are re-created with different implementations 108*6777b538SAndroid Build Coastguard Worker further on in the build process. 109*6777b538SAndroid Build Coastguard Worker * E.g.: `R.class` files - a part of [Android Resources]. 110*6777b538SAndroid Build Coastguard Worker * E.g.: `GEN_JNI.class` - a part of our [JNI] glue. 111*6777b538SAndroid Build Coastguard Worker * E.g.: `AppHooksImpl.class` - how `chrome_java` wires up different 112*6777b538SAndroid Build Coastguard Worker implementations for [non-public builds][apphooks]. 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker[JNI]: /third_party/jni_zero/README.md 115*6777b538SAndroid Build Coastguard Worker[Android Resources]: life_of_a_resource.md 116*6777b538SAndroid Build Coastguard Worker[apphooks]: /chrome/android/java/src/org/chromium/chrome/browser/AppHooksImpl.java 117*6777b538SAndroid Build Coastguard Worker 118*6777b538SAndroid Build Coastguard Worker### Step 6: Per-Library Dexing 119*6777b538SAndroid Build Coastguard Worker 120*6777b538SAndroid Build Coastguard WorkerThis step happens only when targets have `supports_android = true`. 121*6777b538SAndroid Build Coastguard Worker 122*6777b538SAndroid Build Coastguard Worker* [d8] converts `.jar` files containing `.class` files into `.dex.jar` files 123*6777b538SAndroid Build Coastguard Worker containing `classes.dex` files. 124*6777b538SAndroid Build Coastguard Worker* Dexing is incremental - it will reuse dex'ed classes from a previous build if 125*6777b538SAndroid Build Coastguard Worker the corresponding `.class` file is unchanged. 126*6777b538SAndroid Build Coastguard Worker* These per-library `.dex.jar` files are used directly by [incremental install], 127*6777b538SAndroid Build Coastguard Worker and are inputs to the Apk step when `enable_proguard = false`. 128*6777b538SAndroid Build Coastguard Worker * Even when `is_java_debug = false`, many apk targets do not enable ProGuard 129*6777b538SAndroid Build Coastguard Worker (e.g. unit tests). 130*6777b538SAndroid Build Coastguard Worker 131*6777b538SAndroid Build Coastguard Worker[d8]: https://developer.android.com/studio/command-line/d8 132*6777b538SAndroid Build Coastguard Worker[incremental install]: /build/android/incremental_install/README.md 133*6777b538SAndroid Build Coastguard Worker 134*6777b538SAndroid Build Coastguard Worker### Step 7: Apk / Bundle Module Compile 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker* Each `android_apk` and `android_bundle_module` template has a nested 137*6777b538SAndroid Build Coastguard Worker `java_library` target. The nested library includes final copies of files 138*6777b538SAndroid Build Coastguard Worker stripped out by prior filtering steps. These files include: 139*6777b538SAndroid Build Coastguard Worker * Final `R.java` files, created by `compile_resources.py`. 140*6777b538SAndroid Build Coastguard Worker * Final `GEN_JNI.java` for [JNI glue]. 141*6777b538SAndroid Build Coastguard Worker * `BuildConfig.java` and `NativeLibraries.java` (//base dependencies). 142*6777b538SAndroid Build Coastguard Worker 143*6777b538SAndroid Build Coastguard Worker[JNI glue]: /third_party/jni_zero/README.md 144*6777b538SAndroid Build Coastguard Worker 145*6777b538SAndroid Build Coastguard Worker### Step 8: Final Dexing 146*6777b538SAndroid Build Coastguard Worker 147*6777b538SAndroid Build Coastguard WorkerThis step is skipped when building using [Incremental Install]. 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard WorkerWhen `is_java_debug = true`: 150*6777b538SAndroid Build Coastguard Worker* [d8] merges all library `.dex.jar` files into a final `.mergeddex.jar`. 151*6777b538SAndroid Build Coastguard Worker 152*6777b538SAndroid Build Coastguard WorkerWhen `is_java_debug = false`: 153*6777b538SAndroid Build Coastguard Worker* [R8] performs whole-program optimization on all library `lib.java` `.jar` 154*6777b538SAndroid Build Coastguard Worker files and outputs a final `.r8dex.jar`. 155*6777b538SAndroid Build Coastguard Worker * For App Bundles, R8 creates a `.r8dex.jar` for each module. 156*6777b538SAndroid Build Coastguard Worker 157*6777b538SAndroid Build Coastguard Worker[Incremental Install]: /build/android/incremental_install/README.md 158*6777b538SAndroid Build Coastguard Worker[R8]: https://r8.googlesource.com/r8 159*6777b538SAndroid Build Coastguard Worker 160*6777b538SAndroid Build Coastguard Worker## Test APKs with apk_under_test 161*6777b538SAndroid Build Coastguard Worker 162*6777b538SAndroid Build Coastguard WorkerTest APKs are normal APKs that contain an `<instrumentation>` tag within their 163*6777b538SAndroid Build Coastguard Worker`AndroidManifest.xml`. If this tag specifies an `android:targetPackage` 164*6777b538SAndroid Build Coastguard Workerdifferent from itself, then Android will add that package's `classes.dex` to the 165*6777b538SAndroid Build Coastguard Workertest APK's Java classpath when run. In GN, you can enable this behavior using 166*6777b538SAndroid Build Coastguard Workerthe `apk_under_test` parameter on `instrumentation_test_apk` targets. Using it 167*6777b538SAndroid Build Coastguard Workeris discouraged if APKs have `proguard_enabled=true`. 168*6777b538SAndroid Build Coastguard Worker 169*6777b538SAndroid Build Coastguard Worker### Difference in Final Dex 170*6777b538SAndroid Build Coastguard Worker 171*6777b538SAndroid Build Coastguard WorkerWhen `enable_proguard=false`: 172*6777b538SAndroid Build Coastguard Worker* Any library depended on by the test APK that is also depended on by the 173*6777b538SAndroid Build Coastguard Worker apk-under-test is excluded from the test APK's final dex step. 174*6777b538SAndroid Build Coastguard Worker 175*6777b538SAndroid Build Coastguard WorkerWhen `enable_proguard=true`: 176*6777b538SAndroid Build Coastguard Worker* Test APKs cannot make use of the apk-under-test's dex because only symbols 177*6777b538SAndroid Build Coastguard Worker explicitly kept by `-keep` directives are guaranteed to exist after 178*6777b538SAndroid Build Coastguard Worker ProGuarding. As a work-around, test APKs include all of the apk-under-test's 179*6777b538SAndroid Build Coastguard Worker libraries directly in its own final dex such that the under-test apk's Java 180*6777b538SAndroid Build Coastguard Worker code is never used (because it is entirely shadowed by the test apk's dex). 181*6777b538SAndroid Build Coastguard Worker * We've found this configuration to be fragile, and are trying to [move away 182*6777b538SAndroid Build Coastguard Worker from it](https://bugs.chromium.org/p/chromium/issues/detail?id=890452). 183*6777b538SAndroid Build Coastguard Worker 184*6777b538SAndroid Build Coastguard Worker### Difference in GEN_JNI.java 185*6777b538SAndroid Build Coastguard Worker* Calling native methods using [JNI glue] requires that a `GEN_JNI.java` class 186*6777b538SAndroid Build Coastguard Worker be generated that contains all native methods for an APK. There cannot be 187*6777b538SAndroid Build Coastguard Worker conflicting `GEN_JNI` classes in both the test apk and the apk-under-test, so 188*6777b538SAndroid Build Coastguard Worker only the apk-under-test has one generated for it. As a result this, 189*6777b538SAndroid Build Coastguard Worker instrumentation test APKs that use apk-under-test cannot use native methods 190*6777b538SAndroid Build Coastguard Worker that aren't already part of the apk-under-test. 191*6777b538SAndroid Build Coastguard Worker 192*6777b538SAndroid Build Coastguard Worker## How to Generate Java Source Code 193*6777b538SAndroid Build Coastguard WorkerThere are two ways to go about generating source files: Annotation Processors 194*6777b538SAndroid Build Coastguard Workerand custom build steps. 195*6777b538SAndroid Build Coastguard Worker 196*6777b538SAndroid Build Coastguard Worker### Annotation Processors 197*6777b538SAndroid Build Coastguard Worker* These are run by `javac` as part of the compile step. 198*6777b538SAndroid Build Coastguard Worker* They **cannot** modify the source files that they apply to. They can only 199*6777b538SAndroid Build Coastguard Worker generate new sources. 200*6777b538SAndroid Build Coastguard Worker* Use these when: 201*6777b538SAndroid Build Coastguard Worker * an existing Annotation Processor does what you want 202*6777b538SAndroid Build Coastguard Worker (E.g. Dagger, AutoService, etc.), or 203*6777b538SAndroid Build Coastguard Worker * you need to understand Java types to do generation. 204*6777b538SAndroid Build Coastguard Worker 205*6777b538SAndroid Build Coastguard Worker### Custom Build Steps 206*6777b538SAndroid Build Coastguard Worker* These use discrete build actions to generate source files. 207*6777b538SAndroid Build Coastguard Worker * Some generate `.java` directly, but most generate a zip file of sources 208*6777b538SAndroid Build Coastguard Worker (called a `.srcjar`) to simplify the number of inputs / outputs. 209*6777b538SAndroid Build Coastguard Worker* Examples of existing templates: 210*6777b538SAndroid Build Coastguard Worker * `jinja_template`: Generates source files using [Jinja]. 211*6777b538SAndroid Build Coastguard Worker * `java_cpp_template`: Generates source files using the C preprocessor. 212*6777b538SAndroid Build Coastguard Worker * `java_cpp_enum`: Generates `@IntDef`s based on enums within `.h` files. 213*6777b538SAndroid Build Coastguard Worker * `java_cpp_strings`: Generates String constants based on strings defined in 214*6777b538SAndroid Build Coastguard Worker `.cc` files. 215*6777b538SAndroid Build Coastguard Worker* Custom build steps are preferred over Annotation Processors because they are 216*6777b538SAndroid Build Coastguard Worker generally easier to understand, and can run in parallel with other steps 217*6777b538SAndroid Build Coastguard Worker (rather than being tied to compiles). 218*6777b538SAndroid Build Coastguard Worker 219*6777b538SAndroid Build Coastguard Worker[Jinja]: https://palletsprojects.com/p/jinja/ 220*6777b538SAndroid Build Coastguard Worker 221*6777b538SAndroid Build Coastguard Worker## Static Analysis & Code Checks 222*6777b538SAndroid Build Coastguard Worker 223*6777b538SAndroid Build Coastguard WorkerSee [static_analysis.md](static_analysis.md) 224