Sub-folders in 'META-INF/services' should be ignored
Closed this issue ยท 3 comments
We are using the dependency org.apache.qpid:qpid-jms-client
in our project, and are generating a module-info for it with the help of your plugin, by defining:
extraJavaModuleInfo {
failOnMissingModuleInfo.set(false)
module("org.apache.qpid:qpid-jms-client", "qpid.jms.client")
[...]
}
We are running into some issues with the provides
sections in the module-info that are generated for the service providers in that library.
Expand for the generated module-info.class
open module qpid.jms.client@1.8.0 {
requires java.base;
provides org.;
provides org.apache.;
provides org.apache.qpid.;
provides org.apache.qpid.jms.;
provides org.apache.qpid.jms.provider.;
provides org.apache.qpid.jms.provider.redirects.;
provides org.apache.qpid.jms.sasl.;
provides org.apache.qpid.jms.tracing.;
provides org.apache.qpid.jms.transports.;
provides org.apache.qpid.jms.provider.amqp with
class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory,
transportScheme=tcp,
providerScheme=amqp;
provides org.apache.qpid.jms.provider.amqps with
class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory,
transportScheme=ssl,
providerScheme=amqps;
provides org.apache.qpid.jms.provider.amqpws with
class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory,
transportScheme=ws,
providerScheme=amqpws;
provides org.apache.qpid.jms.provider.amqpwss with
class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory,
transportScheme=wss,
providerScheme=amqpwss;
provides org.apache.qpid.jms.provider.failover with
class=org.apache.qpid.jms.provider.failover.FailoverProviderFactory;
provides org.apache.qpid.jms.provider.redirects.ws with
class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory,
transportScheme=ws,
providerScheme=amqpws;
provides org.apache.qpid.jms.provider.redirects.wss with
class=org.apache.qpid.jms.provider.amqp.AmqpProviderFactory,
transportScheme=wss,
providerScheme=amqpwss;
provides org.apache.qpid.jms.sasl.ANONYMOUS with
class=org.apache.qpid.jms.sasl.AnonymousMechanismFactory;
provides org.apache.qpid.jms.sasl.CRAM-MD5 with
class=org.apache.qpid.jms.sasl.CramMD5MechanismFactory;
provides org.apache.qpid.jms.sasl.EXTERNAL with
class=org.apache.qpid.jms.sasl.ExternalMechanismFactory;
provides org.apache.qpid.jms.sasl.GSSAPI with
class=org.apache.qpid.jms.sasl.GssapiMechanismFactory;
provides org.apache.qpid.jms.sasl.PLAIN with
class=org.apache.qpid.jms.sasl.PlainMechanismFactory;
provides org.apache.qpid.jms.sasl.SCRAM-SHA-1 with
class=org.apache.qpid.jms.sasl.ScramSHA1MechanismFactory;
provides org.apache.qpid.jms.sasl.SCRAM-SHA-256 with
class=org.apache.qpid.jms.sasl.ScramSHA256MechanismFactory;
provides org.apache.qpid.jms.sasl.SCRAM-SHA-512 with
class=org.apache.qpid.jms.sasl.ScramSHA512MechanismFactory;
provides org.apache.qpid.jms.sasl.XOAUTH2 with
class=org.apache.qpid.jms.sasl.XOauth2MechanismFactory;
provides org.apache.qpid.jms.tracing.noop with
class=org.apache.qpid.jms.tracing.JmsNoOpTracerFactory;
provides org.apache.qpid.jms.tracing.opentracing with
class=org.apache.qpid.jms.tracing.opentracing.OpenTracingTracerFactory;
provides org.apache.qpid.jms.transports.ssl with
class=org.apache.qpid.jms.transports.netty.NettySslTransportFactory;
provides org.apache.qpid.jms.transports.tcp with
class=org.apache.qpid.jms.transports.netty.NettyTcpTransportFactory;
provides org.apache.qpid.jms.transports.ws with
class=org.apache.qpid.jms.transports.netty.NettyWsTransportFactory;
provides org.apache.qpid.jms.transports.wss with
class=org.apache.qpid.jms.transports.netty.NettyWssTransportFactory;
}
There seem to be 2 kinds of issues:
Empty provides (e.g. provides org.apache.;
, provides org.apache.qpid.;
) which are generated for all directories inside the META-INF/services/
directory.
These produce the following error when running the application:
> Task :sources:application:run FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /Users/xxxxxx/.gradle/caches/transforms-3/c59ca46c3ed823128e0b390a8b01c364/transformed/qpid-jms-client-1.8.0-module.jar
Caused by: java.lang.module.InvalidModuleDescriptorException: Empty providers set
These can be ignored with ignoreServiceProvider statement, e.g.:
Expand for ignoreServiceProvider statements for empty providers
ignoreServiceProvider("org/")
ignoreServiceProvider("org/apache/")
ignoreServiceProvider("org/apache/qpid/")
ignoreServiceProvider("org/apache/qpid/jms/")
ignoreServiceProvider("org/apache/qpid/jms/provider/")
ignoreServiceProvider("org/apache/qpid/jms/provider/redirects/")
ignoreServiceProvider("org/apache/qpid/jms/sasl/")
ignoreServiceProvider("org/apache/qpid/jms/tracing/")
ignoreServiceProvider("org/apache/qpid/jms/transports/")
Then, the following error occurs with the remaining providers:
> Task :sources:application:run FAILED
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /Users/xxxxx/.gradle/caches/transforms-3/38a74fc7ce0078574e63820cb84f1f08/transformed/qpid-jms-client-1.8.0-module.jar
Caused by: java.lang.module.InvalidModuleDescriptorException: transportScheme=tcp: unnamed package
I'm no expert on service providers, so I'm not sure whether the library is not using them correctly, or whether the gradle plugin doesn't deal with them properly.
Any advice is appreciated ๐ Thanks in advance already!
Yes, it's a bug in this plugin. It shouldn't scan the subfolders located in the META-INF\services
folder.
According to the spec, only the files contained in the META-INF\services
folder should be treated as services.
A service provider is identified by placing a provider-configuration file in the resource directory META-INF/services. The file's name is the fully-qualified binary name of the service's type. The file contains a list of fully-qualified binary names of concrete provider classes, one per line. Space and tab characters surrounding each name, as well as blank lines, are ignored. The comment character is '#' ('\u0023', NUMBER SIGN); on each line all characters following the first comment character are ignored. The file must be encoded in UTF-8.
As a workaround, try specifying the following ignore list in the plugin configuration.
module("org.apache.qpid:qpid-jms-client", "qpid.jms.client") {
...
ignoreServiceProvider("org/")
ignoreServiceProvider("org/apache/")
ignoreServiceProvider("org/apache/qpid/")
ignoreServiceProvider("org/apache/qpid/jms/")
ignoreServiceProvider("org/apache/qpid/jms/provider/")
ignoreServiceProvider("org/apache/qpid/jms/provider/redirects/")
ignoreServiceProvider("org/apache/qpid/jms/sasl/")
ignoreServiceProvider("org/apache/qpid/jms/tracing/")
ignoreServiceProvider("org/apache/qpid/jms/transports/")
ignoreServiceProvider("org/apache/qpid/jms/provider/amqp")
ignoreServiceProvider("org/apache/qpid/jms/provider/amqps")
ignoreServiceProvider("org/apache/qpid/jms/provider/amqpws")
ignoreServiceProvider("org/apache/qpid/jms/provider/amqpwss")
ignoreServiceProvider("org/apache/qpid/jms/provider/failover")
ignoreServiceProvider("org/apache/qpid/jms/provider/redirects/ws")
ignoreServiceProvider("org/apache/qpid/jms/provider/redirects/wss")
ignoreServiceProvider("org/apache/qpid/jms/sasl/ANONYMOUS")
ignoreServiceProvider("org/apache/qpid/jms/sasl/CRAM-MD5")
ignoreServiceProvider("org/apache/qpid/jms/sasl/EXTERNAL")
ignoreServiceProvider("org/apache/qpid/jms/sasl/GSSAPI")
ignoreServiceProvider("org/apache/qpid/jms/sasl/PLAIN")
ignoreServiceProvider("org/apache/qpid/jms/sasl/SCRAM-SHA-1")
ignoreServiceProvider("org/apache/qpid/jms/sasl/SCRAM-SHA-256")
ignoreServiceProvider("org/apache/qpid/jms/sasl/SCRAM-SHA-512")
ignoreServiceProvider("org/apache/qpid/jms/sasl/XOAUTH2")
ignoreServiceProvider("org/apache/qpid/jms/tracing/noop")
ignoreServiceProvider("org/apache/qpid/jms/tracing/opentracing")
ignoreServiceProvider("org/apache/qpid/jms/transports/ssl")
ignoreServiceProvider("org/apache/qpid/jms/transports/tcp")
ignoreServiceProvider("org/apache/qpid/jms/transports/ws")
ignoreServiceProvider("org/apache/qpid/jms/transports/wss")
}
However, Apache Qpid must be doing some classpath scanning for its service discovery and chances are it will not work when the library is placed on the module path.
Thank you for reporting @j-beyer and thanks for analyzing @iherasymenko! Lets see that we get this fixed in the next release.
Thanks, that's great news! Also thanks for the details, will apply the workaround and experiment with it a bit :)