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 <slawre...@apache.org> 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) }