diff options
author | Liam Miller-Cushon <cushon@google.com> | 2022-01-11 08:36:40 -0800 |
---|---|---|
committer | Javac Team <javac-team+copybara@google.com> | 2022-01-11 08:37:29 -0800 |
commit | db7b4bf2862d547d2568b6b2d2e7ee0397a3fd4f (patch) | |
tree | 6bfd703ed8b0cefeb49a274a44f745bc4856a1c4 | |
parent | a0a74df826ac4a112ab0be4d6b9c6a069c690970 (diff) | |
download | turbine-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.java | 11 | ||||
-rw-r--r-- | javatests/com/google/turbine/lower/MissingJavaBaseModule.java | 105 |
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))); + } +} |