apache / apache/kyuubi

ReflectUtils.isClassLoadable throws LinkageError instead of answering false for classes that fail to link or initialize

Open
#7,723 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Scala
Stars
2.4k
Forks
1k
PR merge metrics
No merged PRs in 30d

Description

### Describe the bug

`ReflectUtils.isClassLoadable` probes a class through `DynClasses`, wrapped in `scala.util.Try`:

```scala
def isClassLoadable(
className: String,
cl: ClassLoader = Thread.currentThread().getContextClassLoader): Boolean =
Try {
DynClasses.builder().loader(cl).impl(className).buildChecked()
}.isSuccess
```

`DynClasses.impl` resolves the name with `Class.forName(className, true, loader)`. `initialize = true` means loading the class also links it and runs its static initializer, so a class that is present but fails at that stage raises a `LinkageError`, not a `ClassNotFoundException`: `NoClassDefFoundError` for a missing superclass or dependency, `ExceptionInInitializerError` when a static initializer throws.

`Try` only catches `NonFatal`, and `LinkageError` is excluded from `NonFatal`. So a class that fails to link or initialize never reaches `.isSuccess`; the `LinkageError` escapes `isClassLoadable` and crashes the caller. A loadability probe should answer `false` for such a class, not throw.

Both call sites treat the result as a feature-detection boolean and never expect an exception:

- `Logging.scala:152`: `if (ReflectUtils.isClassLoadable("org.slf4j.bridge.SLF4JBridgeHandler"))`
- `JDBCMetadataStore.scala:51`: `if (ReflectUtils.isClassLoadable("com.mysql.cj.jdbc.Driver"))`

A probed class that is on the classpath but whose static initializer throws (a misconfigured dependency, say) aborts the check instead of being reported as not loadable.

The `Try` wrapping came in with the reflection-utility consolidation (#4887); nothing there depended on a `LinkageError` propagating.

### Affects Version(s)

master (1.13.0-SNAPSHOT), and earlier releases carrying `kyuubi-util-scala`.

### Are you willing to submit PR?

Yes.

Contributor guide

Open the contributing guide

Research direction

Start with ReflectUtils.isClassLoadable and its DynClasses/scala.util.Try usage, then inspect the call sites in Logging.scala:152 and JDBCMetadataStore.scala:51. Reproduce behavior with classes that fail linking or initialization, and add or update a regression test near the reflection utility. Done means the probe returns false instead of propagating the LinkageError while existing feature checks remain unaffected.

Written by the indexing model from the issue text.

Assessment

Tech stack
scala
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.