ReflectUtils.isClassLoadable throws LinkageError instead of answering false for classes that fail to link or initialize
- 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
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