Skip to content

Commit

Permalink
Re-shade zinc to avoid classpath collisions with annotation processor…
Browse files Browse the repository at this point in the history
…s. (#5953)

### Problem

Zinc used to be shaded before the `1.x.y` upgrade (#4729), but shading was removed due to an overabundance of optimism. When testing the zinc upgrade internally, we experienced a classpath collision between an annotation processor and zinc (in guava, although zinc has many other dependencies that could cause issues).

### Solution

Shade zinc, and ensure that our annotation processor uses a very old guava in order to attempt to force collisions in future.
  • Loading branch information
Stu Hood committed Jun 12, 2018
1 parent b95299f commit aefc649
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 21 deletions.
8 changes: 6 additions & 2 deletions src/python/pants/backend/jvm/subsystems/zinc.py
Expand Up @@ -49,13 +49,17 @@ def register_options(cls, register):
Shader.exclude_package('scala', recursive=True),
Shader.exclude_package('xsbt', recursive=True),
Shader.exclude_package('xsbti', recursive=True),
# Unfortunately, is loaded reflectively by the compiler.
Shader.exclude_package('org.apache.logging.log4j', recursive=True),
]

cls.register_jvm_tool(register,
Zinc.ZINC_COMPILER_TOOL_NAME,
classpath=[
JarDependency('org.pantsbuild', 'zinc-compiler_2.11', '0.0.5'),
])
],
main=Zinc.ZINC_COMPILE_MAIN,
custom_rules=shader_rules)

cls.register_jvm_tool(register,
'compiler-bridge',
Expand Down Expand Up @@ -85,7 +89,7 @@ def register_options(cls, register):

@classmethod
def _zinc(cls, products):
return cls.tool_classpath_from_products(products, Zinc.ZINC_COMPILER_TOOL_NAME, cls.options_scope)
return cls.tool_jar_from_products(products, Zinc.ZINC_COMPILER_TOOL_NAME, cls.options_scope)

@classmethod
def _compiler_bridge(cls, products):
Expand Down
Expand Up @@ -268,7 +268,7 @@ def _zinc_cache_dir(self):
than compiling it.
"""
hasher = sha1()
for cp_entry in self._zinc.zinc + [self._zinc.compiler_interface, self._zinc.compiler_bridge]:
for cp_entry in [self._zinc.zinc, self._zinc.compiler_interface, self._zinc.compiler_bridge]:
hasher.update(os.path.relpath(cp_entry, self.get_options().pants_workdir))
key = hasher.hexdigest()[:12]
return os.path.join(self.get_options().pants_bootstrapdir, 'zinc', key)
Expand Down Expand Up @@ -353,7 +353,7 @@ def compile(self, ctx, args, classpath, upstream_analysis,
fp.write(arg)
fp.write(b'\n')

if self.runjava(classpath=self._zinc.zinc,
if self.runjava(classpath=[self._zinc.zinc],
main=Zinc.ZINC_COMPILE_MAIN,
jvm_options=jvm_options,
args=zinc_args,
Expand Down
7 changes: 7 additions & 0 deletions testprojects/3rdparty/com/google/guava/BUILD
@@ -0,0 +1,7 @@
# NB: This is an intentionally ancient guava to attempt to flush out classpath collisions
# with the compiler.
jar_library(name='ancient-guava',
jars=[
jar('com.google.guava', 'guava', '10.0')
])

Expand Up @@ -7,7 +7,9 @@ annotation_processor(
sources=globs('*.java'),
processors=['org.pantsbuild.testproject.annotation.processor.ResourceMappingProcessor'],
dependencies=[
'3rdparty:guava',
# NB: We use the oldest guava we can stomach here, in order to flush out classpath
# collisions between the compiler and annotation processors.
'testprojects/3rdparty/com/google/guava:ancient-guava',
],
)

Expand Up @@ -4,7 +4,6 @@
package org.pantsbuild.testproject.annotation.processor;

import com.google.common.collect.ImmutableSet;
import com.google.common.io.Closer;
import java.io.Closeable;
import java.io.IOException;
import java.io.PrintWriter;
Expand Down Expand Up @@ -120,24 +119,25 @@ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment
}

FileObject outputFile = createResourceOrDie("" /* no package */, REPORT_FILE_NAME);
Closer closer = Closer.create();
try {
Set<String> typeNames = new HashSet<String>();
PrintWriter writer = closer.register(new PrintWriter(outputFile.openWriter()));
for (TypeElement annotation : annotations) {
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
Set<TypeElement> typeElements = ElementFilter.typesIn(annotatedElements);
for (TypeElement typeElement : typeElements) {
String typeName = elementUtils.getBinaryName(typeElement).toString();
typeNames.add(typeName);
writer.println(typeName);
PrintWriter writer = new PrintWriter(outputFile.openWriter());
try {
Set<String> typeNames = new HashSet<String>();
for (TypeElement annotation : annotations) {
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(annotation);
Set<TypeElement> typeElements = ElementFilter.typesIn(annotatedElements);
for (TypeElement typeElement : typeElements) {
String typeName = elementUtils.getBinaryName(typeElement).toString();
typeNames.add(typeName);
writer.println(typeName);
}
}
}

closer.close();

writeResourceMapping(typeNames, outputFile);
log(Diagnostic.Kind.NOTE, "Generated resource '%s'", outputFile.toUri());
writeResourceMapping(typeNames, outputFile);
log(Diagnostic.Kind.NOTE, "Generated resource '%s'", outputFile.toUri());
} finally {
writer.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand Down

0 comments on commit aefc649

Please sign in to comment.