Open LarsBodewig opened 2 weeks ago
You mean this configuration? There are multiple ways to configure the Gradle plugin. You can specify a name and then the plugin will be resolved from within the plugin's class path, or you can configure the plugin and its dependencies directly. How did you approach this?
Judging from the name, I expected the classpath property to allow arbitrary classes to be supplied and accessed in the plugin.
buildscript {
dependencies {
classpath 'net.bytebuddy:byte-buddy-gradle-plugin:1.15.0'
classpath 'net.bytebuddy:byte-buddy:1.15.0'
}
}
configurations {
myCustomClasspath
}
dependencies {
myCustomClasspath 'my:special:jar' // containing my.special.jar.MySpecialClass
}
import net.bytebuddy.build.Plugin
import net.bytebuddy.build.gradle.ByteBuddyJarTask
import net.bytebuddy.description.type.TypeDescription
import net.bytebuddy.dynamic.ClassFileLocator
import net.bytebuddy.dynamic.DynamicType
class SimplePlugin implements Plugin {
@Override
void close() throws IOException {
}
@Override
DynamicType.Builder<?> apply(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassFileLocator classFileLocator) {
Class.forName("my.special.jar.MySpecialClass") // fails since the myCustomClasspath configuration is not resolved/available
return builder
}
@Override
boolean matches(TypeDescription typeDefinitions) {
return true
}
}
tasks.register("myByteBuddyTask", ByteBuddyJarsTask) {
source = files("libs")
target = file("transformedLibs")
classPath = project.getConfigurations().getByName("myCustomClasspath")
transformation {
plugin = SimplePlugin
}
}
The Class.forName()
is just a simple example. I actually want to detect classes from 'my:special:jar' that have a special annotation.
Right now I have to include 'my:special:jar' in the buildscript classpath to be available in the SimplePlugin.
buildscript {
dependencies {
classpath 'net.bytebuddy:byte-buddy-gradle-plugin:1.15.0'
classpath 'net.bytebuddy:byte-buddy:1.15.0'
classpath 'my:special:jar'
}
}
However I try to avoid that since those classes are not needed outside of the custom byte-buddy plugin.
As far as I understand, that is exactly the purpose of the classpath property in gradle tasks like JavaExec
- using classes during task runtime but not script compilation. Is there a better way to access arbitrary classes from my plugin?
I tried creating a custom classloader that reads the byte[] from the class file locator. But I always get java.lang.ClassFormatError: Truncated class file
.
Does the class file locator do anything special with the class files or are my classes the issue?
You can also configure dependencies in the transformation
block. I think this is where your additional dependencies need to go. The class path property is mostly used for reading.
Multiple byte-buddy gradle tasks annotate an input property as classpath but the input is not actually used as the classpath for execution.
I tried to load some classes in my custom plugin, expecting to find them on the classpath, however they are never available, unless they are also part of an origin or used for discovery.
I understand that byte-buddy does not actually need any other classpath elements that are not part of an origin, so I am not sure if it would be smart to load more, however the use of the annotation makes this a bit misleading.
Would it be possible to load all classes that are configured as classpath? Or idk run the plugins in a custom classloader that queries the ClassFileLocator?