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

Franco Graziosi fg123 at fga-software.com
Mon Jul 20 17:53:54 EDT 2009


Julian,

You are right, I am using version 3.0.4.11371

I' ll get the new version.

Thank you very much!

fg


Julian Hyde wrote:
> Update. I just checked the code, and we have a test for this exact case.
> UdfTest.getGenericFun. I recall that there was a bug about mondrian not
> recognizing and using a constructor that takes a string argument.
>
> I don't recall the bug number or change number, and I'm offline right now,
> but the fix was made post 3.1.1. Pick up the nightly build and see whether
> it fixes your problem. I think it will.
>
> 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
>>
>>
>>
>>     
>
>
> _______________________________________________
> Mondrian mailing list
> Mondrian at pentaho.org
> http://lists.pentaho.org/mailman/listinfo/mondrian
>
>   





More information about the Mondrian mailing list