diff --git a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/AarGradleTransformAction.java b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/AarGradleTransformAction.java deleted file mode 100644 index 488a7dba9d9..00000000000 --- a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/AarGradleTransformAction.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright 2014 - Present Rafael Winterhalter - * - * 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 net.bytebuddy.build.gradle.android; - -import org.gradle.api.Action; -import org.gradle.api.artifacts.transform.*; -import org.gradle.api.file.FileSystemLocation; -import org.gradle.api.provider.Provider; - -import java.io.*; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -/** - * This {@link TransformAction} takes care of providing JARs embedded in AARs dependencies for Byte Buddy's configuration. - */ -public abstract class AarGradleTransformAction implements TransformAction { - - /** - * The AAR file format extension. - */ - private static final String AAR_FILE_EXTENSION = "aar"; - - /** - * Returns the input artifact. - * - * @return The input artifact. - */ - @InputArtifact - public abstract Provider getInputArtifact(); - - /** - * {@inheritDoc} - */ - public void transform(TransformOutputs transformOutputs) { - File input = getInputArtifact().get().getAsFile(); - String outputName = input.getName().replaceAll("\\." + AAR_FILE_EXTENSION + "$", ".jar"); - try { - ZipFile zipFile = new ZipFile(input); - try { - ZipEntry entry = zipFile.getEntry("classes.jar"); - InputStream inputStream = zipFile.getInputStream(entry); - try { - OutputStream outputStream = new FileOutputStream(transformOutputs.file(outputName)); - try { - byte[] buffer = new byte[1024 * 8]; - int length; - while ((length = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, length); - } - } finally { - outputStream.close(); - } - } finally { - inputStream.close(); - } - } finally { - zipFile.close(); - } - } catch (IOException exception) { - throw new IllegalStateException("Failed to transform " + getInputArtifact(), exception); - } - } - - /** - * A configuration action for transforming an AAR file. - */ - protected static class ConfigurationAction implements Action> { - - /** - * {@inheritDoc} - */ - public void execute(TransformSpec spec) { - spec.getFrom().attribute(ByteBuddyAndroidPlugin.ARTIFACT_TYPE_ATTRIBUTE, AAR_FILE_EXTENSION); - spec.getTo().attribute(ByteBuddyAndroidPlugin.ARTIFACT_TYPE_ATTRIBUTE, "bytebuddy-jar"); - } - } -} diff --git a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyAndroidPlugin.java b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyAndroidPlugin.java index 81a3a214692..815804efdd2 100644 --- a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyAndroidPlugin.java +++ b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyAndroidPlugin.java @@ -32,6 +32,7 @@ import java.util.concurrent.ConcurrentMap; import kotlin.Unit; import kotlin.jvm.functions.Function1; +import net.bytebuddy.utility.nullability.MaybeNull; import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.Plugin; @@ -72,7 +73,8 @@ public class ByteBuddyAndroidPlugin implements Plugin { /** * The name of the Byte Buddy jar type. */ - private static final String BYTE_BUDDY_JAR_TYPE = "bytebuddy-jar"; + public static final String BYTE_BUDDY_CLASSES_TYPE = "bytebuddy-classes"; + public static final String BYTE_BUDDY_RESOURCES_TYPE = "bytebuddy-resources"; /* * Resolves the dispatcher. @@ -84,7 +86,7 @@ public class ByteBuddyAndroidPlugin implements Plugin { Class scopedArtifacts = Class.forName("com.android.build.api.variant.ScopedArtifacts"); Class scopedArtifact = Class.forName("com.android.build.api.artifact.ScopedArtifact"); @SuppressWarnings("unchecked") - Object project = Enum.valueOf((Class) scope, "PROJECT"); + Object project = Enum.valueOf((Class) scope, "ALL"); dispatcher = new TransformationDispatcher.ForApk74CompatibleAndroid( Artifacts.class.getMethod("forScope", scope), scopedArtifacts.getMethod("use", TaskProvider.class), @@ -110,7 +112,6 @@ public void apply(Project project) { if (currentAgpVersion.compareTo(new AndroidPluginVersion(7, 2)) < 0) { throw new IllegalStateException("Byte Buddy requires at least Gradle Plugin version 7.2+, but found " + currentAgpVersion); } - project.getDependencies().registerTransform(AarGradleTransformAction.class, new AarGradleTransformAction.ConfigurationAction()); project.getDependencies().getAttributesSchema().attribute(ARTIFACT_TYPE_ATTRIBUTE, new AttributeMatchingStrategyConfigurationAction()); extension.onVariants(extension.selector().all(), new VariantAction(project, project.getConfigurations().create("byteBuddy", new ConfigurationConfigurationAction()))); } @@ -151,9 +152,26 @@ protected VariantAction(Project project, Configuration configuration) { * {@inheritDoc} */ public void execute(Variant variant) { + Configuration configuration = getByteBuddyConfiguration(variant); + + if (TRANSFORMATION_DISPATCHER instanceof TransformationDispatcher.ForApk74CompatibleAndroid) { + TRANSFORMATION_DISPATCHER.accept(project, variant, configuration, null); + return; + } + + // Legacy api usage. Provider byteBuddyAndroidServiceProvider = project.getGradle().getSharedServices().registerIfAbsent(variant.getName() + "ByteBuddyAndroidService", ByteBuddyAndroidService.class, new ByteBuddyAndroidService.ConfigurationAction(project.getExtensions().getByType(BaseExtension.class))); + FileCollection classPath = RuntimeClassPathResolver.INSTANCE.apply(variant); + variant.getInstrumentation().transformClassesWith(ByteBuddyAsmClassVisitorFactory.class, InstrumentationScope.ALL, new ByteBuddyTransformationConfiguration(project, + configuration, + byteBuddyAndroidServiceProvider, + classPath)); + TRANSFORMATION_DISPATCHER.accept(project, variant, configuration, classPath); + } + + private Configuration getByteBuddyConfiguration(Variant variant) { if (variant.getBuildType() == null) { throw new GradleException("Build type for " + variant + " was null"); } @@ -167,12 +185,7 @@ public void execute(Variant variant) { configuration = previous; } } - FileCollection classPath = RuntimeClassPathResolver.INSTANCE.apply(variant); - variant.getInstrumentation().transformClassesWith(ByteBuddyAsmClassVisitorFactory.class, InstrumentationScope.ALL, new ByteBuddyTransformationConfiguration(project, - configuration, - byteBuddyAndroidServiceProvider, - classPath)); - TRANSFORMATION_DISPATCHER.accept(project, variant, configuration, classPath); + return configuration; } } @@ -247,9 +260,9 @@ protected OfModernAgp(Method getRuntimeConfiguration) { protected FileCollection apply(Variant variant) { try { return ((Configuration) getRuntimeConfiguration.invoke(variant)).getIncoming() - .artifactView(this) - .getArtifacts() - .getArtifactFiles(); + .artifactView(this) + .getArtifacts() + .getArtifactFiles(); } catch (IllegalAccessException exception) { throw new IllegalStateException("Failed to access runtime configuration", exception); } catch (InvocationTargetException exception) { @@ -314,7 +327,7 @@ protected ByteBuddyTransformationConfiguration(Project project, * {@inheritDoc} */ public Unit invoke(ByteBuddyInstrumentationParameters parameters) { - parameters.getByteBuddyClasspath().from(configuration); + parameters.getByteBuddyClasspath().from(getByteBuddyClasspath(project, configuration)); parameters.getAndroidBootClasspath().from(project.getExtensions().getByType(BaseExtension.class).getBootClasspath()); parameters.getRuntimeClasspath().from(classPath); parameters.getByteBuddyService().set(byteBuddyAndroidServiceProvider); @@ -396,11 +409,9 @@ protected AttributeContainerConfigurationAction(Project project, String buildTyp * {@inheritDoc} */ public void execute(AttributeContainer attributes) { - attributes.attribute(ARTIFACT_TYPE_ATTRIBUTE, BYTE_BUDDY_JAR_TYPE); attributes.attribute(Category.CATEGORY_ATTRIBUTE, project.getObjects().named(Category.class, Category.LIBRARY)); attributes.attribute(BuildTypeAttr.ATTRIBUTE, project.getObjects().named(BuildTypeAttr.class, buildType)); attributes.attribute(Usage.USAGE_ATTRIBUTE, project.getObjects().named(Usage.class, Usage.JAVA_RUNTIME)); - } } @@ -413,7 +424,7 @@ protected static class AttributeMatchingStrategyConfigurationAction implements A * {@inheritDoc} */ public void execute(AttributeMatchingStrategy stringAttributeMatchingStrategy) { - stringAttributeMatchingStrategy.getCompatibilityRules().add(ByteBuddyJarRule.class); + stringAttributeMatchingStrategy.getCompatibilityRules().add(ByteBuddyDependencyRule.class); } } @@ -434,14 +445,22 @@ public void execute(Configuration configuration) { /** * A rule to check for jar compatibility. */ - public abstract static class ByteBuddyJarRule implements AttributeCompatibilityRule { + public abstract static class ByteBuddyDependencyRule implements AttributeCompatibilityRule { /** * {@inheritDoc} */ public void execute(CompatibilityCheckDetails details) { - if (BYTE_BUDDY_JAR_TYPE.equals(details.getConsumerValue()) && "jar".equals(details.getProducerValue())) { - details.compatible(); + if (BYTE_BUDDY_CLASSES_TYPE.equals(details.getConsumerValue())) { + String producerValue = details.getProducerValue(); + if ("java-classes-directory".equals(producerValue) || "android-classes-directory".equals(producerValue)) { + details.compatible(); + } + } else if (BYTE_BUDDY_RESOURCES_TYPE.equals(details.getConsumerValue())) { + String producerValue = details.getProducerValue(); + if ("java-resources-directory".equals(producerValue) || "android-java-res".equals(producerValue)) { + details.compatible(); + } } } } @@ -467,7 +486,7 @@ enum ForLegacyAndroid implements TransformationDispatcher { public void accept(Project project, Variant variant, Configuration configuration, FileCollection classPath) { TaskProvider provider = project.getTasks().register(variant.getName() + "BytebuddyLocalTransform", LegacyByteBuddyLocalClassesEnhancerTask.class, - new LegacyByteBuddyLocalClassesEnhancerTask.ConfigurationAction(configuration, project.getExtensions().getByType(BaseExtension.class), classPath)); + new LegacyByteBuddyLocalClassesEnhancerTask.ConfigurationAction(getByteBuddyClasspath(project, configuration), project.getExtensions().getByType(BaseExtension.class), classPath)); variant.getArtifacts() .use(provider) .wiredWith(GetLocalClassesFunction.INSTANCE, GetOutputDirFunction.INSTANCE) @@ -562,13 +581,13 @@ protected ForApk74CompatibleAndroid(Method forScope, Method use, Method toTransf * {@inheritDoc} */ public void accept(Project project, Variant variant, Configuration configuration, FileCollection classPath) { - TaskProvider provider = project.getTasks().register(variant.getName() + "BytebuddyLocalTransform", + TaskProvider provider = project.getTasks().register(variant.getName() + "BytebuddyTransform", ByteBuddyLocalClassesEnhancerTask.class, - new ByteBuddyLocalClassesEnhancerTask.ConfigurationAction(configuration, project.getExtensions().getByType(BaseExtension.class), classPath)); + new ByteBuddyLocalClassesEnhancerTask.ConfigurationAction(getByteBuddyClasspath(project, configuration), project.getExtensions().getByType(BaseExtension.class))); try { toTransform.invoke(use.invoke(forScope.invoke(variant.getArtifacts(), scope), provider), artifact, - GetLocalJarsFunction.INSTANCE, + GetProjectJarsFunction.INSTANCE, GetLocalClassesDirsFunction.INSTANCE, GetOutputFileFunction.INSTANCE); } catch (IllegalAccessException exception) { @@ -579,9 +598,9 @@ public void accept(Project project, Variant variant, Configuration configuration } /** - * A function representation of resolving local jars. + * A function representation of resolving local and dependencies jars. */ - protected enum GetLocalJarsFunction implements Function1> { + protected enum GetProjectJarsFunction implements Function1> { /** * The singleton instance. @@ -592,7 +611,7 @@ protected enum GetLocalJarsFunction implements Function1 invoke(ByteBuddyLocalClassesEnhancerTask task) { - return task.getLocalJars(); + return task.getInputJars(); } } @@ -641,6 +660,23 @@ public RegularFileProperty invoke(ByteBuddyLocalClassesEnhancerTask task) { * @param configuration The configuration to use. * @param classPath The class path to use. */ - void accept(Project project, Variant variant, Configuration configuration, FileCollection classPath); + void accept(Project project, Variant variant, Configuration configuration, @MaybeNull FileCollection classPath); + } + + /** + * For external dependencies, it provides their JAR files. For local project's dependencies, it provides their local + * build dirs for both classes and resources. The latter allows for faster and more reliable (up-to-date) compilation processes + * when using local plugins. + */ + private static FileCollection getByteBuddyClasspath(Project project, Configuration byteBuddyConfiguration) { + FileCollection resources = byteBuddyConfiguration.getIncoming().artifactView(viewConfiguration -> { + viewConfiguration.lenient(false); + viewConfiguration.getAttributes().attribute(ARTIFACT_TYPE_ATTRIBUTE, BYTE_BUDDY_RESOURCES_TYPE); + }).getFiles(); + FileCollection classes = byteBuddyConfiguration.getIncoming().artifactView(viewConfiguration -> { + viewConfiguration.lenient(false); + viewConfiguration.getAttributes().attribute(ARTIFACT_TYPE_ATTRIBUTE, BYTE_BUDDY_CLASSES_TYPE); + }).getFiles(); + return project.files(classes, resources); } } diff --git a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyLocalClassesEnhancerTask.java b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyLocalClassesEnhancerTask.java index 6ad20f616bd..4d1e7b07835 100644 --- a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyLocalClassesEnhancerTask.java +++ b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/ByteBuddyLocalClassesEnhancerTask.java @@ -22,19 +22,21 @@ import net.bytebuddy.build.BuildLogger; import net.bytebuddy.build.EntryPoint; import net.bytebuddy.build.Plugin; +import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.dynamic.scaffold.inline.MethodNameTransformer; +import net.bytebuddy.utility.QueueFactory; import org.gradle.api.Action; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; import org.gradle.api.JavaVersion; -import org.gradle.api.artifacts.Configuration; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.Directory; import org.gradle.api.file.FileCollection; import org.gradle.api.file.RegularFile; import org.gradle.api.file.RegularFileProperty; import org.gradle.api.logging.Logger; +import org.gradle.api.logging.Logging; import org.gradle.api.provider.ListProperty; import org.gradle.api.provider.Property; import org.gradle.api.tasks.Input; @@ -51,7 +53,7 @@ import java.util.*; /** - * Transformation task for instrumenting the project's local classes. + * Transformation task for instrumenting the project's local and dependencies' classes. */ public abstract class ByteBuddyLocalClassesEnhancerTask extends DefaultTask { @@ -71,14 +73,6 @@ public abstract class ByteBuddyLocalClassesEnhancerTask extends DefaultTask { @InputFiles public abstract ConfigurableFileCollection getByteBuddyClasspath(); - /** - * Returns the runtime class path. - * - * @return The runtime class path. - */ - @InputFiles - public abstract ConfigurableFileCollection getRuntimeClasspath(); - /** * Returns the Java target compatibility version. * @@ -88,12 +82,12 @@ public abstract class ByteBuddyLocalClassesEnhancerTask extends DefaultTask { public abstract Property getJavaTargetCompatibilityVersion(); /** - * Target project's local jars. + * Target project's local and dependencies jars. * - * @return The target project's local jars. + * @return The target project's local and dependencies jars. */ @InputFiles - public abstract ListProperty getLocalJars(); + public abstract ListProperty getInputJars(); /** * Target project's local classes dirs. @@ -111,6 +105,8 @@ public abstract class ByteBuddyLocalClassesEnhancerTask extends DefaultTask { @OutputFile public abstract RegularFileProperty getOutputFile(); + private static final Logger LOGGER = Logging.getLogger(ByteBuddyLocalClassesEnhancerTask.class); + /** * Translates a collection of files to {@link URL}s. * @@ -131,14 +127,14 @@ private static URL[] toUrls(Collection files) { } /** - * Executes the plugin for transforming local classes. + * Executes the plugin for transforming all project's classes. */ @TaskAction public void execute() { try { ClassFileVersion classFileVersion = ClassFileVersion.ofJavaVersionString(getJavaTargetCompatibilityVersion().get().toString()); List classFileLocators = new ArrayList(); - for (File file : getRuntimeClasspath().plus(getAndroidBootClasspath()).plus(getByteBuddyClasspath()).getFiles()) { + for (File file : getAndroidBootClasspath().plus(getByteBuddyClasspath()).getFiles()) { classFileLocators.add(file.isFile() ? ClassFileLocator.ForJarFile.of(file) : new ClassFileLocator.ForFolder(file)); @@ -147,10 +143,14 @@ public void execute() { ClassFileLocator classFileLocator = new ClassFileLocator.Compound(classFileLocators); try { Set sources = new LinkedHashSet(); + Set localClasspath = new HashSet<>(); for (Directory directory : getLocalClassesDirs().get()) { - sources.add(new Plugin.Engine.Source.ForFolder(directory.getAsFile())); + File file = directory.getAsFile(); + localClasspath.add(file); + sources.add(new Plugin.Engine.Source.ForFolder(file)); } - for (RegularFile jarFile : getLocalJars().get()) { + AndroidDescriptor androidDescriptor = DefaultAndroidDescriptor.ofClassPath(localClasspath); + for (RegularFile jarFile : getInputJars().get()) { sources.add(new Plugin.Engine.Source.ForJarFile(jarFile.getAsFile())); } ClassLoader classLoader = new URLClassLoader( @@ -162,7 +162,7 @@ public void execute() { try { buildLogger = (BuildLogger) Class.forName("net.bytebuddy.build.gradle.GradleBuildLogger") .getConstructor(Logger.class) - .newInstance(getProject().getLogger()); + .newInstance(LOGGER); } catch (Exception exception) { throw new GradleException("Failed to resolve Gradle build logger", exception); } @@ -174,9 +174,9 @@ public void execute() { throw new GradleException(type.getName() + " does not implement " + Plugin.class.getName()); } factories.add(new Plugin.Factory.UsingReflection(type) - .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(AndroidDescriptor.class, AndroidDescriptor.Trivial.LOCAL)) - .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(Logger.class, getProject().getLogger())) - .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(org.slf4j.Logger.class, getProject().getLogger())) + .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(AndroidDescriptor.class, androidDescriptor)) + .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(Logger.class, LOGGER)) + .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(org.slf4j.Logger.class, LOGGER)) .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(BuildLogger.class, buildLogger))); } catch (Throwable throwable) { throw new IllegalStateException("Cannot resolve plugin: " + name, throwable); @@ -186,13 +186,13 @@ public void execute() { classFileVersion, MethodNameTransformer.Suffixing.withRandomSuffix()) .with(classFileLocator) - .apply(new Plugin.Engine.Source.Compound(sources), new Plugin.Engine.Target.ForJarFile(getOutputFile().get().getAsFile()), factories); + .apply(new Plugin.Engine.Source.Compound(sources), new TargetForAndroidAppJarFile(getOutputFile().get().getAsFile()), factories); if (!summary.getFailed().isEmpty()) { - throw new IllegalStateException(summary.getFailed() + " local type transformations have failed"); + throw new IllegalStateException(summary.getFailed() + " type transformations have failed"); } else if (summary.getTransformed().isEmpty()) { - getLogger().info("No local types were transformed during plugin execution"); + LOGGER.info("No types were transformed during plugin execution"); } else { - getLogger().info("Transformed {} local type(s)", summary.getTransformed().size()); + LOGGER.info("Transformed {} type(s)", summary.getTransformed().size()); } } finally { if (classLoader instanceof Closeable) { @@ -206,7 +206,7 @@ public void execute() { classFileLocator.close(); } } catch (IOException exception) { - throw new GradleException("Failed to transform local classes", exception); + throw new GradleException("Failed to transform classes", exception); } } @@ -218,35 +218,87 @@ public static class ConfigurationAction implements Action names; + + /** + * Creates a default Android descriptor. + * + * @param names The names of all classes on the class path. + */ + protected DefaultAndroidDescriptor(Set names) { + this.names = names; + } + + /** + * Resolves class names of a set of class files from the class path. + * + * @param roots The class path roots to resolve. + * @return A suitable Android descriptor. + */ + protected static AndroidDescriptor ofClassPath(Set roots) { + Set names = new HashSet(); + for (File root : roots) { + Queue queue = QueueFactory.make(Collections.singleton(root)); + while (!queue.isEmpty()) { + File file = queue.remove(); + if (file.isDirectory()) { + File[] value = file.listFiles(); + if (value != null) { + queue.addAll(Arrays.asList(value)); + } + } else if (file.getName().endsWith(CLASS_FILE_EXTENSION)) { + String path = root.getAbsoluteFile().toURI().relativize(file.getAbsoluteFile().toURI()).getPath(); + names.add(path.substring(0, path.length() - CLASS_FILE_EXTENSION.length()).replace('/', '.')); + } + } + } + return new DefaultAndroidDescriptor(names); + } + + /** + * {@inheritDoc} + */ + public TypeScope getTypeScope(TypeDescription typeDescription) { + return names.contains(typeDescription.getName()) + ? TypeScope.LOCAL + : TypeScope.EXTERNAL; + } + } } diff --git a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/LegacyByteBuddyLocalClassesEnhancerTask.java b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/LegacyByteBuddyLocalClassesEnhancerTask.java index f9aff5c21d3..f29db09ef11 100644 --- a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/LegacyByteBuddyLocalClassesEnhancerTask.java +++ b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/LegacyByteBuddyLocalClassesEnhancerTask.java @@ -28,7 +28,6 @@ import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; import org.gradle.api.JavaVersion; -import org.gradle.api.artifacts.Configuration; import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.Directory; import org.gradle.api.file.DirectoryProperty; @@ -206,7 +205,7 @@ public static class ConfigurationAction implements Action