From f40317ae215863102cf87fe0679ad66f4b19454e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89amonn=20McManus?= Date: Wed, 28 Oct 2020 08:29:02 -0700 Subject: Update versions of auto-service and compile-testing, and fix a bug with SimpleServiceLoader. Updating the compile-testing version revealed a bug in AutoValue. If the same jar is present more than once in the class path (perhaps in different versions), then we get `META-INF/services` contributions from both. That could lead to us instantiating the same AutoValueExtension more than once. The bug has been fixed by uniquifying the list of classes before instantiating them. We specifically saw this bug because compile-testing now has a dependency on AutoValue, which meant that that AutoValue was in the classpath when compiling tests, in addition to the version of AutoValue being tested. RELNOTES=Fixed a bug which could lead to the same AutoValue extension being run more than once. PiperOrigin-RevId: 339463884 --- .../value/processor/SimpleServiceLoaderTest.java | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'value/src/test/java') diff --git a/value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java b/value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java index fab18056..5e2d230d 100644 --- a/value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java +++ b/value/src/test/java/com/google/auto/value/processor/SimpleServiceLoaderTest.java @@ -28,6 +28,8 @@ import java.io.PrintWriter; import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; import java.util.Enumeration; import java.util.List; import java.util.ServiceConfigurationError; @@ -54,6 +56,35 @@ public final class SimpleServiceLoaderTest { assertThat(classes).containsExactly(String.class, StringBuilder.class).inOrder(); } + // Sometimes you can have the same jar appear more than once in the classpath, perhaps in + // different versions. In that case we don't want to instantiate the same class more than once. + // This test checks that we don't. + @Test + public void loadWithDuplicates() throws Exception { + ClassLoader loader1 = + loaderForJarWithEntries( + CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName()); + ClassLoader loader2 = + loaderForJarWithEntries( + CharSequence.class.getName(), String.class.getName(), StringBuilder.class.getName()); + ClassLoader combinedLoader = + new ClassLoader() { + @Override + public Enumeration getResources(String name) throws IOException { + List urls = new ArrayList<>(Collections.list(loader1.getResources(name))); + urls.addAll(Collections.list(loader2.getResources(name))); + return Collections.enumeration(urls); + } + }; + + ImmutableList providers = + SimpleServiceLoader.load(CharSequence.class, combinedLoader); + + assertThat(providers).contains(""); + List> classes = providers.stream().map(Object::getClass).collect(toList()); + assertThat(classes).containsExactly(String.class, StringBuilder.class).inOrder(); + } + @Test public void blankLinesAndComments() throws Exception { ClassLoader loader = -- cgit v1.2.3