2222import com .android .build .api .variant .AndroidComponentsExtension ;
2323import com .android .build .api .variant .Variant ;
2424import com .android .build .gradle .BaseExtension ;
25+ import com .android .build .gradle .internal .component .ComponentCreationConfig ;
26+ import com .android .build .gradle .internal .publishing .AndroidArtifacts ;
2527import kotlin .Unit ;
2628import kotlin .jvm .functions .Function1 ;
27- import net .bytebuddy .build .gradle .android .classpath .DependenciesClasspathProvider ;
2829import org .gradle .api .Action ;
2930import org .gradle .api .GradleException ;
3031import org .gradle .api .Plugin ;
3132import org .gradle .api .Project ;
33+ import org .gradle .api .artifacts .ArtifactView ;
3234import org .gradle .api .artifacts .Configuration ;
33- import org .gradle .api .attributes .Attribute ;
34- import org .gradle .api .attributes .AttributeCompatibilityRule ;
35- import org .gradle .api .attributes .AttributeContainer ;
36- import org .gradle .api .attributes .AttributeMatchingStrategy ;
37- import org .gradle .api .attributes .Category ;
38- import org .gradle .api .attributes .CompatibilityCheckDetails ;
39- import org .gradle .api .attributes .Usage ;
35+ import org .gradle .api .attributes .*;
4036import org .gradle .api .file .FileCollection ;
4137import org .gradle .api .provider .Provider ;
4238import org .gradle .api .tasks .TaskProvider ;
4339
40+ import java .lang .reflect .InvocationTargetException ;
41+ import java .lang .reflect .Method ;
4442import java .util .concurrent .ConcurrentHashMap ;
4543import java .util .concurrent .ConcurrentMap ;
4644
@@ -52,7 +50,7 @@ public class ByteBuddyAndroidPlugin implements Plugin<Project> {
5250 /**
5351 * The name of the artifact type attribute.
5452 */
55- public static final Attribute <String > ARTIFACT_TYPE_ATTRIBUTE = Attribute .of ("artifactType" , String .class );
53+ protected static final Attribute <String > ARTIFACT_TYPE_ATTRIBUTE = Attribute .of ("artifactType" , String .class );
5654
5755 /**
5856 * The name of the Byte Buddy jar type.
@@ -71,8 +69,7 @@ public void apply(Project project) {
7169 }
7270 project .getDependencies ().registerTransform (AarGradleTransformAction .class , new AarGradleTransformAction .ConfigurationAction ());
7371 project .getDependencies ().getAttributesSchema ().attribute (ARTIFACT_TYPE_ATTRIBUTE , new AttributeMatchingStrategyConfigurationAction ());
74- extension .onVariants (extension .selector ().all (), new VariantAction (project , project .getConfigurations ().create ("byteBuddy" , new ConfigurationConfigurationAction ()),
75- DependenciesClasspathProvider .getInstance (currentAgpVersion )));
72+ extension .onVariants (extension .selector ().all (), new VariantAction (project , project .getConfigurations ().create ("byteBuddy" , new ConfigurationConfigurationAction ())));
7673 }
7774
7875 /**
@@ -90,11 +87,6 @@ protected static class VariantAction implements Action<Variant> {
9087 */
9188 private final Configuration configuration ;
9289
93- /**
94- * The runtime classpath provider.
95- */
96- private final DependenciesClasspathProvider classpathProvider ;
97-
9890 /**
9991 * A cache of configurations by built type name.
10092 */
@@ -103,14 +95,12 @@ protected static class VariantAction implements Action<Variant> {
10395 /**
10496 * Creates a new variant action.
10597 *
106- * @param project The current Gradle project.
107- * @param configuration The general Byte Buddy configuration.
108- * @param classpathProvider The runtime classpath provider.
98+ * @param project The current Gradle project.
99+ * @param configuration The general Byte Buddy configuration.
109100 */
110- protected VariantAction (Project project , Configuration configuration , DependenciesClasspathProvider classpathProvider ) {
101+ protected VariantAction (Project project , Configuration configuration ) {
111102 this .project = project ;
112103 this .configuration = configuration ;
113- this .classpathProvider = classpathProvider ;
114104 configurations = new ConcurrentHashMap <String , Configuration >();
115105 }
116106
@@ -134,22 +124,111 @@ public void execute(Variant variant) {
134124 configuration = previous ;
135125 }
136126 }
137- FileCollection classPath = classpathProvider . getRuntimeClasspath (variant );
127+ FileCollection classPath = RuntimeClassPathResolver . INSTANCE . apply (variant );
138128 variant .getInstrumentation ().transformClassesWith (ByteBuddyAsmClassVisitorFactory .class , InstrumentationScope .ALL , new ByteBuddyTransformationConfiguration (project ,
139129 configuration ,
140130 byteBuddyAndroidServiceProvider ,
141131 classPath ));
142- TaskProvider <ByteBuddyLocalClassesEnhancerTask > localClassesTransformation = project .getTasks ().register (variant .getName () + "BytebuddyLocalTransform" , ByteBuddyLocalClassesEnhancerTask .class ,
143- new ByteBuddyLocalClassesEnhancerTask .ConfigurationAction (
144- configuration ,
145- project .getExtensions ().getByType (BaseExtension .class ),
146- classPath ));
132+ TaskProvider <ByteBuddyLocalClassesEnhancerTask > localClassesTransformation = project .getTasks ().register (variant .getName () + "BytebuddyLocalTransform" ,
133+ ByteBuddyLocalClassesEnhancerTask .class ,
134+ new ByteBuddyLocalClassesEnhancerTask .ConfigurationAction (configuration , project .getExtensions ().getByType (BaseExtension .class ), classPath ));
147135 variant .getArtifacts ().use (localClassesTransformation )
148136 .wiredWith (ByteBuddyLocalClassesEnhancerTask ::getLocalClassesDirs , ByteBuddyLocalClassesEnhancerTask ::getOutputDir )
149137 .toTransform (MultipleArtifact .ALL_CLASSES_DIRS .INSTANCE );
150138 }
151139 }
152140
141+ /**
142+ * A dispatcher for resolving the runtime class path.
143+ */
144+ protected abstract static class RuntimeClassPathResolver {
145+
146+ /**
147+ * The runtime class path resolver to use.
148+ */
149+ protected static final RuntimeClassPathResolver INSTANCE ;
150+
151+ /*
152+ * Creates the runtime class path resolver to use.
153+ */
154+ static {
155+ RuntimeClassPathResolver instance ;
156+ try {
157+ instance = new OfModernAgp (Variant .class .getMethod ("getRuntimeConfiguration" ));
158+ } catch (Throwable ignored ) {
159+ instance = new OfLegacyAgp ();
160+ }
161+ INSTANCE = instance ;
162+ }
163+
164+ /**
165+ * Resolves the runtime class path.
166+ *
167+ * @param variant The variant for which to resolve the runtime class path.
168+ * @return The runtime class path.
169+ */
170+ protected abstract FileCollection apply (Variant variant );
171+
172+ /**
173+ * Before AGP 7.3, the {@code com.android.build.api.variant.Variant#getRuntimeConfiguration()} method is not available and an
174+ * internal cast must be used to resolve the runtime class path.
175+ */
176+ protected static class OfLegacyAgp extends RuntimeClassPathResolver {
177+
178+ @ Override
179+ protected FileCollection apply (Variant variant ) {
180+ if (!(variant instanceof ComponentCreationConfig )) {
181+ throw new GradleException ("Cannot resolve runtime class path for " + variant );
182+ }
183+ return ((ComponentCreationConfig ) variant ).getVariantDependencies ().getArtifactFileCollection (AndroidArtifacts .ConsumedConfigType .RUNTIME_CLASSPATH ,
184+ AndroidArtifacts .ArtifactScope .ALL ,
185+ AndroidArtifacts .ArtifactType .CLASSES_JAR );
186+ }
187+ }
188+
189+ /**
190+ * From AGP 7.3, the runtime configuration can be queried from the {@link Variant}.
191+ */
192+ protected static class OfModernAgp extends RuntimeClassPathResolver implements Action <ArtifactView .ViewConfiguration > {
193+
194+ /**
195+ * The {@code com.android.build.api.variant.Variant#getRuntimeConfiguration()} method.
196+ */
197+ private final Method getRuntimeConfiguration ;
198+
199+ /**
200+ * Creates a new resolver.
201+ *
202+ * @param getRuntimeConfiguration The {@code com.android.build.api.variant.Variant#getRuntimeConfiguration()} method.
203+ */
204+ protected OfModernAgp (Method getRuntimeConfiguration ) {
205+ this .getRuntimeConfiguration = getRuntimeConfiguration ;
206+ }
207+
208+ @ Override
209+ protected FileCollection apply (Variant variant ) {
210+ try {
211+ return ((Configuration ) getRuntimeConfiguration .invoke (variant )).getIncoming ()
212+ .artifactView (this )
213+ .getArtifacts ()
214+ .getArtifactFiles ();
215+ } catch (IllegalAccessException exception ) {
216+ throw new IllegalStateException ("Failed to access runtime configuration" , exception );
217+ } catch (InvocationTargetException exception ) {
218+ throw new IllegalStateException ("Failed to resolve runtime configuration" , exception .getCause ());
219+ }
220+ }
221+
222+ /**
223+ * {@inheritDoc}
224+ */
225+ public void execute (ArtifactView .ViewConfiguration configuration ) {
226+ configuration .setLenient (false );
227+ configuration .getAttributes ().attribute (ARTIFACT_TYPE_ATTRIBUTE , "android-classes-jar" );
228+ }
229+ }
230+ }
231+
153232 /**
154233 * A function to register Byte Buddy instrumentation parameters into the current execution.
155234 */
0 commit comments