diff options
author | 2016-03-16 18:26:13 +0000 | |
---|---|---|
committer | 2016-03-17 10:07:36 +0000 | |
commit | c96ed864b13cf981a8be33e39fd6ed71decce3c0 (patch) | |
tree | ed9a6f65bc4fb31c6ae5464aa2e5f5075f2986ab | |
parent | de082b35aa61f57eaa2e2c856161136d38d1ebf5 (diff) |
Mask turbine classes from the processor classpath to avoid version skew
This prevents processors from seeing turbine's version of e.g. guava. javac is
still available becuase Blaze puts it on the bootstrap classpath.
--
MOS_MIGRATED_REVID=117363448
2 files changed, 83 insertions, 1 deletions
diff --git a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/ZipOutputFileManager.java b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/ZipOutputFileManager.java index f2410afdba..bda9dad10a 100644 --- a/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/ZipOutputFileManager.java +++ b/src/java_tools/buildjar/java/com/google/devtools/build/java/turbine/javac/ZipOutputFileManager.java @@ -24,6 +24,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URI; +import java.net.URL; +import java.net.URLClassLoader; import java.nio.ByteBuffer; import java.nio.charset.CharsetDecoder; import java.nio.charset.CodingErrorAction; @@ -158,4 +160,10 @@ public class ZipOutputFileManager extends JavacFileManager { } }); } + + @Override + protected ClassLoader getClassLoader(URL[] urls) { + // mask turbine classes from the processor classpath to avoid version skew + return new URLClassLoader(urls, null); + } } diff --git a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java index 69c92f1f91..e2e832c39f 100644 --- a/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java +++ b/src/java_tools/buildjar/javatests/com/google/devtools/build/java/turbine/javac/JavacTurbineTest.java @@ -47,6 +47,7 @@ import org.objectweb.asm.util.TraceClassVisitor; import java.io.BufferedInputStream; import java.io.IOError; import java.io.IOException; +import java.io.InputStream; import java.io.OutputStream; import java.io.PrintWriter; import java.io.StringWriter; @@ -829,7 +830,7 @@ public class JavacTurbineTest { assertThat(sw.toString()).contains("error reading"); } } - + @Test public void requiredConstructor() throws Exception { addSourceLines("Super.java", "class Super {", " public Super(int x) {}", "}"); @@ -898,4 +899,77 @@ public class JavacTurbineTest { }; assertThat(text).isEqualTo(Joiner.on('\n').join(expected)); } + + @SupportedAnnotationTypes("*") + public static class HostClasspathProcessor extends AbstractProcessor { + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + boolean first = true; + + @Override + public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) { + if (!first) { + return false; + } + first = false; + + String message; + try { + JavacTurbine.class.toString(); + message = "ok"; + } catch (Throwable e) { + StringWriter stringWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(stringWriter)); + message = stringWriter.toString(); + } + try { + FileObject fileObject = + processingEnv + .getFiler() + .createResource(StandardLocation.CLASS_OUTPUT, "", "result.txt"); + try (OutputStream os = fileObject.openOutputStream()) { + os.write(message.getBytes(StandardCharsets.UTF_8)); + } + } catch (IOException e) { + throw new IOError(e); + } + return false; + } + } + + @Test + public void maskProcessorClasspath() throws Exception { + addSourceLines("MyAnnotation.java", "public @interface MyAnnotation {}"); + addSourceLines("Hello.java", "@MyAnnotation class Hello {}"); + + // create a jar containing only HostClasspathProcessor + Path processorJar = temp.newFile("libprocessor.jar").toPath(); + try (OutputStream os = Files.newOutputStream(processorJar); + JarOutputStream jos = new JarOutputStream(os)) { + String classFileName = HostClasspathProcessor.class.getName().replace('.', '/') + ".class"; + jos.putNextEntry(new JarEntry(classFileName)); + try (InputStream is = getClass().getClassLoader().getResourceAsStream(classFileName)) { + ByteStreams.copy(is, jos); + } + } + + optionsBuilder.setProcessors(ImmutableList.of(HostClasspathProcessor.class.getName())); + optionsBuilder.addProcessorPathEntries(ImmutableList.of(processorJar.toString())); + optionsBuilder.addClassPathEntries(ImmutableList.<String>of()); + + compile(); + + Map<String, byte[]> outputs = collectOutputs(); + assertThat(outputs.keySet()).contains("result.txt"); + + String text = new String(outputs.get("result.txt"), StandardCharsets.UTF_8); + assertThat(text) + .contains( + "java.lang.NoClassDefFoundError:" + + " com/google/devtools/build/java/turbine/javac/JavacTurbine"); + } } |