Skip to content

Commit

Permalink
Implement local_java_repository for local version of Java
Browse files Browse the repository at this point in the history
Implement local_java_repository for local version of Java.

Repository is a way to verify Java is really present and emit a nice message otherwise.

Resolves #6993

Closes #12078.

PiperOrigin-RevId: 331980488
  • Loading branch information
comius authored and copybara-github committed Sep 16, 2020
1 parent 35b3780 commit f259b8a
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 22 deletions.
1 change: 0 additions & 1 deletion scripts/bootstrap/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,6 @@ function build_jni() {

build_jni "${ARCHIVE_DIR}"

cp src/main/tools/jdk.BUILD ${ARCHIVE_DIR}/jdk.BUILD
cp $OUTPUT_DIR/libblaze.jar ${ARCHIVE_DIR}

# TODO(b/28965185): Remove when xcode-locator is no longer required in embedded_binaries.
Expand Down
1 change: 0 additions & 1 deletion src/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,6 @@ filegroup(
"//src/main/native/windows:target-os-native-lib",
"//src/main/tools:build-runfiles",
"//src/main/tools:process-wrapper",
"//src/main/tools:jdk-support",
"//src/main/tools:linux-sandbox",
"//tools/osx:xcode-locator",
] + select({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# External dependencies for the java_* rules.
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")

new_local_repository(
local_java_repository(
name = "local_jdk",
build_file = __embedded_dir__ + "/jdk.BUILD",
path = DEFAULT_SYSTEM_JAVABASE,
java_home = DEFAULT_SYSTEM_JAVABASE,
)

bind(
Expand Down Expand Up @@ -97,7 +97,7 @@ bind(
maybe(
http_archive,
name = "remotejdk11_linux",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "360626cc19063bc411bfed2914301b908a8f77a7919aaea007a977fa8fb3cde1",
strip_prefix = "zulu11.37.17-ca-jdk11.0.6-linux_x64",
urls = [
Expand All @@ -109,7 +109,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk11_linux_aarch64",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "a452f1b9682d9f83c1c14e54d1446e1c51b5173a3a05dcb013d380f9508562e4",
strip_prefix = "zulu11.37.48-ca-jdk11.0.6-linux_aarch64",
urls = [
Expand All @@ -121,7 +121,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk11_linux_ppc64le",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "a417db0295b1f4b538ecbaf7c774f3a177fab9657a665940170936c0eca4e71a",
strip_prefix = "jdk-11.0.7+10",
urls = [
Expand All @@ -134,7 +134,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk11_linux_s390x",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "d9b72e87a1d3ebc0c9552f72ae5eb150fffc0298a7cb841f1ce7bfc70dcd1059",
strip_prefix = "jdk-11.0.7+10",
urls = [
Expand All @@ -147,7 +147,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk11_macos",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "e1fe56769f32e2aaac95e0a8f86b5a323da5af3a3b4bba73f3086391a6cc056f",
strip_prefix = "zulu11.37.17-ca-jdk11.0.6-macosx_x64",
urls = [
Expand All @@ -159,7 +159,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk11_win",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "a9695617b8374bfa171f166951214965b1d1d08f43218db9a2a780b71c665c18",
strip_prefix = "zulu11.37.17-ca-jdk11.0.6-win_x64",
urls = [
Expand All @@ -171,7 +171,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk14_linux",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "48bb8947034cd079ad1ef83335e7634db4b12a26743a0dc314b6b861480777aa",
strip_prefix = "zulu14.28.21-ca-jdk14.0.1-linux_x64",
urls = [
Expand All @@ -183,7 +183,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk14_macos",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "088bd4d0890acc9f032b738283bf0f26b2a55c50b02d1c8a12c451d8ddf080dd",
strip_prefix = "zulu14.28.21-ca-jdk14.0.1-macosx_x64",
urls = ["https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu14.28.21-ca-jdk14.0.1-macosx_x64.tar.gz"],
Expand All @@ -193,7 +193,7 @@ maybe(
maybe(
http_archive,
name = "remotejdk14_win",
build_file = "@local_jdk//:BUILD.bazel",
build_file = "@bazel_tools//tools/jdk:jdk.BUILD",
sha256 = "9cb078b5026a900d61239c866161f0d9558ec759aa15c5b4c7e905370e868284",
strip_prefix = "zulu14.28.21-ca-jdk14.0.1-win_x64",
urls = ["https://mirror.bazel.build/cdn.azul.com/zulu/bin/zulu14.28.21-ca-jdk14.0.1-win_x64.zip"],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
The path to the root of the runtime.
Subject to <a href="${link make-variables}">"Make" variable</a> substitution.
If this path is absolute, the rule denotes a non-hermetic Java runtime with a well-known
path. In that case, the <code>srcs</code> and <java></code> attributes must be empty.
path. In that case, the <code>srcs</code> and <code>java</code> attributes must be empty.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
.add(attr("java_home", STRING))
.add(attr("output_licenses", LICENSE))
Expand Down
7 changes: 0 additions & 7 deletions src/main/tools/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,6 @@ cc_binary(
}),
)

filegroup(
name = "jdk-support",
srcs = [
"jdk.BUILD",
],
)

exports_files([
"build_interface_so",
])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,10 @@ public void setupMockToolsRepository(MockToolsConfig config) throws IOException
"",
"def http_file(**kwargs):",
" pass");
config.create(
"bazel_tools_workspace/tools/jdk/local_java_repository.bzl",
"def local_java_repository(**kwargs):",
" pass");
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ public void initializeSkyframeExecutor(boolean doPackageLoadingChecks) throws Ex
"",
"def http_file(**kwargs):",
" pass");
mockToolsConfig.create(
"bazel_tools_workspace/tools/jdk/local_java_repository.bzl",
"def local_java_repository(**kwargs):",
" pass");
initializeMockClient();

packageOptions = parsePackageOptions();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@ public final void initializeSkyframeExecutor() throws Exception {
"",
"def http_file(**kwargs):",
" pass");
mockToolsConfig.create(
"bazel_tools_workspace/tools/jdk/local_java_repository.bzl",
"def local_java_repository(**kwargs):",
" pass");

analysisMock.setupMockClient(mockToolsConfig);
analysisMock.setupMockWorkspaceFiles(directories.getEmbeddedBinariesRoot());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ private static void mockEmbeddedTools(Path embeddedBinaries) throws IOException
"def maybe(repo_rule, name, **kwargs):",
" if name not in native.existing_rules():",
" repo_rule(name = name, **kwargs)");
FileSystemUtils.writeIsoLatin1(tools.getRelative("tools/jdk/BUILD"));
FileSystemUtils.writeIsoLatin1(
tools.getRelative("tools/jdk/local_java_repository.bzl"),
"def local_java_repository(**kwargs):",
" pass");
}

private void fetchExternalRepo(RepositoryName externalRepo) {
Expand Down
29 changes: 29 additions & 0 deletions src/test/shell/bazel/bazel_with_jdk_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,33 @@ function test_bazel_license_prints_jdk_license() {
fail "'bazel license' did not print an expected string from LICENSE"
}


function test_bazel_reports_missing_local_jdk() {
# Make a JAVA_HOME with javac and without java
# This fails discovery on systems that rely on JAVA_HOME, rely on PATH and
# also on Darwin that is using /usr/libexec/java_home for discovery

mkdir bin
touch bin/javac
chmod +x bin/javac
export JAVA_HOME="$PWD"
export PATH="$PWD/bin:$PATH"

mkdir -p java/main
cat >java/main/BUILD <<EOF
java_library(
name = 'JavaExample',
srcs = ['JavaExample.java'],
)
EOF

cat >java/main/JavaExample.java <<EOF
public class JavaExample {
}
EOF

bazel build java/main:JavaExample &>"${TEST_log}" && fail "build should have failed" || true
expect_log "Auto-Configuration Error: Cannot find Java binary"
}

run_suite "bazel test suite"
3 changes: 3 additions & 0 deletions tools/jdk/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,10 @@ filegroup(
"BUILD-jdk", # Tools are build from the workspace for tests.
"DumpPlatformClassPath.java",
"default_java_toolchain.bzl",
"fail_rule.bzl",
"java_toolchain_alias.bzl",
"jdk.BUILD",
"local_java_repository.bzl",
"nosystemjdk/README",
"proguard_whitelister.py",
"proguard_whitelister_test.py",
Expand Down
35 changes: 35 additions & 0 deletions tools/jdk/fail_rule.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2020 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""A rule than fails during analysis."""

def _fail_rule_impl(ctx):
if ctx.attr.header:
fail("%s %s" % (ctx.attr.header, ctx.attr.message))
else:
fail(ctx.attr.message)

fail_rule = rule(
doc = "A rule that fails during analysis.",
implementation = _fail_rule_impl,
attrs = {
"header": attr.string(
doc = "Header of the message.",
),
"message": attr.string(
mandatory = True,
doc = "Message to display.",
),
},
)
File renamed without changes.
74 changes: 74 additions & 0 deletions tools/jdk/local_java_repository.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2020 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Java repository implementation.
Creates a local repository using jdk.BUILD file.
When Java executable is not present it creates a BUILD file with target "jdk"
displaying an error message.
"""

def _local_java_repository_impl(repository_ctx):
java_home = repository_ctx.attr.java_home
java_home_path = repository_ctx.path(java_home)
if not java_home_path.exists:
fail('The path indicated by the "java_home" attribute "%s" (absolute: "%s") ' +
"does not exist." % (java_home, str(java_home_path)))

repository_ctx.file(
"WORKSPACE",
"# DO NOT EDIT: automatically generated WORKSPACE file for local_java_repository\n" +
"workspace(name = \"{name}\")\n".format(name = repository_ctx.name),
)

extension = ".exe" if repository_ctx.os.name.lower().find("windows") != -1 else ""
if java_home_path.get_child("bin").get_child("java" + extension).exists:
repository_ctx.file(
"BUILD.bazel",
repository_ctx.read(repository_ctx.path(repository_ctx.attr._build_file)),
False,
)

# Symlink all files
for file in repository_ctx.path(java_home).readdir():
repository_ctx.symlink(file, file.basename)

return

# Java binary does not exist
# TODO(ilist): replace error message after toolchain implementation
repository_ctx.file(
"BUILD.bazel",
'''load("@bazel_tools//tools/jdk:fail_rule.bzl", "fail_rule")
fail_rule(
name = "jdk",
header = "Auto-Configuration Error:",
message = ("Cannot find Java binary %s in %s; either correct your JAVA_HOME, " +
"PATH or specify embedded Java (e.g. " +
"--javabase=@bazel_tools//tools/jdk:remote_jdk11)")
)''' % ("bin/java" + extension, java_home),
False,
)

local_java_repository = repository_rule(
implementation = _local_java_repository_impl,
local = True,
configure = True,
attrs = {
"java_home": attr.string(),
"_build_file": attr.label(default = "@bazel_tools//tools/jdk:jdk.BUILD"),
},
)

0 comments on commit f259b8a

Please sign in to comment.