Project

Profile

Help

Support #4184

Error: Invalid configuration property extensionFunction

Added by Kenneth Hughes 6 months ago. Updated about 1 month ago.

Status:
Closed
Priority:
Low
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
2019-03-28
Due date:
% Done:

0%

Legacy ID:
Applies to branch:
9.9
Fix Committed on Branch:
Fixed in Maintenance Release:

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

extensionFunction.zip (3.94 KB) contains complete example Kenneth Hughes, 2019-03-28 19:11 extensionFunction.zip

History

#1 Updated by Martin Honnen 6 months 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.

#2 Updated by Kenneth Hughes 6 months 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 explicit public) 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.

#3 Updated by Kenneth Hughes 6 months 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.

#4 Updated by Michael Kay 6 months 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.

#5 Updated by Kenneth Hughes 5 months 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.

#6 Updated by Michael Kay about 1 month ago

  • Status changed from New to Closed

Closing this thread as the issue seems to have been resolved.

Please register to edit this issue

Also available in: Atom PDF