From 628b6a90c503192f9987fc488421a19d7d331bd5 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Wed, 9 Nov 2022 22:44:37 +0100 Subject: [PATCH] Close class loader in Gradle plugin, if possible. --- .../java/net/bytebuddy/pool/TypePool.java | 2 +- .../build/gradle/AbstractByteBuddyTask.java | 167 +++++++++--------- 2 files changed, 88 insertions(+), 81 deletions(-) diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/pool/TypePool.java b/byte-buddy-dep/src/main/java/net/bytebuddy/pool/TypePool.java index 5fee4785b40..38ae268ca11 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/pool/TypePool.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/pool/TypePool.java @@ -219,7 +219,7 @@ interface CacheProvider { * Attempts to find a resolution in this cache. * * @param name The name of the type to describe. - * @return A resolution of the type or {@code null} if no such resolution can be found in the cache.. + * @return A resolution of the type or {@code null} if no such resolution can be found in the cache. */ @MaybeNull Resolution find(String name); diff --git a/byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/AbstractByteBuddyTask.java b/byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/AbstractByteBuddyTask.java index d3ee6e9e392..5839086e129 100644 --- a/byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/AbstractByteBuddyTask.java +++ b/byte-buddy-gradle-plugin/src/main/java/net/bytebuddy/build/gradle/AbstractByteBuddyTask.java @@ -33,6 +33,7 @@ import org.gradle.api.tasks.Nested; import org.gradle.api.tasks.Optional; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.net.MalformedURLException; @@ -371,96 +372,102 @@ protected void doApply(Plugin.Engine.Source source, Plugin.Engine.Target target) } List transformations = new ArrayList(getTransformations()); ClassLoader classLoader = ByteBuddySkippingUrlClassLoader.of(getClass().getClassLoader(), discoverySet(), classPath()); - if (discovery.isDiscover(transformations)) { - Set undiscoverable = new HashSet(); - if (discovery.isRecordConfiguration()) { - for (Transformation transformation : transformations) { - undiscoverable.add(transformation.toPluginName()); + try { + if (discovery.isDiscover(transformations)) { + Set undiscoverable = new HashSet(); + if (discovery.isRecordConfiguration()) { + for (Transformation transformation : transformations) { + undiscoverable.add(transformation.toPluginName()); + } } - } - for (String name : Plugin.Engine.Default.scan(classLoader)) { - if (undiscoverable.add(name)) { - try { - @SuppressWarnings("unchecked") - Class plugin = (Class) Class.forName(name); - Transformation transformation = new Transformation(); - transformation.setPlugin(plugin); - transformations.add(transformation); - } catch (ClassNotFoundException exception) { - throw new IllegalStateException("Discovered plugin is not available: " + name, exception); + for (String name : Plugin.Engine.Default.scan(classLoader)) { + if (undiscoverable.add(name)) { + try { + @SuppressWarnings("unchecked") + Class plugin = (Class) Class.forName(name); + Transformation transformation = new Transformation(); + transformation.setPlugin(plugin); + transformations.add(transformation); + } catch (ClassNotFoundException exception) { + throw new IllegalStateException("Discovered plugin is not available: " + name, exception); + } + getLogger().debug("Registered discovered plugin: {}", name); + } else { + getLogger().info("Skipping discovered plugin {} which was previously discovered or registered", name); } - getLogger().debug("Registered discovered plugin: {}", name); - } else { - getLogger().info("Skipping discovered plugin {} which was previously discovered or registered", name); } } - } - if (transformations.isEmpty()) { - getLogger().warn("No transformations are specified or discovered. Skipping plugin application."); - } else { - getLogger().debug("{} plugins are being applied via configuration and discovery", transformations.size()); - } - List factories = new ArrayList(transformations.size()); - for (Transformation transformation : transformations) { - try { - factories.add(new Plugin.Factory.UsingReflection(transformation.toPlugin(classLoader)) - .with(transformation.makeArgumentResolvers()) - .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(File.class, source()), - Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(Logger.class, getLogger()), - Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(org.slf4j.Logger.class, getLogger()), - Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(BuildLogger.class, new GradleBuildLogger(getLogger())))); - getLogger().info("Resolved plugin: {}", transformation.toPluginName()); - } catch (Throwable throwable) { - throw new IllegalStateException("Cannot resolve plugin: " + transformation.toPluginName(), throwable); + if (transformations.isEmpty()) { + getLogger().warn("No transformations are specified or discovered. Skipping plugin application."); + } else { + getLogger().debug("{} plugins are being applied via configuration and discovery", transformations.size()); } - } - List classFileLocators = new ArrayList(); - for (File artifact : classPath()) { - classFileLocators.add(artifact.isFile() - ? ClassFileLocator.ForJarFile.of(artifact) - : new ClassFileLocator.ForFolder(artifact)); - } - ClassFileLocator classFileLocator = new ClassFileLocator.Compound(classFileLocators); - Plugin.Engine.Summary summary; - try { - getLogger().info("Processing class files located in in: {}", source()); - Plugin.Engine pluginEngine; - try { - ClassFileVersion classFileVersion; - if (this.classFileVersion == null) { - classFileVersion = ClassFileVersion.ofThisVm(); - getLogger().warn("Could not locate Java target version, build is JDK dependant: {}", classFileVersion.getJavaVersion()); - } else { - classFileVersion = this.classFileVersion; - getLogger().debug("Java version was configured: {}", classFileVersion.getJavaVersion()); + List factories = new ArrayList(transformations.size()); + for (Transformation transformation : transformations) { + try { + factories.add(new Plugin.Factory.UsingReflection(transformation.toPlugin(classLoader)) + .with(transformation.makeArgumentResolvers()) + .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(File.class, source()), + Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(Logger.class, getLogger()), + Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(org.slf4j.Logger.class, getLogger()), + Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(BuildLogger.class, new GradleBuildLogger(getLogger())))); + getLogger().info("Resolved plugin: {}", transformation.toPluginName()); + } catch (Throwable throwable) { + throw new IllegalStateException("Cannot resolve plugin: " + transformation.toPluginName(), throwable); } - pluginEngine = Plugin.Engine.Default.of(getEntryPoint(), classFileVersion, getSuffix().length() == 0 - ? MethodNameTransformer.Suffixing.withRandomSuffix() - : new MethodNameTransformer.Suffixing(getSuffix())); - } catch (Throwable throwable) { - throw new IllegalStateException("Cannot create plugin engine", throwable); } + List classFileLocators = new ArrayList(); + for (File artifact : classPath()) { + classFileLocators.add(artifact.isFile() + ? ClassFileLocator.ForJarFile.of(artifact) + : new ClassFileLocator.ForFolder(artifact)); + } + ClassFileLocator classFileLocator = new ClassFileLocator.Compound(classFileLocators); + Plugin.Engine.Summary summary; try { - summary = pluginEngine - .with(isExtendedParsing() - ? Plugin.Engine.PoolStrategy.Default.EXTENDED - : Plugin.Engine.PoolStrategy.Default.FAST) - .with(classFileLocator) - .with(new TransformationLogger(getLogger())) - .withErrorHandlers(Plugin.Engine.ErrorHandler.Enforcing.ALL_TYPES_RESOLVED, isFailOnLiveInitializer() - ? Plugin.Engine.ErrorHandler.Enforcing.NO_LIVE_INITIALIZERS - : Plugin.Engine.Listener.NoOp.INSTANCE, isFailFast() - ? Plugin.Engine.ErrorHandler.Failing.FAIL_FAST - : Plugin.Engine.ErrorHandler.Failing.FAIL_LAST) - .with(getThreads() == 0 - ? Plugin.Engine.Dispatcher.ForSerialTransformation.Factory.INSTANCE - : new Plugin.Engine.Dispatcher.ForParallelTransformation.WithThrowawayExecutorService.Factory(getThreads())) - .apply(source, target, factories); - } catch (Throwable throwable) { - throw new IllegalStateException("Failed to transform class files in " + source(), throwable); + getLogger().info("Processing class files located in in: {}", source()); + Plugin.Engine pluginEngine; + try { + ClassFileVersion classFileVersion; + if (this.classFileVersion == null) { + classFileVersion = ClassFileVersion.ofThisVm(); + getLogger().warn("Could not locate Java target version, build is JDK dependant: {}", classFileVersion.getJavaVersion()); + } else { + classFileVersion = this.classFileVersion; + getLogger().debug("Java version was configured: {}", classFileVersion.getJavaVersion()); + } + pluginEngine = Plugin.Engine.Default.of(getEntryPoint(), classFileVersion, getSuffix().length() == 0 + ? MethodNameTransformer.Suffixing.withRandomSuffix() + : new MethodNameTransformer.Suffixing(getSuffix())); + } catch (Throwable throwable) { + throw new IllegalStateException("Cannot create plugin engine", throwable); + } + try { + summary = pluginEngine + .with(isExtendedParsing() + ? Plugin.Engine.PoolStrategy.Default.EXTENDED + : Plugin.Engine.PoolStrategy.Default.FAST) + .with(classFileLocator) + .with(new TransformationLogger(getLogger())) + .withErrorHandlers(Plugin.Engine.ErrorHandler.Enforcing.ALL_TYPES_RESOLVED, isFailOnLiveInitializer() + ? Plugin.Engine.ErrorHandler.Enforcing.NO_LIVE_INITIALIZERS + : Plugin.Engine.Listener.NoOp.INSTANCE, isFailFast() + ? Plugin.Engine.ErrorHandler.Failing.FAIL_FAST + : Plugin.Engine.ErrorHandler.Failing.FAIL_LAST) + .with(getThreads() == 0 + ? Plugin.Engine.Dispatcher.ForSerialTransformation.Factory.INSTANCE + : new Plugin.Engine.Dispatcher.ForParallelTransformation.WithThrowawayExecutorService.Factory(getThreads())) + .apply(source, target, factories); + } catch (Throwable throwable) { + throw new IllegalStateException("Failed to transform class files in " + source(), throwable); + } + } finally { + classFileLocator.close(); } } finally { - classFileLocator.close(); + if (classLoader instanceof Closeable) { + ((Closeable) classLoader).close(); + } } if (!summary.getFailed().isEmpty()) { throw new IllegalStateException(summary.getFailed() + " type transformations have failed");