Skip to content

Commit 6292c99

Browse files
committed
Attempt to fix missing class error by not using tree artifacts for bootclasspath
A few times a year across many thousands of builds we encounter a rare error about the `DumpPlatformClassPath` class being missing. Our Bazel setup uses dynamic execution, builds without the bytes, remote execution + remote caching, and path mapping. The error we encounter is as follows: ``` Error: Could not find or load main class DumpPlatformClassPath Caused by: java.lang.ClassNotFoundException: DumpPlatformClassPath ``` I'm guessing that this is happening due to some kind of Bazel bug that happens with our Bazel setup and tree artifacts, i.e., declare_directory. Best I can tell this is happening because the `DumpPlatformClassPath.class` file is somehow not materializing correctly. I'm not 100% confident about that, but it's my leading hypothesis at this point in time. This commit changes the actions in `bootclasspath.bzl` to, when possible, not rely on tree artifacts. Instead, they rely JDK 11+'s ability to launch single-file programs (introduced in JEP 330). This avoids the `javac` action and `declare_directory` previously required to compile `DumpPlatformClassPath`.
1 parent 9d6184b commit 6292c99

File tree

1 file changed

+38
-26
lines changed

1 file changed

+38
-26
lines changed

toolchains/bootclasspath.bzl

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -129,29 +129,35 @@ def _bootclasspath_impl(ctx):
129129
exec_javabase = ctx.attr.java_runtime_alias[java_common.JavaRuntimeInfo]
130130
env = ctx.attr._utf8_environment[Utf8EnvironmentInfo].environment
131131

132-
class_dir = ctx.actions.declare_directory("%s_classes" % ctx.label.name)
133-
134-
args = ctx.actions.args()
135-
args.add("-source")
136-
args.add("8")
137-
args.add("-target")
138-
args.add("8")
139-
args.add("-Xlint:-options")
140-
args.add("-J-XX:-UsePerfData")
141-
args.add("-d")
142-
args.add_all([class_dir], expand_directories = False)
143-
args.add(ctx.file.src)
144-
145-
ctx.actions.run(
146-
executable = "%s/bin/javac" % exec_javabase.java_home,
147-
mnemonic = "JavaToolchainCompileClasses",
148-
inputs = [ctx.file.src] + ctx.files.java_runtime_alias,
149-
outputs = [class_dir],
150-
arguments = [args],
151-
env = env,
152-
execution_requirements = _SUPPORTS_PATH_MAPPING,
153-
use_default_shell_env = True,
154-
)
132+
# If possible, use JDK 11+'s ability to run a single Java file to avoid a
133+
# separate action to compile DumpPlatformClassPath.
134+
use_source_launcher = exec_javabase.version >= 11
135+
136+
class_dir = None
137+
if not use_source_launcher:
138+
class_dir = ctx.actions.declare_directory("%s_classes" % ctx.label.name)
139+
140+
args = ctx.actions.args()
141+
args.add("-source")
142+
args.add("8")
143+
args.add("-target")
144+
args.add("8")
145+
args.add("-Xlint:-options")
146+
args.add("-J-XX:-UsePerfData")
147+
args.add("-d")
148+
args.add_all([class_dir], expand_directories = False)
149+
args.add(ctx.file.src)
150+
151+
ctx.actions.run(
152+
executable = "%s/bin/javac" % exec_javabase.java_home,
153+
mnemonic = "JavaToolchainCompileClasses",
154+
inputs = [ctx.file.src] + ctx.files.java_runtime_alias,
155+
outputs = [class_dir],
156+
arguments = [args],
157+
env = env,
158+
execution_requirements = _SUPPORTS_PATH_MAPPING,
159+
use_default_shell_env = True,
160+
)
155161

156162
unstripped_bootclasspath = ctx.actions.declare_file("%s_unstripped.jar" % ctx.label.name)
157163

@@ -161,8 +167,13 @@ def _bootclasspath_impl(ctx):
161167
args.add("--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED")
162168
args.add("--add-exports=jdk.compiler/com.sun.tools.javac.platform=ALL-UNNAMED")
163169
args.add("--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED")
164-
args.add_all("-cp", [class_dir], expand_directories = False)
165-
args.add("DumpPlatformClassPath")
170+
171+
if use_source_launcher:
172+
args.add(ctx.file.src)
173+
else:
174+
args.add_all("-cp", [class_dir], expand_directories = False)
175+
args.add("DumpPlatformClassPath")
176+
166177
args.add(unstripped_bootclasspath)
167178

168179
if ctx.attr.language_version_bootstrap_runtime:
@@ -211,7 +222,8 @@ Rerun with --toolchain_resolution_debug='@bazel_tools//tools/jdk:bootstrap_runti
211222
if len(system) != len(system_files):
212223
system = None
213224

214-
inputs = depset([class_dir] + ctx.files.java_runtime_alias, transitive = [any_javabase.files])
225+
classpath_input = ctx.file.src if use_source_launcher else class_dir
226+
inputs = depset([classpath_input] + ctx.files.java_runtime_alias, transitive = [any_javabase.files])
215227
ctx.actions.run(
216228
executable = str(exec_javabase.java_executable_exec_path),
217229
mnemonic = "JavaToolchainCompileBootClasspath",

0 commit comments

Comments
 (0)