aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Miller-Cushon <cushon@google.com>2022-01-11 08:36:40 -0800
committerJavac Team <javac-team+copybara@google.com>2022-01-11 08:37:29 -0800
commitdb7b4bf2862d547d2568b6b2d2e7ee0397a3fd4f (patch)
tree6bfd703ed8b0cefeb49a274a44f745bc4856a1c4
parenta0a74df826ac4a112ab0be4d6b9c6a069c690970 (diff)
downloadturbine-db7b4bf2862d547d2568b6b2d2e7ee0397a3fd4f.tar.gz
Don't crash on `module-info.java`s is we can't load `java.base`
This can happen when compiling a module declaration against a non-modular bootclasspath. The lookup of `java.base` is only used to get its version, which we can skip. PiperOrigin-RevId: 421040147
-rw-r--r--java/com/google/turbine/binder/ModuleBinder.java11
-rw-r--r--javatests/com/google/turbine/lower/MissingJavaBaseModule.java105
2 files changed, 111 insertions, 5 deletions
diff --git a/java/com/google/turbine/binder/ModuleBinder.java b/java/com/google/turbine/binder/ModuleBinder.java
index 0b0180e..e88440d 100644
--- a/java/com/google/turbine/binder/ModuleBinder.java
+++ b/java/com/google/turbine/binder/ModuleBinder.java
@@ -137,15 +137,16 @@ public class ModuleBinder {
}
}
if (!requiresJavaBase) {
- // everything requires java.base, either explicitly or implicitly
- ModuleInfo javaBaseModule = moduleEnv.getNonNull(ModuleSymbol.JAVA_BASE);
+ // Everything requires java.base, either explicitly or implicitly.
+ ModuleInfo javaBaseModule = moduleEnv.get(ModuleSymbol.JAVA_BASE);
+ // Tolerate a missing java.base module, e.g. when compiling a module against a non-modular
+ // bootclasspath, and just omit the version below.
+ String javaBaseVersion = javaBaseModule != null ? javaBaseModule.version() : null;
requires =
ImmutableList.<RequireInfo>builder()
.add(
new RequireInfo(
- ModuleSymbol.JAVA_BASE.name(),
- TurbineFlag.ACC_MANDATED,
- javaBaseModule.version()))
+ ModuleSymbol.JAVA_BASE.name(), TurbineFlag.ACC_MANDATED, javaBaseVersion))
.addAll(requires.build());
}
diff --git a/javatests/com/google/turbine/lower/MissingJavaBaseModule.java b/javatests/com/google/turbine/lower/MissingJavaBaseModule.java
new file mode 100644
index 0000000..230b18f
--- /dev/null
+++ b/javatests/com/google/turbine/lower/MissingJavaBaseModule.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2021 Google Inc. 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.
+ */
+
+package com.google.turbine.lower;
+
+import static com.google.common.base.StandardSystemProperty.JAVA_CLASS_VERSION;
+import static com.google.common.collect.ImmutableMap.toImmutableMap;
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.turbine.binder.ClassPath;
+import com.google.turbine.binder.CtSymClassBinder;
+import com.google.turbine.binder.JimageClassBinder;
+import com.google.turbine.binder.bound.ModuleInfo;
+import com.google.turbine.binder.bytecode.BytecodeBoundClass;
+import com.google.turbine.binder.env.Env;
+import com.google.turbine.binder.lookup.TopLevelIndex;
+import com.google.turbine.binder.sym.ClassSymbol;
+import com.google.turbine.binder.sym.ModuleSymbol;
+import java.util.Map;
+import java.util.Optional;
+import org.jspecify.nullness.Nullable;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class MissingJavaBaseModule {
+
+ @Test
+ public void test() throws Exception {
+
+ Map<String, String> sources = ImmutableMap.of("module-info.java", "module foo {}");
+
+ Map<String, byte[]> expected =
+ IntegrationTestSupport.runJavac(
+ sources, ImmutableList.of(), ImmutableList.of("--release", "9", "--module-version=42"));
+
+ ClassPath base =
+ Double.parseDouble(JAVA_CLASS_VERSION.value()) < 54
+ ? JimageClassBinder.bindDefault()
+ : CtSymClassBinder.bind(9);
+ ClassPath bootclasspath =
+ new ClassPath() {
+ @Override
+ public Env<ClassSymbol, BytecodeBoundClass> env() {
+ return base.env();
+ }
+
+ @Override
+ public Env<ModuleSymbol, ModuleInfo> moduleEnv() {
+ return new Env<ModuleSymbol, ModuleInfo>() {
+ @Override
+ public @Nullable ModuleInfo get(ModuleSymbol sym) {
+ if (sym.name().equals("java.base")) {
+ return null;
+ }
+ return base.moduleEnv().get(sym);
+ }
+ };
+ }
+
+ @Override
+ public TopLevelIndex index() {
+ return base.index();
+ }
+
+ @Override
+ public @Nullable Supplier<byte[]> resource(String path) {
+ return base.resource(path);
+ }
+ };
+ Map<String, byte[]> actual =
+ IntegrationTestSupport.runTurbine(
+ sources,
+ ImmutableList.of(),
+ bootclasspath,
+ Optional.of("42"),
+ /* javacopts= */ ImmutableList.of());
+
+ assertEquals(dump(expected), dump(actual));
+ }
+
+ private String dump(Map<String, byte[]> map) throws Exception {
+ return IntegrationTestSupport.dump(
+ map.entrySet().stream()
+ .filter(e -> e.getKey().endsWith("module-info"))
+ .collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
+ }
+}