I’m writing a plugin to execute some classes from my jar files.
My jar files have this structure:
├── META-INF/classes.properties
└── com
└──example
├── Class1.class
├── Class2.class
├── Class3.class
In classes.properties
, I specify which classes should be executed in my plugin.
For example, it looks like this:
com.example.Class1
com.example.Class2
And here is my build.gradle
file:
apply plugin: 'MyPlugin'
dependencies{
compile "com.example:example:xx"
}
So in my plugin, I need to read classes.properties
and then using reflection to instantiate Class1
and Class2
class MyPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.afterEvaluate {
project.configurations.compile.each {
File it -> // read from classes.properties then instantiate classes
}
}
}
But i don’t know how to instantiate classes or read .properties
file.
Thanks in advance.
Your properties file doesn’t seem to adhere to the usual name=value format for propery files. Ignoring that, you could do something like:
File jarFile = project.configurations.compile.singleFile
File propFile = project.zipTree(jarFile).matching {
include 'META-INF/classes.properties'
}.singleFile
propFile.withReader { Reader reader ->
Properties props = new Properties(reader)
URL[] urls = { jarFile.toURL() }
Classloader classloader = new URLClassloader(urls)
props.stringPropertyNames().each { String className ->
def instance = classloader.loadClass(className).newInstance()
doStuff(instance)
}
}
2 Likes
Thank you, But I got ClassNotFoundException, Is it possible to use project dependencies in gradle plugin?
Yes, you have some options. If you compiled your plugin with dependencies defined in compile
configuration, they will automatically be made available on the classpath.
Otherwise if those classes in your plugin requires other classes, not on the classpath, you will have to push them there via the appropriate classloader as referred to by @Lance_Java.
The Asciidoctor task in asciidoctor-gradle plugin has examples of adding to the classpath during task execution. (I have also written about this in the Idiomatic Gradle book).
1 Like
I changed jarFile.toURL()
to jarFile.toURI().toURL()
and now it works. Thank you both
1 Like