This is an automated email from the ASF dual-hosted git repository.
slawrence pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new 3c4c1924d Include the cause when a plugin fails to be instantiated
3c4c1924d is described below
commit 3c4c1924db971baf38689e30b11d019b5dba3448
Author: Steve Lawrence <[email protected]>
AuthorDate: Tue Apr 8 09:23:22 2025 -0400
Include the cause when a plugin fails to be instantiated
If a UDF, charset, or layer plugin fails to be instantiated because and
exception is thrown when loading, then we get a pretty helpful message,
like:
Named service XYZ failed to load. Cause: Provider XYZ could not be
instantiated
This provides no useful information as to the underlying cause why the
provider could not be instantiated, so is very difficult to track down
and fix.
When this kind of error occurs, Java throws a ServiceConfigurationError
exception and includes the underlying exception as the cause. This
changes the logging message so we include the cause if one exists. This
should make it a little easier for users to figure out why their plugin
failed to load.
DAFFODIL-2989
---
.../daffodil/lib/util/SimpleNamedServiceLoader.scala | 16 ++++++++++++++--
.../runtime1/udf/UserDefinedFunctionService.scala | 13 ++++++++++++-
.../scala/org/apache/daffodil/cliTest/TestCLIUdfs.scala | 5 ++++-
3 files changed, 30 insertions(+), 4 deletions(-)
diff --git
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SimpleNamedServiceLoader.scala
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SimpleNamedServiceLoader.scala
index 9324a79ea..3177c685a 100644
---
a/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SimpleNamedServiceLoader.scala
+++
b/daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SimpleNamedServiceLoader.scala
@@ -16,6 +16,8 @@
*/
package org.apache.daffodil.lib.util
+import java.io.PrintWriter
+import java.io.StringWriter
import java.util.ServiceConfigurationError
import java.util.ServiceLoader
import scala.collection.mutable.ArrayBuffer
@@ -49,8 +51,18 @@ object SimpleNamedServiceLoader {
try {
instanceBuf += iter.next()
} catch {
- case e: ServiceConfigurationError =>
- Logger.log.warn(s"Named service $thingName failed to load. Cause:
${e.getMessage}")
+ case e: ServiceConfigurationError => {
+ Logger.log.warn(
+ s"Named service $thingName failed to load: ${e.getMessage}.
Enable debug logging for more details"
+ )
+ Logger.log.debug({
+ val sw = new StringWriter()
+ val pw = new PrintWriter(sw, true)
+ e.printStackTrace(pw)
+ pw.close()
+ sw.toString()
+ })
+ }
}
}
val instancesFound: Map[String, Seq[T]] = instanceBuf.toSeq.groupBy {
_.name() }
diff --git
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/udf/UserDefinedFunctionService.scala
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/udf/UserDefinedFunctionService.scala
index 2986b2dcd..a14f9d004 100644
---
a/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/udf/UserDefinedFunctionService.scala
+++
b/daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/udf/UserDefinedFunctionService.scala
@@ -21,7 +21,9 @@ import java.io.ByteArrayOutputStream
import java.io.NotSerializableException
import java.io.ObjectInputStream
import java.io.ObjectOutputStream
+import java.io.PrintWriter
import java.io.Serializable
+import java.io.StringWriter
import java.lang.reflect.Method
import java.util.ServiceConfigurationError
import java.util.ServiceLoader
@@ -110,7 +112,16 @@ object UserDefinedFunctionService {
Some(providerIter.next())
} catch {
case e: ServiceConfigurationError => {
- Logger.log.warn(s"User Defined Function Provider failed to load:
${e.getMessage}")
+ Logger.log.warn(
+ s"User Defined Function Provider failed to load:
${e.getMessage}. Enable debug logging for more details"
+ )
+ Logger.log.debug({
+ val sw = new StringWriter()
+ val pw = new PrintWriter(sw)
+ e.printStackTrace(pw)
+ pw.close()
+ sw.toString()
+ })
None
}
}
diff --git
a/daffodil-test-integration/src/test/scala/org/apache/daffodil/cliTest/TestCLIUdfs.scala
b/daffodil-test-integration/src/test/scala/org/apache/daffodil/cliTest/TestCLIUdfs.scala
index a145b9aa8..d0acb49a1 100644
---
a/daffodil-test-integration/src/test/scala/org/apache/daffodil/cliTest/TestCLIUdfs.scala
+++
b/daffodil-test-integration/src/test/scala/org/apache/daffodil/cliTest/TestCLIUdfs.scala
@@ -369,13 +369,16 @@ class TestCLIUdfs {
"daffodil-udf/src/test/scala/org/sbadudfs/udfpexceptions2/StringFunctions/"
)
- runCLI(args"-v parse -s $schema -r user_func3", classpath) { cli =>
+ runCLI(args"-vv parse -s $schema -r user_func3", classpath) { cli =>
cli.expectErr(
"[warn] User Defined Function Provider failed to load:
org.apache.daffodil.udf.UserDefinedFunctionProvider"
)
cli.expectErr(
"Provider
org.sbadudfs.udfpexceptions2.StringFunctions.StringFunctionsProvider could not
be instantiated"
)
+ cli.expectErr(
+ "Caused by:
org.sbadudfs.udfpexceptions2.StringFunctions.StringFunctionsProvider$CustomException:
UDFP Error!"
+ )
cli.expectErr("[error] Schema Definition Error: Unsupported function:
ssudf:rev-words")
}(ExitCode.UnableToCreateProcessor)
}