Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Java 11 doesn't work with Android builds #8615

Open
cushon opened this issue Jun 12, 2019 · 9 comments
Open

Java 11 doesn't work with Android builds #8615

cushon opened this issue Jun 12, 2019 · 9 comments
Labels
P2 We'll consider working on this in future. (Assignee optional) team-Rules-Java Issues for Java rules type: bug

Comments

@cushon
Copy link
Contributor

cushon commented Jun 12, 2019

Using Bazel at head (4aa48f9) and configuring the Java 11 language level with --javacopt='--release 11' (as currently suggested in #6245 (comment)) doesn't allow building Android targets.

Repro:

git clone git@github.com:bazelbuild/examples.git bazel-examples
cd bazel-examples/android/tutorial

Create a minimal WORKSPACE and BUILD:

git diff HEAD
diff --git a/android/tutorial/WORKSPACE b/android/tutorial/WORKSPACE
new file mode 100644
index 0000000..9cc43bb
--- /dev/null
+++ b/android/tutorial/WORKSPACE
@@ -0,0 +1 @@
+android_sdk_repository(name = "androidsdk")
diff --git a/android/tutorial/src/main/java/com/example/bazel/BUILD b/android/tutorial/src/main/java/com/example/bazel/BUILD
new file mode 100644
index 0000000..76f8ba7
--- /dev/null
+++ b/android/tutorial/src/main/java/com/example/bazel/BUILD
@@ -0,0 +1,13 @@
+package(
+    default_visibility = ["//src:__subpackages__"],
+)
+
+android_library(
+    name = "greeter_activity",
+    srcs = [
+        "Greeter.java",
+        "MainActivity.java",
+    ],
+    manifest = "AndroidManifest.xml",
+    resource_files = glob(["res/**"]),
+)

Building with default options works:

$ bazel build ...
...
Target //src/main/java/com/example/bazel:greeter_activity up-to-date:

Building with --javacopt='--release 11' doesn't:

$ bazel build --javacopt='--release 11' ...
...
ERROR: bazel-examples/android/tutorial/src/main/java/com/example/bazel/BUILD:5:1: Building src/main/java/com/example/bazel/libgreeter_activity.jar (2 source files) failed (Exit 1)
src/main/java/com/example/bazel/MainActivity.java:3: error: package android.app does not exist
import android.app.Activity;
                  ^

Setting --javacopt='-verbose --release 11' provides some hints about what's going on:

$ bazel build --javacopt='-verbose --release 11' ...
...
[search path for class files: bazel-out/host/bin/external/bazel_tools/tools/android/java_lang_extras.jar,external/androidsdk/platforms/android-28/android.jar,bazel-out/k8-fastbuild/bin/src/main/java/com/example/bazel/greeter_activity_resources.jar]
...
[loading modules/java.base/java/lang/Object.class]

The search path for class files shows that the expected bootclasspath jars are being passed to javac, including android.jar. But the [loading modules/java.base/java/lang/Object.class] suggests that when targeting a language level that supports modules (i.e. Java >= 9), the compiler is ignoring the legacy bootclasspath configuration and looking at the host/exec JDK's module equivalent.

That's supported by the javac docs:

--boot-class-path path or -bootclasspath path
Overrides the location of the bootstrap class files.
This can only be used when compiling for versions prior to JDK 9. As applicable, see the descriptions in --release, -source, or -target for details.

The --system flag can be used to support this kind of cross compilation, but the argument is a path to a complete JDK containing the system APIs we're targeting, which we don't have for android.jar.

@cushon cushon added the team-Rules-Java Issues for Java rules label Jun 12, 2019
@iirina
Copy link
Contributor

iirina commented Jun 13, 2019

cc @jin

@jin
Copy link
Member

jin commented Jun 13, 2019

cc @ahumesky

@iirina iirina added P2 We'll consider working on this in future. (Assignee optional) and removed untriaged labels Jul 3, 2019
@iirina iirina self-assigned this Jul 3, 2019
@sgammon
Copy link

sgammon commented Jul 17, 2020

this is a blocker for us because we're building in a Micronaut codebase on Java 12. is there any way the community can help?

@ThomasCJY
Copy link
Contributor

Any update on this issue? This has become a blocker for us to bump java version to 11

@mauriciogg
Copy link
Contributor

Looks like this gradle change needs to be replicated in bazel: https://cs.android.com/android-studio/platform/tools/base/+/79330f946ba270218ef06e34dfaed22c759c0613

Which is just unpacking an core-for-system-modules.jar with the sdk (30+) and passing the android jar in the classpath instead of bootclasspath. The core-for-system-modules.jar dependency makes it so that this only works for api 30 and above (not entirely sure why classpath is not enough though).

@cushon
Copy link
Contributor Author

cushon commented Sep 30, 2021

We laid most of the groundwork for this with java_common.BootClassPathInfo. That provider can be used with java_toolchain.bootclasspath to set the contents of a 'system' directory that's passed to javac's --system flag.

--system overrides the system APIs for Java > 9 compilations, in the way that -bootclasspath did for Java <= 8 compilations.

I think most of what's needed here is to create a system directory containing the classes in android.jar, and then to configure the java_toolchain for Android compilations to use it.

@cushon
Copy link
Contributor Author

cushon commented Sep 30, 2021

To expand a little, this doesn't require changes to Bazel core, it 'just' requires creating a starlark rule that packages up android.jar and provides java_common.BootClassPathInfo, and then to use that rule in the bootclasspath attribute of the configured java_toolchain.

e.g. something like

java_toolchain(
   ...
   bootclasspath = [":android_system"]
)

@dhbaird
Copy link

dhbaird commented Jun 29, 2022

Using local JDK seems to work. But I need remote JDK to work, and to get any version between up to 13 working (a restriction per proguard 6.2.2), which leads me to this issue. Any practical info that could help me? I'm already building bazel from source in order to work around another issue (#13989), so I can edit anything needed to do so. I'm working off of release-6.0.0-pre.20220502.3rc1. Thanks in advance.

@jvliwanag
Copy link

I needed to build an android_library with a maven dependency on a classes on Java 17. My workaround was to use kt_android_library which worked even for just plain java sources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
P2 We'll consider working on this in future. (Assignee optional) team-Rules-Java Issues for Java rules type: bug
Projects
None yet
Development

No branches or pull requests

10 participants