java - while - which of the following is a quality plugin of gradle
META-INF/servicios en JAR con Gradle (5)
Quería construir un módulo de complemento que se pueda cargar con un ServiceLoader
. Esto requiere agregar un archivo al directorio META-INF/services
, que lleva el nombre de la interfaz del servicio y que contiene la ruta calificada a la clase que lo implementa. Luego puede cargar estos servicios llamando a ServiceLoader.load()
.
Aquí hay un ejemplo:
Digamos que queremos proporcionar una interfaz de plugin llamada org.example.plugins.PluginService
. Luego proporcionamos una implementación de este servicio en la clase org.example.plugins.impl.ExamplePlugin
.
Si queremos tener algún tipo de mecanismo de complemento, podríamos crear un archivo JAR, que contenga la implementación. Este archivo JAR también debe contener el archivo META-INF/services/org.example.plugins.PluginService
. Este archivo debe contener una línea.
org.example.plugins.impl.ExamplePlugin
para habilitar el ServiceLoader
para encontrar la implementación. Si ese archivo JAR está en la ruta de compilación, puede cargar el complemento llamando
Iterator<PluginService> it = ServiceLoader.load(PluginService.class).iterator();
Ese iterador le dará acceso también a todos los complementos encontrados por ServiceLoader
.
Por alguna razón, Gradle no incluye archivos en el directorio META-INF
de forma predeterminada. ¿Hay alguna manera de permitir que el JAR resultante contenga un archivo de este tipo?
Ya encontré el método metaInf
en la clase Jar
. Pero no sé lo suficientemente bueno como para encontrar la solución por mi cuenta.
Esperemos que implementen esto en la tarea jarra como lo hace la hormiga. Alguien ya trabajó en él: http://fgaliegue.blogspot.fr/2013/06/gradle-serviceloader-support.html
Hola, puedes intentar esto: https://plugins.gradle.org/plugin/com.github.harbby.gradle.serviceloader
Uso
serviceLoader {
serviceInterface ''org.example.plugins.PluginService''
serviceInterface ''org.example.plugins.PluginService2''
}
Mientras tanto, encontré una solución a mi problema en una pregunta (algo) similar .
Agregando lo siguiente al archivo gradle.build
, resuelve mi problema
jar {
from (''./src/main/java'') {
include ''META-INF/services/org.example.plugins.PluginService''
}
}
Ahora el archivo JAR se ve como se esperaba
.
|- org
| `- example
| `- plugins
| `- impl
| `- ExamplePlugin.class
`- META-INF
|- MANIFEST.MF
`- services
`- org.example.plugins.PluginService
Si le sucede que hereda un código heredado basado en hormigas que no sigue las convenciones de Maven, lo siguiente puede ayudar.
Defina sus conjuntos de fuentes para que coincidan con la estructura heredada e incluya una línea como esta:
include ''META-INF/services/**''
En sus conjuntos de fuentes. Este patrón es genérico y recogerá todos sus servicios de meta inf.
Ejemplo completo a continuación.
sourceSets {
main {
java {
srcDir ''src''
exclude ''**/Test*.java''
}
resources {
srcDir ''src''
include ''**/*.xml''
include ''META-INF/services/**''
}
}
test {
java {
srcDir ''src''
include ''**/Test*.java''
}
resources { srcDir ''resources'' }
}
}
META-INF/services/org.example.plugins.PluginService
en src/main/java
, pero no es una fuente, es un archivo de recursos, por lo tanto, debe colocarse en la carpeta de recursos según la convención de diseño de directorios de Maven, es decir
src/main/resources/META-INF/services/org.example.plugins.PluginService
En este caso todo debería funcionar fuera de la caja.