LuciferYang opened a new issue, #7705:
URL: https://github.com/apache/kyuubi/issues/7705

   ### Describe the bug
   
   `DynMethods.Builder` probes a chain of candidate classes and signatures, 
swallowing each lookup failure so the next candidate gets a turn. When none 
matches, `build()` and `buildChecked()` throw with the method name alone:
   
   ```java
       public UnboundMethod build() {
         if (method != null) {
           return method;
         } else {
           throw new RuntimeException("Cannot find method: " + name);
         }
       }
   ```
   
   Every `ClassNotFoundException` and `NoSuchMethodException` collected on the 
way is gone, so the message names neither the classes that were tried nor the 
signatures they were tried with.
   
   `HiveConnectorUtils.storageFormatApply` shows what that costs. It probes the 
seven-argument `CatalogStorageFormat.apply` that SPARK-55645 added in Spark 
4.2, then the six-argument one:
   
   ```scala
       DynMethods.builder("apply")
         .impl( // SPARK-55645 (4.2.0): 7-arg apply with serdeName
           classOf[CatalogStorageFormat],
           ...
         .impl( // Spark < 4.2.0: 6-arg apply without serdeName
   ```
   
   On a Spark whose signature matches neither, the whole diagnosis is `Cannot 
find method: apply`. Nothing says which two arities were tried, so there is no 
way to tell a Spark version this code has never seen from a genuine bug in the 
probe. `RowSet.toHiveString` (four-argument then five-argument) and 
`SparkUtilsHelper.getLocalDir` have the same shape.
   
   `DynConstructors.Builder` in the same package does not have this problem: it 
records each miss in a `problems` map and attaches the entries to the thrown 
exception, both in the message and as suppressed throwables.
   
   It does have a related one, which surfaces as soon as `DynMethods.ctorImpl` 
starts reporting what it delegates. `DynConstructors.methodName` renders a 
candidate by calling `getName()` on every argument type, so a null element 
throws `NullPointerException` out of the `catch` that was supposed to record an 
ordinary miss:
   
   ```java
         sb.append(type.getName());
   ```
   
   A null element is what a caller passes when it probes an optional dependency 
through `DynClasses.builder()...orNull().build()`, and `getConstructor` treats 
it as a plain no-match rather than an error. `EmbeddedExecutorFactory` writes 
that shape with `LEGACY_TIME_CLASS`, which is null on Flink 2.x, and is saved 
only by an earlier candidate matching first.
   
   ### Affects Version(s)
   
   master (1.13.0-SNAPSHOT), and every earlier release carrying this file.
   
   ### Are you willing to submit PR?
   
   Yes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to