Skip to content

Commit

Permalink
Merge pull request #1389 from LikeTheSalad/master
Browse files Browse the repository at this point in the history
Providing Android runtimeClasspath using new tools from API 7.3
  • Loading branch information
raphw authored Jan 10, 2023
2 parents 493eb7d + 6fe8a5c commit 99e6861
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 17 deletions.
2 changes: 1 addition & 1 deletion byte-buddy-gradle-plugin/android-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ repositories {

dependencies {
api gradleApi()
compileOnly group: 'com.android.tools.build', name: 'gradle', version: '7.2.0'
compileOnly group: 'com.android.tools.build', name: 'gradle', version: '7.3.0'
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,25 @@
import com.android.build.api.AndroidPluginVersion;
import com.android.build.api.artifact.MultipleArtifact;
import com.android.build.api.attributes.BuildTypeAttr;
import com.android.build.api.component.impl.ComponentImpl;
import com.android.build.api.instrumentation.InstrumentationScope;
import com.android.build.api.variant.AndroidComponentsExtension;
import com.android.build.api.variant.Variant;
import com.android.build.gradle.BaseExtension;
import com.android.build.gradle.internal.publishing.AndroidArtifacts;
import kotlin.Unit;
import kotlin.jvm.functions.Function1;
import net.bytebuddy.build.gradle.android.classpath.DependenciesClasspathProvider;
import org.gradle.api.Action;
import org.gradle.api.GradleException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.attributes.*;
import org.gradle.api.attributes.Attribute;
import org.gradle.api.attributes.AttributeCompatibilityRule;
import org.gradle.api.attributes.AttributeContainer;
import org.gradle.api.attributes.AttributeMatchingStrategy;
import org.gradle.api.attributes.Category;
import org.gradle.api.attributes.CompatibilityCheckDetails;
import org.gradle.api.attributes.Usage;
import org.gradle.api.file.FileCollection;
import org.gradle.api.provider.Provider;
import org.gradle.api.tasks.TaskProvider;
Expand All @@ -47,7 +52,7 @@ public class ByteBuddyAndroidPlugin implements Plugin<Project> {
/**
* The name of the artifact type attribute.
*/
protected static final Attribute<String> ARTIFACT_TYPE_ATTRIBUTE = Attribute.of("artifactType", String.class);
public static final Attribute<String> ARTIFACT_TYPE_ATTRIBUTE = Attribute.of("artifactType", String.class);

/**
* The name of the Byte Buddy jar type.
Expand All @@ -60,12 +65,14 @@ public class ByteBuddyAndroidPlugin implements Plugin<Project> {
public void apply(Project project) {
@SuppressWarnings("unchecked")
AndroidComponentsExtension<?, ?, Variant> extension = project.getExtensions().getByType(AndroidComponentsExtension.class);
if (extension.getPluginVersion().compareTo(new AndroidPluginVersion(7, 2)) < 0) {
throw new IllegalStateException("Byte Buddy requires at least Gradle Plugin version 7.2+, but found " + extension.getPluginVersion());
AndroidPluginVersion currentAgpVersion = extension.getPluginVersion();
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())));
extension.onVariants(extension.selector().all(), new VariantAction(project, project.getConfigurations().create("byteBuddy", new ConfigurationConfigurationAction()),
DependenciesClasspathProvider.getInstance(currentAgpVersion)));
}

/**
Expand All @@ -83,6 +90,11 @@ protected static class VariantAction implements Action<Variant> {
*/
private final Configuration configuration;

/**
* The runtime classpath provider.
*/
private final DependenciesClasspathProvider classpathProvider;

/**
* A cache of configurations by built type name.
*/
Expand All @@ -91,12 +103,14 @@ protected static class VariantAction implements Action<Variant> {
/**
* Creates a new variant action.
*
* @param project The current Gradle project.
* @param configuration The general Byte Buddy configuration.
* @param project The current Gradle project.
* @param configuration The general Byte Buddy configuration.
* @param classpathProvider The runtime classpath provider.
*/
protected VariantAction(Project project, Configuration configuration) {
protected VariantAction(Project project, Configuration configuration, DependenciesClasspathProvider classpathProvider) {
this.project = project;
this.configuration = configuration;
this.classpathProvider = classpathProvider;
configurations = new ConcurrentHashMap<String, Configuration>();
}

Expand All @@ -120,12 +134,7 @@ public void execute(Variant variant) {
configuration = previous;
}
}
if (!(variant instanceof ComponentImpl)) {
throw new GradleException("Expected " + variant + " to be of type " + ComponentImpl.class.getName());
}
FileCollection classPath = ((ComponentImpl) variant).getVariantDependencies().getArtifactFileCollection(AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH,
AndroidArtifacts.ArtifactScope.ALL,
AndroidArtifacts.ArtifactType.CLASSES_JAR);
FileCollection classPath = classpathProvider.getRuntimeClasspath(variant);
variant.getInstrumentation().transformClassesWith(ByteBuddyAsmClassVisitorFactory.class, InstrumentationScope.ALL, new ByteBuddyTransformationConfiguration(project,
configuration,
byteBuddyAndroidServiceProvider,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* 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.classpath;

import com.android.build.api.AndroidPluginVersion;
import com.android.build.api.variant.Variant;
import org.gradle.api.file.FileCollection;
import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging;

import java.lang.reflect.InvocationTargetException;

/**
* Needed to query the runtime classpath for an Android project, which process has changed in recent versions of the
* AGP plugin, so each method gets its own implementation.
*/
public interface DependenciesClasspathProvider {

/**
* Returns the appropriate {@link DependenciesClasspathProvider} implementation based on the AGP version that the host
* project is running.
*
* @param currentVersion The current AGP version used in the host project.
*/
static DependenciesClasspathProvider getInstance(AndroidPluginVersion currentVersion) {
boolean isLowerThan73 = currentVersion.compareTo(new AndroidPluginVersion(7, 3)) < 0;
Logger logger = Logging.getLogger(DependenciesClasspathProvider.class);
try {
if (isLowerThan73) {
logger.debug("Using legacy classpath provider implementation");
return (DependenciesClasspathProvider) Class.forName("net.bytebuddy.build.gradle.android.classpath.impl.LegacyDependenciesClasspathProvider").getDeclaredConstructor().newInstance();
} else {
logger.debug("Using default classpath provider implementation");
return (DependenciesClasspathProvider) Class.forName("net.bytebuddy.build.gradle.android.classpath.impl.DefaultDependenciesClasspathProvider").getDeclaredConstructor().newInstance();
}
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
NoSuchMethodException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}

FileCollection getRuntimeClasspath(Variant variant);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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.classpath.impl;

import com.android.build.api.variant.Variant;
import net.bytebuddy.build.gradle.android.classpath.DependenciesClasspathProvider;
import org.gradle.api.Action;
import org.gradle.api.artifacts.ArtifactView;
import org.gradle.api.file.FileCollection;

import static net.bytebuddy.build.gradle.android.ByteBuddyAndroidPlugin.ARTIFACT_TYPE_ATTRIBUTE;

/**
* This implementation uses the method {@link Variant#getRuntimeConfiguration()} which was added in AGP version 7.3.0.
*/
public class DefaultDependenciesClasspathProvider implements DependenciesClasspathProvider {

@Override
public FileCollection getRuntimeClasspath(Variant variant) {
return variant.getRuntimeConfiguration().getIncoming()
.artifactView(new JarsViewAction())
.getArtifacts()
.getArtifactFiles();
}

/**
* Needed to query ".jar" files from both, plain Java libraries and Android libraries too. Android libraries
* are files of type ".aar" which contain a ".jar" file inside, without this filter, we'd get Android libraries
* as raw ".aar" files, which cannot be used for Java classpath purposes.
*/
protected static class JarsViewAction implements Action<ArtifactView.ViewConfiguration> {

@Override
public void execute(ArtifactView.ViewConfiguration configuration) {
configuration.setLenient(false);
configuration.getAttributes().attribute(ARTIFACT_TYPE_ATTRIBUTE, "android-classes-jar");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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.classpath.impl;

import com.android.build.api.component.impl.ComponentImpl;
import com.android.build.api.variant.Variant;
import com.android.build.gradle.internal.publishing.AndroidArtifacts;
import net.bytebuddy.build.gradle.android.classpath.DependenciesClasspathProvider;
import org.gradle.api.file.FileCollection;

/**
* This implementation is needed for projects running AGP version < 7.3, since the method {@link Variant#getRuntimeConfiguration()}
* was added in AGP 7.3.0. So this legacy implementation uses a workaround due to the missing "getRuntimeConfiguration" method.
*/
public class LegacyDependenciesClasspathProvider implements DependenciesClasspathProvider {

@Override
public FileCollection getRuntimeClasspath(Variant variant) {
return ((ComponentImpl) variant).getVariantDependencies().getArtifactFileCollection(AndroidArtifacts.ConsumedConfigType.RUNTIME_CLASSPATH,
AndroidArtifacts.ArtifactScope.ALL,
AndroidArtifacts.ArtifactType.CLASSES_JAR);
}
}
64 changes: 64 additions & 0 deletions byte-buddy-gradle-plugin/gradle/verification-metadata.xml
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,14 @@
<sha256 value="1dfac4e326232698bedd94d5fe7cd1fc1483a3741b696585cc528b743ccddd36" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android" name="zipflinger" version="7.3.0">
<artifact name="zipflinger-7.3.0.jar">
<sha256 value="accf407c70267cf7eb583ed5aaa1358c2d8fdbdf9c77675010118af6b55c0d5c" origin="Generated by Gradle"/>
</artifact>
<artifact name="zipflinger-7.3.0.pom">
<sha256 value="96db81d49e5728a8e589a2403144ebf3ffa9100a58bd4b87064fa6ba2c47444a" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.databinding" name="baseLibrary" version="4.2.0">
<artifact name="baseLibrary-4.2.0.jar">
<sha256 value="4f63076385e64eb85639e550ecbef3852180d7394638416e18d58f2895001531" origin="Generated by Gradle"/>
Expand Down Expand Up @@ -941,6 +949,14 @@
<sha256 value="c8e06ff71cbc80ebbcd0829ee5394d74c822b1725b46dbc7cd947ba5c1ea2e68" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="apksig" version="7.3.0">
<artifact name="apksig-7.3.0.jar">
<sha256 value="6d6a13a51ac3806c11af5f0967092055e35a67df6a74bff1544d9f5518c5ad55" origin="Generated by Gradle"/>
</artifact>
<artifact name="apksig-7.3.0.pom">
<sha256 value="7f5345c6de0cf29602e0397ea5262277d5e17dd1b66f9b860c02ad283af416ae" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="apkzlib" version="4.2.0">
<artifact name="apkzlib-4.2.0.jar">
<sha256 value="59c71d70754514cf951644797d463d75a6d264795b8c82d4fe0c903da25a57ca" origin="Generated by Gradle"/>
Expand All @@ -957,6 +973,14 @@
<sha256 value="77fa33cd204f17403f9f4c7ea853bfab541539eeae95fd932c09e66febfb2a1e" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="apkzlib" version="7.3.0">
<artifact name="apkzlib-7.3.0.jar">
<sha256 value="415c5d5adff68b0ebd700e27c04c150683e65d5731d47fdb018eae391f70768c" origin="Generated by Gradle"/>
</artifact>
<artifact name="apkzlib-7.3.0.pom">
<sha256 value="748ded253e7f10aeeba455bd40cbb076d593daa0bb70b15ba8d059cc4e66c001" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="builder" version="4.2.0">
<artifact name="builder-4.2.0.jar">
<sha256 value="e6d2cfd8cbaa0afd7f231d5912b642216c79a8d81f0eec147204b154431cadbc" origin="Generated by Gradle"/>
Expand All @@ -973,6 +997,14 @@
<sha256 value="e31e57b8fa883886b4aff7ba3f255906e48a72b501ffc92fb7ed17bfe1afca03" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="builder" version="7.3.0">
<artifact name="builder-7.3.0.jar">
<sha256 value="526e8913ef6bb14a2d6f8a6f5a0e925dc88924956a0b0f6ca1f30a98a2862909" origin="Generated by Gradle"/>
</artifact>
<artifact name="builder-7.3.0.module">
<sha256 value="d3d930446e4d3cce2bef180b771e6cb09460a428d7ac7aee346a8bf4277eb958" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="builder-model" version="4.2.0">
<artifact name="builder-model-4.2.0.jar">
<sha256 value="9190614addae2e8dd8e759a329a648527859f92f7f55037446f5ea6962f4d670" origin="Generated by Gradle"/>
Expand All @@ -989,6 +1021,14 @@
<sha256 value="8adc02ee1dd58045a9de464c9bd6145c63b3592516d6bc509683c1e9a6f6f315" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="builder-model" version="7.3.0">
<artifact name="builder-model-7.3.0.jar">
<sha256 value="9074ac62ec2e8d6b74d9192fc2f7bfb65b20556be3dd212d0924d31177fe06e0" origin="Generated by Gradle"/>
</artifact>
<artifact name="builder-model-7.3.0.module">
<sha256 value="7b915f9909ff1fe8b5469f617b69c2c4b478c74fe97cfe94e83b799b972b41df" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="builder-test-api" version="4.2.0">
<artifact name="builder-test-api-4.2.0.jar">
<sha256 value="6cf4b5e819cacc109ee0bcd8a149ba75d2ee7c48f4680decb360315e5bc421ae" origin="Generated by Gradle"/>
Expand Down Expand Up @@ -1037,6 +1077,14 @@
<sha256 value="246d3513dbcee07c5ce7d9b946243e3aa2472907d5ee23159c30400fb35fc2c9" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="gradle" version="7.3.0">
<artifact name="gradle-7.3.0.jar">
<sha256 value="5994adcffffa90419c85be42f848860cb95f4df6a1b8eadf7cfcfd9ffd7758de" origin="Generated by Gradle"/>
</artifact>
<artifact name="gradle-7.3.0.module">
<sha256 value="dd8fba0ef60344d5b8af43bbc9255e92cc634d3e5227835fb4c4e3bd3e274e3c" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="gradle-api" version="4.2.0">
<artifact name="gradle-api-4.2.0.jar">
<sha256 value="8f4bdb1713ea6d6ca1794cb3db98b5587eba5ff3be52d5f51892dc3356f8ae7f" origin="Generated by Gradle"/>
Expand All @@ -1053,6 +1101,14 @@
<sha256 value="26d975119aabd68aa206c98a8faf586816f701c7443f34ca6626a0c59afc2a66" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="gradle-api" version="7.3.0">
<artifact name="gradle-api-7.3.0.jar">
<sha256 value="5b6d06ff7aaab3149244418b5e2ea3a3325f54dfa42c981b18bdbb4fd5b49d84" origin="Generated by Gradle"/>
</artifact>
<artifact name="gradle-api-7.3.0.module">
<sha256 value="e5fe402312da263e01ffc41175bc629cb7d6c880696df2e36bf2db73b1200c07" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="manifest-merger" version="27.2.0">
<artifact name="manifest-merger-27.2.0.jar">
<sha256 value="b4c14da508e3bbc4809bb0d7b063cc389ad72a3835843cc89107a0cdb61c21fb" origin="Generated by Gradle"/>
Expand All @@ -1069,6 +1125,14 @@
<sha256 value="908d9f2d82d37018c4a9e1c303c265b889447adea2a2aa22064c7ecaa170ac7b" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="manifest-merger" version="30.3.0">
<artifact name="manifest-merger-30.3.0.jar">
<sha256 value="704ed10b9cbdf3e57acfd19a9de2548ef19d367bf8c26cac1307814d3572cd6f" origin="Generated by Gradle"/>
</artifact>
<artifact name="manifest-merger-30.3.0.module">
<sha256 value="8bdca275ecea4011d172da88b14c25c140445da130706e880d568a4fe4ae41e0" origin="Generated by Gradle"/>
</artifact>
</component>
<component group="com.android.tools.build" name="transform-api" version="2.0.0-deprecated-use-gradle-api">
<artifact name="transform-api-2.0.0-deprecated-use-gradle-api.jar">
<sha256 value="e8b4151ae1679f1abe7a14ee371ac9b3c651ae7b63290d1f586bdd0f78face9a" origin="Generated by Gradle"/>
Expand Down

0 comments on commit 99e6861

Please sign in to comment.