[Mondrian] Failed to load user-defined function ... does not implement the required interface 'mondrian.spi.UserDefinedFunction'

Julian Hyde jhyde at pentaho.com
Mon Jul 20 14:22:59 EDT 2009


Looks like a bug. Can you log a jira case for this, please? What version are
you running?

Julian

> -----Original Message-----
> From: mondrian-bounces at pentaho.org 
> [mailto:mondrian-bounces at pentaho.org] On Behalf Of Franco Graziosi
> Sent: Monday, July 20, 2009 1:56 AM
> To: Mondrian developer mailing list
> Subject: [Mondrian] Failed to load user-defined function ... 
> does not implement the required interface 
> 'mondrian.spi.UserDefinedFunction'
> 
> Hello,
> 
> H have created a simple user defined function to simplify zero-divide
> prevention instead of using each time an iif wrapper. The 
> function takes
> two arguments and if the second - denominator - is zero or null
> it returns null.  That function alone works fine. I created a variant
> called "increase" that computes an increase instead of ratio and,
> following Mondrian documentation, I tried to put both function in same
> class varying the defined name. (I actually did the reverse 
> and not working
> went back to define a single function and discovered the cause of the 
> problem).
> 
> Here is the class that implement both functions:
> 
>         package net.cbsolution.ps.pisa.fns;
> 
>         import mondrian.olap.Evaluator;
>         import mondrian.olap.Syntax;
>         import mondrian.olap.type.NumericType;
>         import mondrian.olap.type.Type;
>         import mondrian.spi.UserDefinedFunction;
> 
>         public class Ratio implements UserDefinedFunction {
>           private boolean isIncrease;
>          
>           public Ratio(String name) {
>             if ("Ratio".equals(name))
>               isIncrease = false;
>             else if ("Increase".equals(name))
>               isIncrease = true;
>           }
> 
>           @Override
>           public Object execute(Evaluator evaluator, 
> Argument[] arguments) {
>             final Object arg0 = 
> arguments[0].evaluateScalar(evaluator);
>             final Object arg1 = 
> arguments[1].evaluateScalar(evaluator);
>             if (arg0 == null || arg1 == null || (!(arg0 instanceof
>         Number))  || (!(arg1 instanceof Number)))
>               return null;
>             double denom = ((Number)arg1).doubleValue();
>             if (denom == 0)
>               return null;
>             double result = ((Number)arg0).doubleValue() / denom;
>             if (isIncrease)
>               result -= 1.0;
>             return result;
>           }
> 
>           @Override
>           public String getDescription() {
>             return "Return a ratio between two numbers, prevent zero
>         divide and null values returning null in such cases";
>           }
> 
>           @Override
>           public String getName() {
>             if (isIncrease)
>               return "Increase";
>             else
>               return "Ratio";
>           }
> 
>           @Override
>           public Type[] getParameterTypes() {
>             return new Type[] { new NumericType(), new 
> NumericType() };
>           }
> 
>           @Override
>           public String[] getReservedWords() {
>             return null;
>           }
> 
>           @Override
>           public Type getReturnType(Type[] parameterTypes) {
>             return new NumericType();
>           }
> 
>           @Override
>           public Syntax getSyntax() {
>             return Syntax.Function;
>           }
> 
>         }
> 
> 
> And here is the schema code:
> 
>     <UserDefinedFunction name="Ratio" 
> class="net.cbsolution.ps.pisa.fns.Ratio" />
>     <UserDefinedFunction name="Increase" 
> class="net.cbsolution.ps.pisa.fns.Ratio" />
> 
> I get the following exception:
> 
>     Mondrian Error:Failed to load user-defined function '': class 
> 'net.cbsolution.ps.pisa.fns.Ratio' does not implement the required 
> interface 'mondrian.spi.UserDefinedFunction'
> 
> Looking at stack trace I went to the problem 
> (mondrian.olap.Util : 2280):
> 
>        try {
>             udf = (UserDefinedFunction) udfClass.newInstance();
>         } catch (InstantiationException e) {
>             throw 
> MondrianResource.instance().UdfClassWrongIface.ex("",
>                     className, UserDefinedFunction.class.getName());
>         } catch (IllegalAccessException e) {
>             throw 
> MondrianResource.instance().UdfClassWrongIface.ex("",
>                     className, UserDefinedFunction.class.getName());
> 
> Mondrian code tries to instantiate with a zero-argument 
> constructor that 
> obviously do
> not exists. (Note: if I define a zero argument constructor 
> the function 
> is instantiated but
> I get a duplicate Ratio and no Increase).
> 
> Are multiple-name functions really supported?
> 
> fg
> 
> 
> _______________________________________________
> Mondrian mailing list
> Mondrian at pentaho.org
> http://lists.pentaho.org/mailman/listinfo/mondrian
> 
> 
> 





More information about the Mondrian mailing list