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 815804efdd..da9d9c4d4c 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 @@ -74,6 +74,10 @@ public class ByteBuddyAndroidPlugin implements Plugin { * The name of the Byte Buddy jar type. */ public static final String BYTE_BUDDY_CLASSES_TYPE = "bytebuddy-classes"; + + /** + * The name of the Byte Buddy resources type. + */ public static final String BYTE_BUDDY_RESOURCES_TYPE = "bytebuddy-resources"; /* @@ -152,40 +156,32 @@ 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"); } Configuration configuration = configurations.get(variant.getBuildType()); if (configuration == null) { configuration = project.getConfigurations().create(variant.getBuildType() + "ByteBuddy", new VariantConfigurationConfigurationAction(project, - this.configuration, - variant.getBuildType())); + this.configuration, + variant.getBuildType())); Configuration previous = configurations.putIfAbsent(variant.getBuildType(), configuration); if (previous != null) { configuration = previous; } } - return configuration; + if (TRANSFORMATION_DISPATCHER instanceof TransformationDispatcher.ForApk74CompatibleAndroid) { + TRANSFORMATION_DISPATCHER.accept(project, variant, configuration, null); + } else { + 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); + } } } 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 4d1e7b0783..0a5d16defe 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 @@ -105,8 +105,6 @@ 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. * @@ -175,24 +173,24 @@ public void execute() { } factories.add(new Plugin.Factory.UsingReflection(type) .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(Logger.class, getProject().getLogger())) + .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(org.slf4j.Logger.class, getProject().getLogger())) .with(Plugin.Factory.UsingReflection.ArgumentResolver.ForType.of(BuildLogger.class, buildLogger))); } catch (Throwable throwable) { throw new IllegalStateException("Cannot resolve plugin: " + name, throwable); } } Plugin.Engine.Summary summary = Plugin.Engine.Default.of(new EntryPoint.Unvalidated(EntryPoint.Default.DECORATE), - classFileVersion, + classFileVersion,Logger MethodNameTransformer.Suffixing.withRandomSuffix()) .with(classFileLocator) .apply(new Plugin.Engine.Source.Compound(sources), new TargetForAndroidAppJarFile(getOutputFile().get().getAsFile()), factories); if (!summary.getFailed().isEmpty()) { throw new IllegalStateException(summary.getFailed() + " type transformations have failed"); } else if (summary.getTransformed().isEmpty()) { - LOGGER.info("No types were transformed during plugin execution"); + getProject().getLogger().info("No types were transformed during plugin execution"); } else { - LOGGER.info("Transformed {} type(s)", summary.getTransformed().size()); + getProject().getLogger().info("Transformed {} type(s)", summary.getTransformed().size()); } } finally { if (classLoader instanceof Closeable) { @@ -301,4 +299,83 @@ public TypeScope getTypeScope(TypeDescription typeDescription) { : TypeScope.EXTERNAL; } } + + /** + * A Byte Buddy compilation target that merges an enhanced android app's runtime classpath into a jar file. + */ + protected static class TargetForAndroidAppJarFile extends Plugin.Engine.Target.ForJarFile { + + /** + * The targeted file. + */ + private final File file; + + /** + * Creates a new Byte Buddy compilation target for Android. + * + * @param file The targeted file. + */ + protected TargetForAndroidAppJarFile(File file) { + super(file); + this.file = file; + } + + /** + * {@inheritDoc} + */ + public Sink write(@MaybeNull Manifest manifest) throws IOException { + return manifest == null + ? new ForAndroidAppOutputStream(new JarOutputStream(new FileOutputStream(file))) + : new ForAndroidAppOutputStream(new JarOutputStream(new FileOutputStream(file), manifest)); + } + + /** + * A sink for an Android file. + */ + protected static class ForAndroidAppOutputStream extends Sink.ForJarOutputStream { + + /** + * The targeted output stream. + */ + private final JarOutputStream outputStream; + + /** + * Creates an output stream for an Android file. + * + * @param outputStream The targeted output stream. + */ + protected ForAndroidAppOutputStream(JarOutputStream outputStream) { + super(outputStream); + this.outputStream = outputStream; + } + + /** + * {@inheritDoc} + */ + public void retain(Plugin.Engine.Source.Element element) throws IOException { + JarEntry entry = element.resolveAs(JarEntry.class); + if (entry != null && entry.isDirectory()) { + return; + } + try { + outputStream.putNextEntry(new JarEntry(element.getName())); + InputStream inputStream = element.getInputStream(); + try { + byte[] buffer = new byte[1024]; + int length; + while ((length = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, length); + } + } finally { + inputStream.close(); + } + outputStream.closeEntry(); + } catch (ZipException exception) { + if (!element.getName().startsWith("META-INF")) { + throw exception; + } + } + } + } + } } diff --git a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/TargetForAndroidAppJarFile.java b/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/TargetForAndroidAppJarFile.java deleted file mode 100644 index ec0980032e..0000000000 --- a/byte-buddy-gradle-plugin/android-plugin/src/main/java/net/bytebuddy/build/gradle/android/TargetForAndroidAppJarFile.java +++ /dev/null @@ -1,85 +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 java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.jar.JarEntry; -import java.util.jar.JarOutputStream; -import java.util.jar.Manifest; -import java.util.zip.ZipException; -import net.bytebuddy.build.Plugin; -import net.bytebuddy.utility.nullability.MaybeNull; - -/** - * Byte Buddy compilation target that merges an enhanced android app's runtime classpath into a jar file. - */ -final class TargetForAndroidAppJarFile extends Plugin.Engine.Target.ForJarFile { - private final File file; - - public TargetForAndroidAppJarFile(File file) { - super(file); - this.file = file; - } - - @Override - public Sink write(@MaybeNull Manifest manifest) throws IOException { - return manifest == null - ? new ForAndroidAppOutputStream(new JarOutputStream(new FileOutputStream(file))) - : new ForAndroidAppOutputStream(new JarOutputStream(new FileOutputStream(file), manifest)); - } - - static final class ForAndroidAppOutputStream extends Sink.ForJarOutputStream { - private final JarOutputStream outputStream; - - public ForAndroidAppOutputStream(JarOutputStream outputStream) { - super(outputStream); - this.outputStream = outputStream; - } - - @Override - public void retain(Plugin.Engine.Source.Element element) throws IOException { - JarEntry entry = element.resolveAs(JarEntry.class); - if (entry != null && entry.isDirectory()) { - // Folders give a lot of "duplicated" errors. - return; - } - - try { - outputStream.putNextEntry(new JarEntry(element.getName())); - InputStream inputStream = element.getInputStream(); - try { - byte[] buffer = new byte[1024]; - int length; - while ((length = inputStream.read(buffer)) != -1) { - outputStream.write(buffer, 0, length); - } - } finally { - inputStream.close(); - } - outputStream.closeEntry(); - } catch (ZipException e) { - // Ignore duplicated files inside "META-INF" - - if (!element.getName().startsWith("META-INF")) { - throw e; - } - } - } - } -}