Project

Profile

Help

Bug #5044

closed

Java reflexive calls, NullPointerException when argument is null

Added by Christian Grün almost 3 years ago. Updated over 2 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Saxon extensions
Sprint/Milestone:
-
Start date:
2021-07-19
Due date:
% Done:

100%

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

Description

If a null value is supplied as argument to a Java instance function…

Q{java:java.lang.Object}hash-code(())

…a NullPointerException is returned. Users might rather expect an XQuery error.

Actions #1

Updated by Michael Kay almost 3 years ago

  • Category set to Saxon extensions
  • Assignee set to Michael Kay
  • Priority changed from Low to Normal

JUnit test case jaxptest/ExtensionTest/testInstanceMethodNull added; failure confirmed.

Actions #2

Updated by Michael Kay almost 3 years ago

Added (on 11 branch) a simple check at the time of the function call (JavaExtensionFunctionCall line 558).

However, in this example it should be caught be static type checking, which needs further investigation.

Actions #3

Updated by Michael Kay almost 3 years ago

I expect this example is artificial, I'll probably need to construct another test case where the static type is OK but the argument evaluates to an empty sequence at run-time.

With this example, it slips through static checking, which is probably best handled by an explicit check that the value must not be statically empty.

Actions #4

Updated by Michael Kay almost 3 years ago

I added a test where the argument is dynamically null:

Q{java:java.lang.Object}hash-code(current-date()[year-from-date(.) lt 2000])

and this runs without error: in this case no conversion is applied to the argument, the value of the argument is an instance of net.sf.saxon.value.EmptySequence, which is an instance of java.lang.Object, so the call is perfectly valid. This raises an old thorny question about exactly when an empty sequence is converted to a Java null, and when it isn't.

The documentation isn't very specific about conversions applied to the first argument of a call on an instance method, but it does say that Q{java:java.lang.String}split('a,b,c', ',') should work, meaning that xs:string is converted to java.lang.String.

So I'm now feeling that we're handling the dynamically-empty case correctly (by doing no conversion in this case and treating EmptySequence as an instance of Object), and that we should replicate this in the statically-empty case.

Actions #5

Updated by Michael Kay almost 3 years ago

The case of XPath-to-Java conversion where the required type is java.lang.Object isn't very clearly defined, but I've decided that for the case where this is the required type of the first argument to an instance method, we'll use a new conversion rule of "conditional unwrapping": specifically, if the supplied value is a (singleton) instance of a wrapped Java object, then it is unwrapped, and in all other cases it is used "as is". So the two new test cases both succeed, and return the hash code of the object net.sf.saxon.value.EmptySequence.getInstance().

Changes in this kind of area are always a bit risky, so I think that on the 10.x branch, I'm simply going to have the run-time check that empty/null as the first argument of a call to an instance method fails cleanly rather than throwing an NPE. This probably means you'll get different behaviour for the "statically empty" and "dynamically empty" cases.

Actions #6

Updated by Michael Kay almost 3 years ago

  • Status changed from New to Resolved
  • Applies to branch trunk added
  • Fix Committed on Branch 10, trunk added
Actions #7

Updated by Michael Kay over 2 years ago

  • Subject changed from Java calls, null values to Java reflexive calls, NullPointerException when argument is null
Actions #8

Updated by O'Neil Delpratt over 2 years ago

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

Bug fix applied in the Saxon 10.6 maintenance release

Please register to edit this issue

Also available in: Atom PDF