tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

java_toolchain.md (9374B)


Chromium's Java Toolchain

This doc aims to describe the Chrome build process that takes a set of .java files and turns them into a classes.dex file.

[TOC]

Core GN Target Types

The following have supports_android and requires_android set to false by default:

The following have supports_android and requires_android set to true. They also have a default jar_excluded_patterns set (more on that later):

All target names must end with "_java" so that the build system can distinguish them from non-java targets (or other variations).

Most targets produce two separate .jar files:

* Host .jar files live in lib.java/ so that they are archived in builder/tester bots (which do not archive obj/).

From Source to Final Dex

Step 1: Create interface .jar with turbine or ijar

What are interface jars?:

removed.

when only private implementation details change.

For prebuilt .jar files: we use [//third_party/ijar] to create interface .jar files from the prebuilt ones.

For non-prebuilt .jar files`: we use [//third_party/turbine] to create interface .jar files directly from .java source files. Turbine is faster than javac because it does not compile method bodies. Although Turbine causes us to compile files twice, it speeds up builds by allowing javac compilation of targets to happen concurrently with their dependencies. We also use Turbine to run our annotation processors.

[//thirdparty/ijar]: /thirdparty/ijar/README.chromium [//thirdparty/turbine]: /thirdparty/turbine/README.chromium

Step 2a: Compile with javac

This step is the only step that does not apply to prebuilt targets.

* This includes .java files that live within .srcjar files, referenced through srcjar_deps.

its deps. * When deps are library targets, the Step 1 .jar file is used. * When deps are prebuilt targets, the original .jar file is used. * All .jar processing done in subsequent steps does not impact compilation classpath.

* If one source file changes within a library, then the entire library is recompiled. * Prefer smaller targets to avoid slow compiles.

Step 2b: Compile with ErrorProne

This step can be disabled via GN arg: use_errorprone_java_compiler = false

patterns, including some [custom to Chromium][ep_plugins].

being identified as being slower.

[ErrorProne]: https://errorprone.info/ [epplugins]: /tools/android/errorproneplugin/

Step 3: Desugaring (Device .jar Only)

This step happens only when targets have supports_android = true. It is not applied to .jar files used by junit_binary.

lambdas and default interface methods, into constructs that are compatible with Java 7.

Step 4: Instrumenting (Device .jar Only)

This step happens only when this GN arg is set: use_jacoco_coverage = true

[Jacoco]: https://www.eclemma.org/jacoco/

Step 5: Filtering

This step happens only when targets that have jar_excluded_patterns or jar_included_patterns set (e.g. all android_ targets).

files are generally those that are re-created with different implementations further on in the build process. * E.g.: R.class files - a part of [Android Resources]. * E.g.: GEN_JNI.class - a part of our [JNI] glue.

[JNI]: /thirdparty/jnizero/README.md [Android Resources]: lifeofa_resource.md

Step 6: Per-Library Dexing

This step happens only when targets have supports_android = true.

containing classes.dex files.

the corresponding .class file is unchanged.

and are inputs to the Apk step when enable_proguard = false. * Even when is_java_debug = false, many apk targets do not enable ProGuard (e.g. unit tests).

[d8]: https://developer.android.com/studio/command-line/d8 [incremental install]: /build/android/incremental_install/README.md

Step 7: Apk / Bundle Module Compile

java_library target. The nested library includes final copies of files stripped out by prior filtering steps. These files include: * Final R.java files, created by compile_resources.py. * Final GEN_JNI.java for [JNI glue]. * BuildConfig.java and NativeLibraries.java (//base dependencies).

[JNI glue]: /thirdparty/jnizero/README.md

Step 8: Final Dexing

This step is skipped when building using [Incremental Install].

When is_java_debug = true:

When is_java_debug = false:

files and outputs a final .r8dex.jar. * For App Bundles, R8 creates a .r8dex.jar for each module.

[Incremental Install]: /build/android/incremental_install/README.md [R8]: https://r8.googlesource.com/r8

Test APKs with apk_under_test

Test APKs are normal APKs that contain an <instrumentation> tag within their AndroidManifest.xml. If this tag specifies an android:targetPackage different from itself, then Android will add that package's classes.dex to the test APK's Java classpath when run. In GN, you can enable this behavior using the apk_under_test parameter on instrumentation_test_apk targets. Using it is discouraged if APKs have proguard_enabled=true.

Difference in Final Dex

When enable_proguard=false:

apk-under-test is excluded from the test APK's final dex step.

When enable_proguard=true:

explicitly kept by -keep directives are guaranteed to exist after ProGuarding. As a work-around, test APKs include all of the apk-under-test's libraries directly in its own final dex such that the under-test apk's Java code is never used (because it is entirely shadowed by the test apk's dex). * We've found this configuration to be fragile, and are trying to [move away from it](https://bugs.chromium.org/p/chromium/issues/detail?id=890452).

Difference in GEN_JNI.java

be generated that contains all native methods for an APK. There cannot be conflicting GEN_JNI classes in both the test apk and the apk-under-test, so only the apk-under-test has one generated for it. As a result this, instrumentation test APKs that use apk-under-test cannot use native methods that aren't already part of the apk-under-test.

How to Generate Java Source Code

There are two ways to go about generating source files: Annotation Processors and custom build steps.

Annotation Processors

generate new sources.

* an existing Annotation Processor does what you want (E.g. Dagger, AutoService, etc.), or * you need to understand Java types to do generation.

Custom Build Steps

* Some generate .java directly, but most generate a zip file of sources (called a .srcjar) to simplify the number of inputs / outputs.

* jinja_template: Generates source files using [Jinja]. * java_cpp_template: Generates source files using the C preprocessor. * java_cpp_enum: Generates @IntDefs based on enums within .h files. * java_cpp_strings: Generates String constants based on strings defined in .cc files.

generally easier to understand, and can run in parallel with other steps (rather than being tied to compiles).

[Jinja]: https://palletsprojects.com/p/jinja/

Static Analysis & Code Checks

See static_analysis.md