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