0

I am trying to write GenericUDF for Hive. When I add JAR and try to create a temporary function pointing to the class, I get an error, so function creation does not succeed. Can someone provide Java code template for GenericUDF function that accepts one argument of type String and returns an object of type Map. There is so much confusion regarding Object Inspector classes, so it will be of much help if someone provides me very basic template for input type and return type of this function.

So my Java code is here:-

package test;

import java.util.HashMap;
import java.util.Map;
import org.apache.hadoop.hive.ql.exec.UDFArgumentException;
import org.apache.hadoop.hive.ql.exec.UDFArgumentLengthException;
import org.apache.hadoop.hive.ql.metadata.HiveException;
import org.apache.hadoop.hive.ql.udf.generic.GenericUDF;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.JavaIntObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorConverter;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.PrimitiveObjectInspectorFactory;
import org.apache.hadoop.hive.serde2.objectinspector.primitive.StringObjectInspector;

public class CustomUDF extends GenericUDF
{

    Map<Character,Integer> myMap; 
    StringObjectInspector elementOI;

    @Override
    public String getDisplayString(String[] arg0) 
    {
        // TODO Auto-generated method stub
        return "myfunction()";
    }



    @Override
    public ObjectInspector initialize(ObjectInspector[] arg) throws UDFArgumentException 
    {

        if (arg.length != 1) 
        {
              throw new UDFArgumentLengthException("myfunction() only takes 1 argument: String");
        }

        // 1. Check we received the right object types.
        ObjectInspector a = arg[0];
        if (!(a instanceof StringObjectInspector)) 
        {
          throw new UDFArgumentException("Argument must be a string");
        }

        // The custom function is going to return an object of type Map<Character,Integer>
        myMap = new HashMap<Character,Integer>();
        this.elementOI = (StringObjectInspector) a;


        // I could not find way to create ObjectInspector for Character so I am creating ObjectInspector for String
        return ObjectInspectorFactory.getStandardMapObjectInspector(PrimitiveObjectInspectorFactory.javaStringObjectInspector,  PrimitiveObjectInspectorFactory.javaIntObjectInspector);
    }





    @Override
    public Object evaluate(DeferredObject[] arg) throws HiveException 
    {

        myMap.clear();


        String str = elementOI.getPrimitiveJavaObject(arg[0].get());

        // check for nulls
        if (str == null) 
        {
          return null;
        }

        for(Character ch: str.toCharArray()) 
        {
          myMap.put(ch,1);
        }
        return myMap;


    }

}

And this is what happens when I try to create function in Hive against the JAR:-

hive> add jar test.jar;
Added [test.jar] to class path
Added resources: [test.jar]
hive> create temporary function myfunction as 'test.CustomUDF';
java.lang.UnsupportedClassVersionError: test/CustomUDF : Unsupported major.minor version 52.0
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:803)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:278)
        at org.apache.hadoop.hive.ql.exec.FunctionTask.getUdfClass(FunctionTask.java:307)
        at org.apache.hadoop.hive.ql.exec.FunctionTask.createTemporaryFunction(FunctionTask.java:174)
        at org.apache.hadoop.hive.ql.exec.FunctionTask.execute(FunctionTask.java:74)
        at org.apache.hadoop.hive.ql.exec.Task.executeTask(Task.java:160)
        at org.apache.hadoop.hive.ql.exec.TaskRunner.runSequential(TaskRunner.java:86)
        at org.apache.hadoop.hive.ql.Driver.launchTask(Driver.java:1631)
        at org.apache.hadoop.hive.ql.Driver.execute(Driver.java:1390)
        at org.apache.hadoop.hive.ql.Driver.runInternal(Driver.java:1197)
        at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1024)
        at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1014)
        at org.apache.hadoop.hive.cli.CliDriver.processLocalCmd(CliDriver.java:250)
        at org.apache.hadoop.hive.cli.CliDriver.processCmd(CliDriver.java:202)
        at org.apache.hadoop.hive.cli.CliDriver.processLine(CliDriver.java:413)
        at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:786)
        at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:680)
        at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:619)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)
        at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
        at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
FAILED: Execution Error, return code -101 from org.apache.hadoop.hive.ql.exec.FunctionTask. test/CustomUDF : Unsupported major.minor version 52.0
Dhiraj
  • 3,396
  • 4
  • 41
  • 80
  • Can you please provide more info about the UDF that you are writing and stacktrace of the exception that you are getting – Sachin Janani Jul 21 '16 at 10:44
  • Hi Sachin, I have modified the code, I don't have previous code. But as of now even function creation is failing. I have edited my post and provided complete code for this. Thanks. – Dhiraj Jul 21 '16 at 20:36
  • 1
    it's very common problem, go thourgh this question- http://stackoverflow.com/questions/10382929/how-to-fix-java-lang-unsupportedclassversionerror-unsupported-major-minor-versi – Rahul Sharma Jul 21 '16 at 21:01
  • Thanks, I will check. @Sachin, can you please check the code. There is still one issue. The function is supposed to return object of type Map but look at the last line of my iniitalize method. I am not able to figure out how to create ObjectInspector for Character. – Dhiraj Jul 21 '16 at 21:09
  • I got rid of Java version conflict issue and the code is working fine. But I wonder if using String ObjectInspector for Character type is fine or there is better solution than this? – Dhiraj Jul 21 '16 at 22:36
  • 1
    Refer this https://github.com/twitter/elephant-bird/blob/master/hive/src/main/java/com/twitter/elephantbird/hive/serde/ProtobufStructObjectInspector.java for writing custom object inspector – Sachin Janani Jul 22 '16 at 03:15
  • So are you saying for Character ObjectInspector is not available? Creating custom object inspector would be an overkill I guess, I can go with using String ObjectInspector since it is working fine. Thanks. – Dhiraj Jul 22 '16 at 03:18

0 Answers0