Support #4184
closedError: Invalid configuration property extensionFunction
0%
Description
While trying to create a Java extension function (full interface) and use it via the command line, I've been unable to successfully register the extension when declaring it in a configuration file.
Configuration File¶
<configuration xmlns="http://saxon.sf.net/ns/configuration"
edition="EE">
<resources>
<extensionFunction>com.example.ShiftLeft</extensionFunction>
</resources>
</configuration>
Extension Function Definition¶
package com.example;
import net.sf.saxon.lib.ExtensionFunctionCall;
import net.sf.saxon.lib.ExtensionFunctionDefinition;
import net.sf.saxon.om.Sequence;
import net.sf.saxon.om.StructuredQName;
import net.sf.saxon.trans.XPathException;
import net.sf.saxon.expr.XPathContext;
import net.sf.saxon.value.SequenceType;
import net.sf.saxon.value.IntegerValue;
import net.sf.saxon.value.Int64Value;
// Based upon:
// http://www.saxonica.com/html/documentation/extensibility/integratedfunctions/ext-full-J.html
class ShiftLeft extends ExtensionFunctionDefinition {
@Override
public StructuredQName getFunctionQName() {
return new StructuredQName("eg", "http://example.com/saxon-extension", "shift-left");
}
@Override
public SequenceType[] getArgumentTypes() {
return new SequenceType[]{SequenceType.SINGLE_INTEGER, SequenceType.SINGLE_INTEGER};
}
@Override
public SequenceType getResultType(SequenceType[] suppliedArgumentTypes) {
return SequenceType.SINGLE_INTEGER;
}
@Override
public ExtensionFunctionCall makeCallExpression() {
return new ExtensionFunctionCall() {
@Override
public Sequence call(XPathContext context, Sequence[] arguments) throws XPathException {
long v0 = ((IntegerValue)arguments[0]).longValue();
long v1 = ((IntegerValue)arguments[1]).longValue();
long result = v0<<v1;
return Int64Value.makeIntegerValue(result);
}
};
}
}
Error¶
[xslt] Warning on line 4 column 65 of saxon_config.xml:
[xslt] Invalid configuration property extensionFunction. Supplied value 'com.example.ShiftLeft',
[xslt] required value is the name of a class that implements
[xslt] 'net.sf.saxon.lib.ExtensionFunctionDefinition': Failed to instantiate class
[xslt] com.example.ShiftLeft: class net.sf.saxon.trans.DynamicLoader cannot access a member of
[xslt] class com.example.ShiftLeft with modifiers ""
I've attached a complete, ant-driven example that exhibits the problem I'm having. Hope this helps in reproducing it, or (more likely) spotting the error in my ways.
Thank you,
Kenneth J Hughes
Files
Updated by Martin Honnen over 5 years ago
Does it work if you use public class ShiftLeft ...
? I think that's what the error message is trying to tell, that the class is not available as the default (i.e. non modifier instead of an explicit public
) doesn't make such a class available in a different package.
Updated by Kenneth Hughes over 5 years ago
Martin Honnen wrote:
Does it work if you use
public class ShiftLeft ...
? I think that's what the error message is trying to tell, that the class is not available as the default (i.e. non modifier instead of an explicitpublic
) doesn't make such a class available in a different package.
Hi Martin, good idea, and I believe you're right that the class access modifier should be public
to be visible outside of its package. However, I'd done that to no avail in in my original code. The simplified variation I posted was the one with ShiftLeft
exactly as provided in the documentation, and making the class public
is not working in the simplified example either.
Updated by Kenneth Hughes over 5 years ago
Ahh, but that does lead me to try taking ShiftLeft
out of the package I put it in, and with that change, the extension function is found. Thanks, Martin!
I'm still unclear as to why as a public
class ShiftLeft
is not found when placed in a package.
Updated by Michael Kay over 5 years ago
You're not talking about Java 9 modules are you? If so, we have no experience with them; I've no idea how dynamic loading will work.
Martin correctly identified the original problem, that the class was not public, which meant it could not be dynamically loaded.
You say it doesn't work when you change the class to public but does when you take the class out of the package (and put it in a different package?) I can't see why that should be, and it seems to be doing exactly what our test cases do, so I think I will need more information about exactly what you are doing and exactly how it is failing. It might be a good idea to switch on some of the Java command line options that trace class loading, this may give better diagnostics.
Updated by Kenneth Hughes over 5 years ago
No, wasn't talking about Java 9 modules.
Yes, main issue was that the extension class was not public.
Secondary issue I'm no longer able to reproduce -- may have been a build problem on my side. All's well now.
Thanks Martin and Michael.
Updated by Michael Kay over 5 years ago
- Status changed from New to Closed
Closing this thread as the issue seems to have been resolved.
Please register to edit this issue