Pig UDF бросает исключение NullPointerException при создании нового кортежа

У меня есть Pig UDF, который поглощает некоторые данные, а затем пытается преобразовать эти данные минимальным образом.

my_data = LOAD 'path/to/data' USING SomeCustomLoader();
my_other_data = FOREACH my_data GENERATE MyUDF(COL_1, COL_2, $param1, $param2) as output;
my_final_data = FOREACH my_other_data GENERATE output.NEW_COL1, output.NEW_COL2, output.NEW_COL3;

Однако я продолжаю получать следующую ошибку:

ОШИБКА 0: Исключение при выполнении [POUserFunc (Имя: POUserFUnc(udf.MyUDF)[tuple] - scope-38 Ключ оператора: scope-38) дочерние элементы: null at []]: java.lang.NullPointerException

Моя UDF берет данные и преобразует их:

public class MyUDF extends EvalFunc<Tuple> {
    public Tuple exec(Tuple input) throws IOException {
        if (input == null || input.size() == 0)
            return null;

        TupleFactory _factory;

        Long fieldOne;
        String fieldTwo;
        String fieldThree;

        _factory.getInstance();

        try {
            fieldOne = Long.valueOf(input.get(0).toString());
            fieldTwo = input.get(1).toString();
            fieldThree = input.get(2).toString();

            fieldOne = doSomething(fieldOne);
            fieldTwo = doSomething(fieldTwo);
            fieldThree = doSomething(fieldThree);

            return _factory.newTuple(Arrays.asList(fieldOne, fieldTwo, fieldThree));

        } catch (Exception ex) {
            return _factory.newTuple(Arrays.asList("ParseException", "", "", ""));
        }
    }
}

Я отладил и подтвердил, что fieldOne, fieldTwo и fieldThree действительно существуют до вызова фабрики кортежей. Также ясно, что исключение генерируется, потому что код достигает блока catch, а затем выдает эту ошибку NullPointerException.

Что непонятно, так это то, почему на земле это происходит.

Согласно документам Pig (API Pig 0.14.0), я должен иметь возможность вызывать newTuple(java.util.List c) с соответствующими элементами.

Я также определил свою собственную схему, чтобы гарантировать правильность типов при возврате к сценарию свиньи.


person clo_jur    schedule 01.11.2016    source источник


Ответы (1)


Рассматриваемый код не создал экземпляр вашего кортежа, поэтому вы не можете вызвать метод для несуществующего объекта.

public class ... {
    TupleFactory _factory;
    public Tuple exec(Tuple input) {
        _factory = TupleFactory.getInstance();
        ...
    }
}
person clo_jur    schedule 01.11.2016