Project

Profile

Help

Bug #5920

closed

Java reflexive API fails to run, throws ClassNotFoundException for org.jdom2.Document

Added by Mary Holstege over 1 year ago. Updated over 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Saxon extensions
Sprint/Milestone:
-
Start date:
2023-03-13
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
12, trunk
Fix Committed on Branch:
12, trunk
Fixed in Maintenance Release:
Platforms:
Java

Description

With Saxon 12 (EE) but not with Saxon 11 importing a module that references a Java method using reflection does not run but fails with the stack below. I've pared it down: simply having the reference to the Java methods seems to be enough.

Run as: java -cp saxon-ee-12.0.jar net.sf.saxon.Query -q:crash.xqy

xception in thread "main" java.lang.NoClassDefFoundError: org/jdom2/Document at net.sf.saxon.option.jdom2.JDOM2ObjectModel.isRecognizedNodeClass(JDOM2ObjectModel.java:159) at net.sf.saxon.option.jdom2.JDOM2ObjectModel.getPJConverter(JDOM2ObjectModel.java:104) at net.sf.saxon.expr.PJConverter.allocate(PJConverter.java:220) at com.saxonica.expr.JavaExtensionFunctionCall.typeCheck(JavaExtensionFunctionCall.java:228) at com.saxonica.config.JavaExtensionLibrary$UnresolvedExtensionFunctionCall.typeCheck(JavaExtensionLibrary.java:1164) at net.sf.saxon.expr.Operand.typeCheck(Operand.java:224) at net.sf.saxon.expr.flwor.FLWORExpression.lambda$typeCheck$1(FLWORExpression.java:178) at net.sf.saxon.expr.flwor.LetClause.processOperands(LetClause.java:133) at net.sf.saxon.expr.flwor.FLWORExpression.typeCheck(FLWORExpression.java:180) at net.sf.saxon.query.XQueryFunction.compile(XQueryFunction.java:423) at net.sf.saxon.query.XQueryFunctionLibrary.fixupGlobalFunctions(XQueryFunctionLibrary.java:423) at net.sf.saxon.query.QueryModule.fixupGlobalFunctions(QueryModule.java:1103) at net.sf.saxon.expr.instruct.Executable.fixupQueryModules(Executable.java:446) at net.sf.saxon.query.XQueryParser.makeXQueryExpression(XQueryParser.java:175) at net.sf.saxon.query.StaticQueryContext.compileQuery(StaticQueryContext.java:563) at net.sf.saxon.query.StaticQueryContext.compileQuery(StaticQueryContext.java:625) at net.sf.saxon.s9api.XQueryCompiler.compile(XQueryCompiler.java:651) at net.sf.saxon.Query.compileQuery(Query.java:869) at net.sf.saxon.Query.doQuery(Query.java:330) at net.sf.saxon.Query.main(Query.java:106) Caused by: java.lang.ClassNotFoundException: org.jdom2.Document at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)


Files

crash.xqy (152 Bytes) crash.xqy Main module Mary Holstege, 2023-03-13 22:16
crashlib.xqy (580 Bytes) crashlib.xqy Library module Mary Holstege, 2023-03-13 22:16
Actions #1

Updated by Martin Honnen over 1 year ago

Oh no, 12.1 delayed further with that finding...?

Actions #2

Updated by Martin Honnen over 1 year ago

I tried to put the JDOM 2 jar on the class path with e.g. java -cp 'C:\Program Files\Saxonica\SaxonEE12-0J\saxon-ee-12.0.jar;jdom2-2.0.6.jar' net.sf.saxon.Query -q:crash.xqy, now Saxon 12 complains about missing dom4j

Exception in thread "main" java.lang.NoClassDefFoundError: org/dom4j/Document
        at net.sf.saxon.option.dom4j.DOM4JObjectModel.isRecognizedNodeClass(DOM4JObjectModel.java:161)
        at net.sf.saxon.option.dom4j.DOM4JObjectModel.getPJConverter(DOM4JObjectModel.java:88)
        at net.sf.saxon.expr.PJConverter.allocate(PJConverter.java:220)
        at com.saxonica.expr.JavaExtensionFunctionCall.typeCheck(JavaExtensionFunctionCall.java:228)
        at com.saxonica.config.JavaExtensionLibrary$UnresolvedExtensionFunctionCall.typeCheck(JavaExtensionLibrary.java:1164)
        at net.sf.saxon.expr.Operand.typeCheck(Operand.java:224)
        at net.sf.saxon.expr.flwor.FLWORExpression.lambda$typeCheck$1(FLWORExpression.java:178)
        at net.sf.saxon.expr.flwor.LetClause.processOperands(LetClause.java:133)
        at net.sf.saxon.expr.flwor.FLWORExpression.typeCheck(FLWORExpression.java:180)
        at net.sf.saxon.query.XQueryFunction.compile(XQueryFunction.java:423)
        at net.sf.saxon.query.XQueryFunctionLibrary.fixupGlobalFunctions(XQueryFunctionLibrary.java:423)
        at net.sf.saxon.query.QueryModule.fixupGlobalFunctions(QueryModule.java:1103)
        at net.sf.saxon.expr.instruct.Executable.fixupQueryModules(Executable.java:446)
        at net.sf.saxon.query.XQueryParser.makeXQueryExpression(XQueryParser.java:175)
        at net.sf.saxon.query.StaticQueryContext.compileQuery(StaticQueryContext.java:563)
        at net.sf.saxon.query.StaticQueryContext.compileQuery(StaticQueryContext.java:625)
        at net.sf.saxon.s9api.XQueryCompiler.compile(XQueryCompiler.java:651)
        at net.sf.saxon.Query.compileQuery(Query.java:869)
        at net.sf.saxon.Query.doQuery(Query.java:330)
        at net.sf.saxon.Query.main(Query.java:106)
Caused by: java.lang.ClassNotFoundException: org.dom4j.Document
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        ... 20 more
Actions #3

Updated by Norm Tovey-Walsh over 1 year ago

Hi Mary,

I can't explain off the top of my head why we're trying to instantiate these other object models in this case, but as a quick workaround, adding jdom2 and dom4j jar files to the class path seems to avoid the NoClassDefFound error(s).

Actions #4

Updated by Norm Tovey-Walsh over 1 year ago

This is a direct consequence of the fix for #5725 which observes that it's a risky change.

We no longer attempt to check if models (.e.g, jdom2 and dom4j) are available before registering them as external models, so they get registered.

But then, when we're attempting to reflexively instantiate a Java class, we attempt to get a converter for those models, they aren't available, and a NoClassDefError is thrown.

I'm assuming that it's still desirable not to attempt to instantiate them every time (the #5725 fix), so I'm moving the try/catch into the PJConverter and JPConverter classes. This means attempting to instantiate, for example, a java.io.File will succeed even though (some) of the models may fail to instantiate.

I wonder if it's worth adding an API on Configuration to mark some registered models as unavailable. If we don't then we're going to try (and fail, and throw an exception) on every attempt to instantiate a Java class reflexively. That seems like a potential problem if there are stylesheets out there that instantiate a lot of objects.

Actions #5

Updated by Michael Kay over 1 year ago

Yes, I think catching the exception in PJConverter and JPConverter is the way to do it. I've been hunting around to see if there's any way we can detect the availability of the classes without throwing the exception and I think the answer is no. I've arranged it so that if the exception is thrown the first time, then the object model is deregistered from the configuration, which means no further attempts will be made.

I added a unit test to jaxptest/ExtensionTest that registers a user-defined ExternalObjectModel and demonstrates recovery when it's found that it can't be loaded.

Actions #6

Updated by Norm Tovey-Walsh over 1 year ago

Ah. Okay. I'll check your commits and discard mine. (I'd fixed the bug! ;-), I was just trying to decide if pulling the failed models out of the external model list was the right way forward.)

Actions #7

Updated by Michael Kay over 1 year ago

  • Category set to Saxon extensions
  • Status changed from New to Resolved
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal
  • Applies to branch trunk added
  • Fix Committed on Branch 12, trunk added
  • Platforms Java added

Fixed on the 12.x and main branches.

Actions #8

Updated by O'Neil Delpratt over 1 year ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 12.1 added

Bug fix applied in the Saxon 12.1 maintenance release.

Please register to edit this issue

Also available in: Atom PDF