[ 
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)

Reply via email to