[
https://issues.apache.org/jira/browse/KAFKA-8340?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Chris Egerton reassigned KAFKA-8340:
------------------------------------
Assignee: Greg Harris
> ServiceLoader fails when used from isolated plugin path directory
> -----------------------------------------------------------------
>
> Key: KAFKA-8340
> URL: https://issues.apache.org/jira/browse/KAFKA-8340
> Project: Kafka
> Issue Type: Bug
> Components: KafkaConnect
> Reporter: Chris Egerton
> Assignee: Greg Harris
> Priority: Major
>
> Under some circumstances, the {{ServiceLoader.load}} mechanism will fail when
> used from an isolated plugin path directory and return an incomplete (often
> empty) {{ServiceLoader}} instance.
>
> To replicate:
> * Include a {{META-INF/services/...}} file in one of the JARS located in a
> plugin's directory with one or more implementations of that service listed
> inside. For the sake of example, let's say the name of this service is
> {{com.example.MyService}}
> * Program that plugin to invoke
> {{ServiceLoader.load(com.example.MyService.class)}}
> * Start the Connect framework, making sure this plugin is included on the
> plugin path and that it somehow invokes the {{ServiceLoader.load(...)}} method
> * Observe that the services loaded by that invocation do not include the
> ones described in the {{META-INF/services/...}} file contained in the JAR in
> the plugin's directory
>
> This is because the
> [ServiceLoader.load(Class)|https://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html#load(java.lang.Class)]
> method uses the current thread's context classloader to locate resources and
> load services. The current thread's context classloader is, in most cases, an
> instance of {{DelegatingClassLoader}}, which will (unless asked to locate
> resources corresponding to a provider-configuration file for a REST extension
> or config provider) simply delegate resource location to the parent and,
> unless asked to locate a class for a recognized plugin, also delegate class
> loading to the parent. Thus, none of the plugin's JARs are scanned for either
> provider-configuration files or for actual service classes.
> A viable workaround for some cases is to instead use the
> [ServiceLoader.load(Class,
> ClassLoader)|https://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.html#load(java.lang.Class,%20java.lang.ClassLoader)]
> method, specifying the current class's classloader as the second argument.
> This causes the plugin's {{PluginClassLoader}}, which will scan all JARs in
> the plugin's directory to be used to locate resources and classes.
> However, this may not be feasible in all cases, especially when working with
> external libraries that may be difficult or impossible to apply this
> workaround on.
--
This message was sent by Atlassian Jira
(v8.3.2#803003)