[
https://issues.apache.org/jira/browse/RANGER-4201?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
caijialiang updated RANGER-4201:
--------------------------------
Summary: Hbase master can't start due to ranger-hbase-plugin jersey jar
class loading order (was: Hbase master can't start due to ranger-hbase-plugin
jersey jar conflict)
> Hbase master can't start due to ranger-hbase-plugin jersey jar class loading
> order
> -----------------------------------------------------------------------------------
>
> Key: RANGER-4201
> URL: https://issues.apache.org/jira/browse/RANGER-4201
> Project: Ranger
> Issue Type: Bug
> Components: Ranger
> Affects Versions: 2.3.0, 2.4.0
> Reporter: caijialiang
> Assignee: caijialiang
> Priority: Major
> Attachments: image-2023-04-27-16-11-05-561.png,
> image-2023-04-27-16-13-44-504.png, image-2023-04-27-16-14-10-803.png,
> image-2023-04-27-16-14-37-202.png, image-2023-04-27-16-15-44-539.png
>
>
>
> Issue description: HBase fails to start after enabling Ranger 2.4 plugin.
> Problem analysis is required.
> environment:
> linux centos7.4
> hbase 2.4.13
> ranger 2.4
> jdk1.8
> hadoop 3.3.4
> zookeeper 3.5.9
> Symptom: After integrating Ranger with HBase, HBase Master cannot start, and
> Region Server also crashes after running for a period of time. The same error
> message occurs during both processes.
>
> {code:java}
> [master/gs-server-13481:16000:becomeActiveMaster]
> coprocessor.CoprocessorHost: The coprocessor
> org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor threw
> java.lang.ExceptionInInitializerError
> java.lang.ExceptionInInitializerError
> at
> com.sun.jersey.core.spi.factory.MessageBodyFactory.initReaders(MessageBodyFactory.java:182)
> at
> com.sun.jersey.core.spi.factory.MessageBodyFactory.initReaders(MessageBodyFactory.java:175)
> at
> com.sun.jersey.core.spi.factory.MessageBodyFactory.init(MessageBodyFactory.java:162)
> at com.sun.jersey.api.client.Client.init(Client.java:343)
> at com.sun.jersey.api.client.Client.access$000(Client.java:119)
> at com.sun.jersey.api.client.Client$1.f(Client.java:192)
> at com.sun.jersey.api.client.Client$1.f(Client.java:188)
> at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:193)
> at com.sun.jersey.api.client.Client.<init>(Client.java:188)
> at com.sun.jersey.api.client.Client.<init>(Client.java:171)
> at com.sun.jersey.api.client.Client.create(Client.java:683)
> at
> org.apache.ranger.plugin.util.RangerRESTClient.buildClient(RangerRESTClient.java:228)
> at
> org.apache.ranger.plugin.util.RangerRESTClient.getClient(RangerRESTClient.java:193)
> at
> org.apache.ranger.plugin.util.RangerRESTClient.get(RangerRESTClient.java:473)
> at
> org.apache.ranger.admin.client.RangerAdminRESTClient.getRangerRolesDownloadResponse(RangerAdminRESTClient.java:1340)
> at
> org.apache.ranger.admin.client.RangerAdminRESTClient.getRolesIfUpdatedWithCred(RangerAdminRESTClient.java:1202)
> at
> org.apache.ranger.admin.client.RangerAdminRESTClient.getRolesIfUpdated(RangerAdminRESTClient.java:167)
> at
> org.apache.ranger.plugin.util.RangerRolesProvider.loadUserGroupRolesFromAdmin(RangerRolesProvider.java:183)
> at
> org.apache.ranger.plugin.util.RangerRolesProvider.loadUserGroupRoles(RangerRolesProvider.java:123)
> at
> org.apache.ranger.plugin.util.PolicyRefresher.loadRoles(PolicyRefresher.java:495)
> at
> org.apache.ranger.plugin.util.PolicyRefresher.startRefresher(PolicyRefresher.java:144)
> at
> org.apache.ranger.plugin.service.RangerBasePlugin.init(RangerBasePlugin.java:245)
> at
> org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor.start(RangerAuthorizationCoprocessor.java:1120)
> at
> org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor.start(RangerAuthorizationCoprocessor.java:160)
> at
> org.apache.hadoop.hbase.coprocessor.BaseEnvironment.startup(BaseEnvironment.java:69)
> at
> org.apache.hadoop.hbase.coprocessor.CoprocessorHost.checkAndLoadInstance(CoprocessorHost.java:285)
> at
> org.apache.hadoop.hbase.coprocessor.CoprocessorHost.loadSystemCoprocessors(CoprocessorHost.java:171)
> at
> org.apache.hadoop.hbase.master.MasterCoprocessorHost.<init>(MasterCoprocessorHost.java:155)
> at
> org.apache.hadoop.hbase.master.HMaster.initializeCoprocessorHost(HMaster.java:3870)
> at
> org.apache.hadoop.hbase.master.HMaster.finishActiveMasterInitialization(HMaster.java:902)
> at
> org.apache.hadoop.hbase.master.HMaster.startActiveMasterManager(HMaster.java:2175)
> at
> org.apache.hadoop.hbase.master.HMaster.lambda$run$0(HMaster.java:520)
> at java.lang.Thread.run(Thread.java:748)
> Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException:
> org.glassfish.jersey.internal.RuntimeDelegateImpl
> at
> javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:130)
> at
> javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:97)
> at javax.ws.rs.core.MediaType.valueOf(MediaType.java:172)
> at com.sun.jersey.core.header.MediaTypes.<clinit>(MediaTypes.java:65)
> ... 33 more
> Caused by: java.lang.ClassNotFoundException:
> org.glassfish.jersey.internal.RuntimeDelegateImpl
> at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
> at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
> at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
> at java.lang.Class.forName0(Native Method)
> at java.lang.Class.forName(Class.java:264)
> at javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:87)
> at javax.ws.rs.ext.FactoryFinder.find(FactoryFinder.java:185)
> at
> javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:112)
> ... 36 more {code}
> Steps to reproduce:
>
> * 1.After installing HBase 2.x and Ranger 2.4, configure HBase by modifying
> the hbase-site.xml file:
> * Set hbase.coprocessor.master.classes to
> org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor
> * Set hbase.coprocessor.region.classes to
> org.apache.hadoop.hbase.security.access.SecureBulkLoadEndpoint,org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor
> * Set hbase.coprocessor.regionserver.classes to
> org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor
> * Restart HBase and check the HBase Master logs to observe the exception and
> see the Master crash soon after
> solution:delete
> /usr/bigtop/3.2.0/usr/lib/hbase/lib/ranger-hbase-plugin-impl/jersey-core-1.19.3.jar
>
>
> related issues
> https://issues.apache.org/jira/browse/HBASE-22029
> https://issues.apache.org/jira/browse/HBASE-22052
> !image-2023-04-27-16-11-05-561.png!
> Problem Analysis:
> Conclusion: Exception caused by class loading order
>
> Analysis process: The call chain is roughly as follows: master start ->
> org.apache.ranger.authorization.hbase.RangerAuthorizationCoprocessor.start
> ... ->com.sun.jersey.api.client.Client.create
> ...->com.sun.jersey.core.spi.factory.MessageBodyFactory.init
> ->com.sun.jersey.core.header.MediaTypes ->javax.ws.rs.core.MediaType.valueOf
> -> javax.ws.rs.ext.RuntimeDelegate.getInstance ->
> javax.ws.rs.ext.RuntimeDelegate.findDelegate
> I have fully investigated this call chain and found that the root cause of
> the problem is that javax.ws.rs.ext.RuntimeDelegate in the
> javax.ws.rs-api-2.1.1.jar package in HBase did not find
> org.glassfish.jersey.internal.RuntimeDelegateImpl when calling findDelegate,
> which caused the error. Specifically, javax.ws.rs.ext.RuntimeDelegate first
> looks for the default JAXRS_RUNTIME_DELEGATE, which is
> "javax.ws.rs.ext.RuntimeDelegate". If it cannot be found, it will fallback
> and load JAXRS_DEFAULT_RUNTIME_DELEGATE, which is
> org.glassfish.jersey.internal.RuntimeDelegateImpl.
> The method "findDelegate" in "javax.ws.rs.ext.RuntimeDelegate" is as follows:
> {code:java}
> public abstract class RuntimeDelegate {
> public static final String JAXRS_RUNTIME_DELEGATE_PROPERTY =
> "javax.ws.rs.ext.RuntimeDelegate";
> private static final String JAXRS_DEFAULT_RUNTIME_DELEGATE =
> "org.glassfish.jersey.internal.RuntimeDelegateImpl";
> private static final Object RD_LOCK = new Object();
> private static ReflectPermission suppressAccessChecksPermission = new
> ReflectPermission("suppressAccessChecks");
> private static volatile RuntimeDelegate cachedDelegate; protected
> RuntimeDelegate() {
> }
> public static RuntimeDelegate getInstance() {
> // Double-check idiom for lazy initialization of fields.
> // Local variable is used to limit the number of more expensive
> accesses to a volatile field.
> RuntimeDelegate result = cachedDelegate;
> if (result == null) { // First check (no locking)
> synchronized (RD_LOCK) {
> result = cachedDelegate;
> if (result == null) { // Second check (with locking)
> cachedDelegate = result = findDelegate();
> }
> }
> }
> return result;
> } private static RuntimeDelegate findDelegate() {
> try {
> Object delegate = FactoryFinder.find(
> JAXRS_RUNTIME_DELEGATE_PROPERTY,
> JAXRS_DEFAULT_RUNTIME_DELEGATE,
> RuntimeDelegate.class);
> if (!(delegate instanceof RuntimeDelegate)) {
> Class pClass = RuntimeDelegate.class;
> String classnameAsResource = pClass.getName().replace('.',
> '/') + ".class";
> ClassLoader loader = pClass.getClassLoader();
> if (loader == null) {
> loader = ClassLoader.getSystemClassLoader();
> }
> URL targetTypeURL = loader.getResource(classnameAsResource);
> throw new LinkageError("ClassCastException: attempting to
> cast"
> +
> delegate.getClass().getClassLoader().getResource(classnameAsResource)
> + " to " + targetTypeURL);
> }
> return (RuntimeDelegate) delegate;
> } catch (Exception ex) {
> throw new RuntimeException(ex);
> }
> }
> {code}
> When the "jersey-core-1.19.3.jar" file is removed from
> "/usr/bigtop/3.2.0/usr/lib/hbase/lib/ranger-hbase-plugin-impl/", HBase can
> start normally.
>
> It is not clear which class, either "javax.ws.rs.ext.RuntimeDelegate" or
> "org.glassfish.jersey.internal.RuntimeDelegateImpl", is loaded by HBase at
> this point.
>
> To determine which class is loaded and from which JAR file it is loaded, we
> can first remove "/usr/lib/hbase/lib/javax.ws.rs-api-2.1.1.jar" and start
> HBase normally. Then, we can use the Arthas tool
> (https://github.com/alibaba/arthas) to sniff and determine which class is
> loaded and from which JAR file it is loaded by the HBase JVM.
> After starting HBase normally, run the Arthas startup script "sudo -u hbase
> -EH ./as.sh " attach to the HBase process. Then, execute "sc -d
> javax.ws.rs.ext.RuntimeDelegat" to check whether
> "javax.ws.rs.ext.RuntimeDelegate" is loaded.
>
> result:
> {code:java}
> [arthas@1719]$ sc -d javax.ws.rs.ext.RuntimeDelegate
> class-info com.sun.jersey.core.spi.factory.AbstractRuntimeDelegate
> code-source
> /usr/bigtop/3.2.0/usr/lib/hadoop-hdfs/lib/jersey-core-1.19.jar
> name com.sun.jersey.core.spi.factory.AbstractRuntimeDelegate
> isInterface false
> isAnnotation false
> isEnum false
> isAnonymousClass false
> isArray false
> isLocalClass false
> isMemberClass false
> isPrimitive false
> isSynthetic false
> simple-name AbstractRuntimeDelegate
> modifier abstract,public
> annotation
> interfaces
> super-class +-javax.ws.rs.ext.RuntimeDelegate
> +-java.lang.Object
> class-loader +-sun.misc.Launcher$AppClassLoader@4fca772d
> +-sun.misc.Launcher$ExtClassLoader@436a4e4b
> classLoaderHash 4fca772d class-info
> com.sun.jersey.server.impl.provider.RuntimeDelegateImpl
> code-source /usr/bigtop/3.2.0/usr/lib/hadoop/lib/jersey-server-1.19.jar
> name com.sun.jersey.server.impl.provider.RuntimeDelegateImpl
> isInterface false
> isAnnotation false
> isEnum false
> isAnonymousClass false
> isArray false
> isLocalClass false
> isMemberClass false
> isPrimitive false
> isSynthetic false
> simple-name RuntimeDelegateImpl
> modifier public
> annotation
> interfaces
> super-class +-com.sun.jersey.core.spi.factory.AbstractRuntimeDelegate
> +-javax.ws.rs.ext.RuntimeDelegate
> +-java.lang.Object
> class-loader +-sun.misc.Launcher$AppClassLoader@4fca772d
> +-sun.misc.Launcher$ExtClassLoader@436a4e4b
> classLoaderHash 4fca772d class-info javax.ws.rs.ext.RuntimeDelegate
> code-source
> /usr/bigtop/3.2.0/usr/lib/hbase/lib/javax.ws.rs-api-2.1.1.jar
> name javax.ws.rs.ext.RuntimeDelegate
> isInterface false
> isAnnotation false
> isEnum false
> isAnonymousClass false
> isArray false
> isLocalClass false
> isMemberClass false
> isPrimitive false
> isSynthetic false
> simple-name RuntimeDelegate
> modifier abstract,public
> annotation
> interfaces
> super-class +-java.lang.Object
> class-loader +-sun.misc.Launcher$AppClassLoader@4fca772d
> +-sun.misc.Launcher$ExtClassLoader@436a4e4b
> classLoaderHash 4fca772dAffect(row-cnt:3) cost in 112 ms. {code}
> By removing the jersey-core-1.19.3.jar file from
> /usr/bigtop/3.2.0/usr/lib/hbase/lib/ranger-hbase-plugin-impl/, we can see
> that the abstract class javax.ws.rs.ext.RuntimeDelegate is loaded by the
> AppClassLoader from the javax.ws.rs-api-2.1.1.jar file located in
> /usr/bigtop/3.2.0/usr/lib/hbase/lib/.
> At the same time, the implementation of javax.ws.rs.ext.RuntimeDelegate,
> which is com.sun.jersey.server.impl.provider.RuntimeDelegateImpl, is loaded
> from the jersey-server-1.19.jar file located in
> /usr/bigtop/3.2.0/usr/lib/hadoop/lib/. Note that the hadoop lib directory is
> appended to HBase's classpath when HBase is started, which is why it can be
> loaded.
> Additionally, the abstract class
> com.sun.jersey.core.spi.factory.AbstractRuntimeDelegate, which inherits from
> RuntimeDelegate, is loaded from the jersey-core-1.19.jar file located in
> /usr/bigtop/3.2.0/usr/lib/hadoop-hdfs/lib/.
> However, even after removing the jersey-core-1.19.3.jar file, we can still
> see that HBase loads the same version of jersey-core-1.19.jar from the hadoop
> lib directory. Therefore, the root cause of the error is not a class not
> found due to a version conflict, but rather due to the order in which the
> class loader loads the classes.
>
> To verify this conclusion, the simplest way is to:
> # Before deleting the jersey-core-1.19.3.jar file from
> /ranger-hbase-plugin-impl/, print out the loading information of all the
> classes involved in the stack trace of the heap dump exception in the log.
> # After deleting the jersey-core-1.19.3.jar file, print out the loading
> information of all the classes involved in the stack trace of the heap dump
> exception in the log.
> # Use regular expressions to batch delete the timestamps from the log, and
> then compare the two log files to see any differences in the class loading
> information.
> In the Ranger 2.4 source code, Ranger implements its own class loader,
> RangerPluginClassLoader, which inherits from URLClassLoader. During
> initialization, it is passed the path to the
> ranger-\{componentname}-plugin-impl directory, and all the classes in this
> directory will be loaded by RangerPluginClassLoader. The parent is set to
> null, which in my understanding, is to block delegation loading. This is
> because all the classes in the ranger-\{componentname}-plugin-impl directory
> are dependencies of the Ranger plugin. For example, if the version of a jar
> that it depends on is lower, if the delegation loading mechanism is used, it
> is easy to load the higher version of the class under the component/lib
> directory, leading to class conflict issues. Therefore, parent is set to null.
> Internally, RangerPluginClassLoader first tries to load the jar files under
> the ranger-\{componentname}-plugin-impl directory using the parent
> URLClassLoader. If it can't be loaded, it uses the componentClassLoader,
> which is the current thread context's class loader, to load it.
> !image-2023-04-27-16-13-44-504.png!
> Next, you can take a look at the source code of the
> "RangerAuthorizationCoprocessor" class in Ranger. This class initializes an
> instance of "rangerPluginClassLoader" and activates it. Within this class,
> there are pre and post hooks for various HBase operations, primarily for
> performing range permission-related operations. This triggers the loading of
> Ranger-related classes by the rangerPluginClassLoader.
> !image-2023-04-27-16-14-10-803.png!
> Why does the hook activate the Ranger class loader at the beginning and
> de-activate it after the hook method ends? Doesn't this approach impact
> performance?
> !image-2023-04-27-16-14-37-202.png!
> The reason for de-activating the Ranger class loader after the hook method
> ends is because the rangerPluginClassLoader code sets itself as the current
> thread's context class loader. If it's not deactivated, it can cause
> conflicts with the lower version packages loaded in the
> .../ranger-hbase-plugin-impl/ directory, which can cause issues during
> subsequent operations. Therefore, the conclusion is that this involves the
> rangerPluginClassLoader and the AppClassLoader of the thread's context class
> loader.
> We also need to understand how to load an instance of "RuntimeDelegate" and
> how it searches for the implementation of "javax.ws.rs.ext.RuntimeDelegate".
> We should also investigate why it cannot find the implementation class and
> instead looks for "org.glassfish.jersey.internal.RuntimeDelegateImpl",
> causing an error.
> First, the "RuntimeDelegate" class is loaded via the
> "javax.ws.rs.ext.RuntimeDelegate.findDelegate" method, which calls
> "FactoryFinder.find" to load the class. Once loaded, the instance must be of
> type "RuntimeDelegate".
> {code:java}
> private static RuntimeDelegate findDelegate() {
> try {
> Object delegate = FactoryFinder.find("javax.ws.rs.ext.RuntimeDelegate",
> "org.glassfish.jersey.internal.RuntimeDelegateImpl", RuntimeDelegate.class);
> if (!(delegate instanceof RuntimeDelegate)) {
> Class<RuntimeDelegate> pClass = RuntimeDelegate.class;
> String classnameAsResource = pClass.getName().replace('.', '/') +
> ".class";
> ClassLoader loader = pClass.getClassLoader();
> if (loader == null)
> loader = ClassLoader.getSystemClassLoader();
> URL targetTypeURL = loader.getResource(classnameAsResource);
> throw new LinkageError("ClassCastException: attempting to cast" +
> delegate
> .getClass().getClassLoader().getResource(classnameAsResource) + "
> to " + targetTypeURL);
> }
> return (RuntimeDelegate)delegate;
> } catch (Exception ex) {
> throw new RuntimeException(ex);
> }
> } {code}
> The process of loading the class via "FactoryFinder.find" is contained in the
> "javax.ws.rs.ext.FactoryFinder.find" method, as shown in the following code:
> {code:java}
> /**
> * Finds the implementation {@code Class} for the given factory name,
> * or if that fails, finds the {@code Class} for the given fallback
> * class name and create its instance. The arguments supplied MUST be
> * used in order. If using the first argument is successful, the second
> * one will not be used.
> * <p>
> * This method is package private so that this code can be shared.
> *
> * @param factoryId the name of the factory to find, which is
> * a system property.
> * @param fallbackClassName the implementation class name, which is
> * to be used only if nothing else.
> * is found; {@code null} to indicate that
> * there is no fallback class name.
> * @param service service to be found.
> * @param <T> type of the service to be found.
> * @return the instance of the specified service; may not be {@code null}.
> * @throws ClassNotFoundException if the given class could not be found
> * or could not be instantiated.
> */
> static <T> Object find(final String factoryId, final String
> fallbackClassName, Class<T> service) throws ClassNotFoundException {
> ClassLoader classLoader = getContextClassLoader(); try {
> Iterator<T> iterator = ServiceLoader.load(service,
> FactoryFinder.getContextClassLoader()).iterator();
> if(iterator.hasNext()) {
> return iterator.next();
> }
> } catch (Exception | ServiceConfigurationError ex) {
> LOGGER.log(Level.FINER, "Failed to load service " + factoryId +
> ".", ex);
> } try {
> Iterator<T> iterator = ServiceLoader.load(service,
> FactoryFinder.class.getClassLoader()).iterator();
> if(iterator.hasNext()) {
> return iterator.next();
> }
> } catch (Exception | ServiceConfigurationError ex) {
> LOGGER.log(Level.FINER, "Failed to load service " + factoryId +
> ".", ex);
> } // try to read from $java.home/lib/jaxrs.properties
> FileInputStream inputStream = null;
> String configFile = null;
> try {
> String javah = System.getProperty("java.home");
> configFile = javah + File.separator + "lib" + File.separator +
> "jaxrs.properties";
> File f = new File(configFile);
> if (f.exists()) {
> Properties props = new Properties();
> inputStream = new FileInputStream(f);
> props.load(inputStream);
> String factoryClassName = props.getProperty(factoryId);
> return newInstance(factoryClassName, classLoader);
> }
> } catch (Exception ex) {
> LOGGER.log(Level.FINER, "Failed to load service " + factoryId
> + " from $java.home/lib/jaxrs.properties", ex);
> } finally {
> if (inputStream != null) {
> try {
> inputStream.close();
> } catch (IOException ex) {
> LOGGER.log(Level.FINER, String.format("Error closing %s
> file.", configFile), ex);
> }
> }
> } // Use the system property
> try {
> String systemProp = System.getProperty(factoryId);
> if (systemProp != null) {
> return newInstance(systemProp, classLoader);
> }
> } catch (SecurityException se) {
> LOGGER.log(Level.FINER, "Failed to load service " + factoryId
> + " from a system property", se);
> } if (fallbackClassName == null) {
> throw new ClassNotFoundException(
> "Provider for " + factoryId + " cannot be found", null);
> } return newInstance(fallbackClassName, classLoader);
> }
> } {code}
> To summarize the "FactoryFinder.find" method, it uses the thread context
> class loader to load "javax.ws.rs.ext.RuntimeDelegate". If that fails, it
> attempts to load it from system properties or alternative class names. If it
> still cannot be found, it tries to load
> "org.glassfish.jersey.internal.RuntimeDelegateImpl". If it cannot be loaded,
> it throws an exception.
> When the
> /usr/bigtop/3.2.0/usr/lib/hbase/lib/ranger-hbase-plugin-impl/jersey-core-1.19.3.jar
> file was not deleted, the class loading order was as follows:
> javax.ws.rs.ext.RuntimeDelegate(appClassLoader) ->
> javax.ws.rs.ext.RuntimeDelegate.HeaderDelegate(RangerPluginClassLoader) ->
> javax.ws.rs.ext.RuntimeDelegate.HeaderDelegateProvider(RangerPluginClassLoader
> jersey-core-1.19.3.jar ranger-hbase-plugin-impl/jersey-core-1.19.3.jar).
> The RangerPluginClassLoader searched for the
> com.sun.jersey.spi.HeaderDelegateProvider implementation class in the
> META-INF/services/com.sun.jersey.spi.HeaderDelegateProvider file of the
> jersey-core-1.19.3.jar file, found the
> com.sun.jersey.core.impl.provider.header.LocaleProvider class in
> ranger-hbase-plugin-impl/jersey-core-1.19.3.jar, and returned it.
> However, javax.ws.rs.ext.RuntimeDelegate.findDelegate would fail because
> delegate instanceof RuntimeDelegate returned false.
> As a fallback, it searched for
> org.glassfish.jersey.internal.RuntimeDelegateImpl, which was not found in the
> hbase classpath and caused an exception to be thrown.
> After removing ranger-hbase-plugin-impl/jersey-core-1.19.3.jar, HBase can be
> started normally. The class loading order is as follows:
> javax.ws.rs.ext.RuntimeDelegate is loaded from
> /usr/lib/hadoop/lib/javax.ws.rs-api-2.1.1.jar. Then, the implementation class
> of javax.ws.rs.ext.RuntimeDelegate is searched for, which is found in
> /usr/lib/hadoop/lib/jersey-server-1.19.jar->META-INF/services/javax.ws.rs.ext.RuntimeDelegate->com.sun.jersey.server.impl.provider.RuntimeDelegateImpl,
> and successfully loaded.
> The above class loading order was determined by modifying the code in the
> RangerPluginClassLoader to print out the process of loading all classes.
> !image-2023-04-27-16-15-44-539.png!
> The following is a log that includes the class loading order. By analyzing
> this log in conjunction with the Ranger class loader code, the above results
> can be determined.
>
--
This message was sent by Atlassian Jira
(v8.20.10#820010)