Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中的配置单元UDF在创建表时失败_Java_Hive_Hive Udf - Fatal编程技术网

Java中的配置单元UDF在创建表时失败

Java中的配置单元UDF在创建表时失败,java,hive,hive-udf,Java,Hive,Hive Udf,这两个查询之间的区别是什么: SELECT my_fun(col_name) FROM my_table; 及 我的乐趣是java UDF 我这样问是因为当我创建新表(第二个查询)时,我收到一个java错误 Failure while running task:java.lang.RuntimeException: java.lang.RuntimeException: Map operator initialization failed ... Caused by: org.apache.h

这两个查询之间的区别是什么:

SELECT my_fun(col_name) FROM my_table;

我的乐趣是java UDF

我这样问是因为当我创建新表(第二个查询)时,我收到一个java错误

Failure while running task:java.lang.RuntimeException: java.lang.RuntimeException: Map operator initialization failed
...
Caused by: org.apache.hadoop.hive.ql.exec.UDFArgumentException: Unable to instantiate UDF implementation class com.company_name.examples.ExampleUDF: java.lang.NullPointerException
我发现错误的来源是我的java文件中的第行:

encoded = Files.readAllBytes(Paths.get(configPath));

但问题是为什么它在未创建表时工作,而在创建表时失败?

问题可能在于您读取文件的方式。尝试将文件路径作为UDF中的第二个参数传递,然后按如下方式读取

private BufferedReader getReaderFor(String filePath) throws HiveException {
    try {
        Path fullFilePath = FileSystems.getDefault().getPath(filePath);
        Path fileName = fullFilePath.getFileName();
        if (Files.exists(fileName)) {
            return Files.newBufferedReader(fileName, Charset.defaultCharset());
        }
        else
        if (Files.exists(fullFilePath)) {
            return Files.newBufferedReader(fullFilePath, Charset.defaultCharset());
        }
        else {
            throw new HiveException("Could not find \"" + fileName + "\" or \"" + fullFilePath + "\" in inersect_file() UDF.");
        }
    }
    catch(IOException exception) {
        throw new HiveException(exception);
    }
}

private void loadFromFile(String filePath) throws HiveException {
    set = new HashSet<String>();

    try (BufferedReader reader = getReaderFor(filePath)) {
        String line;
        while((line = reader.readLine()) != null) {
            set.add(line);
        }
    } catch (IOException e) {
        throw new HiveException(e);
    }
}
private BufferedReader getReaderFor(字符串文件路径)引发HiveException{
试一试{
Path fullFilePath=FileSystems.getDefault().getPath(filePath);
路径文件名=fullFilePath.getFileName();
if(Files.exists(fileName)){
返回Files.newBuffereder(文件名,Charset.defaultCharset());
}
其他的
if(Files.exists(fullFilePath)){
返回Files.newBufferedReader(fullFilePath,Charset.defaultCharset());
}
否则{
抛出新的HiveException(“在InSect\u file()UDF中找不到\“+fileName+”\”或\“+fullFilePath+”\”);
}
}
捕获(IOException异常){
抛出新的HiveException(异常);
}
}
私有void loadFromFile(字符串文件路径)引发HiveException{
set=新的HashSet();
try(BufferedReader=getReader(文件路径)){
弦线;
而((line=reader.readLine())!=null){
设置。添加(行);
}
}捕获(IOE异常){
抛出新的HiveException(e);
}
}

可以找到使用文件读取器的不同通用UDF的完整代码

我认为有几点不清楚,所以这个答案是基于假设的

首先,重要的是要了解hive目前优化了几个简单的查询,并且根据数据的大小,为您工作的查询
从my_表中选择my_fun(col_name)
很可能从执行作业的客户端本地运行,这就是为什么UDF可以访问本地可用的配置文件,这种“执行模式”是因为数据的大小。CTA触发一个独立于输入数据的作业,该作业在集群中分布式运行,其中每个工作人员都无法访问您的配置文件

看起来您正在尝试从本地文件系统而不是从HDSFS
文件.readAllBytes(path.get(configPath))
读取配置文件,这意味着您的配置必须在所有工作节点中复制,或者之前添加到分布式缓存中(您可以在此使用添加文件,文档。您可以从UDF中找到有关从分布式缓存访问文件的其他问题


另一个问题是,您正在通过一个环境变量传递配置文件的位置,该环境变量未作为配置单元作业的一部分传播到工作节点。您应该将此配置作为配置单元配置传递,假设您正在扩展GenericUDF,则可以从UDF访问配置单元配置。

有多少行是否在您的表中?如果它非常小,则第一个查询可能在本地执行,而第二个查询仅在Hadoop群集上执行。此外,
configPath
是否指示本地路径或HDFS路径?创建表为select(第二个示例)是CTA。它对可能会导致问题的表有一些限制。您是否阅读了上一节?它列出了两个限制:1:目标表不能是外部表。2:目标表不能是列表扣表。这两个限制是否适用?@serge_k似乎与表大小无关,即。它对于大小表都失败。我在本地文件系统和hdfs上测试了configPath,但它也失败了。但这可能是一个很好的点,因为此路径设置为环境变量。如果它是硬编码的,则可以工作。我必须检查它。@zac no,它在这种情况下不适用。
private BufferedReader getReaderFor(String filePath) throws HiveException {
    try {
        Path fullFilePath = FileSystems.getDefault().getPath(filePath);
        Path fileName = fullFilePath.getFileName();
        if (Files.exists(fileName)) {
            return Files.newBufferedReader(fileName, Charset.defaultCharset());
        }
        else
        if (Files.exists(fullFilePath)) {
            return Files.newBufferedReader(fullFilePath, Charset.defaultCharset());
        }
        else {
            throw new HiveException("Could not find \"" + fileName + "\" or \"" + fullFilePath + "\" in inersect_file() UDF.");
        }
    }
    catch(IOException exception) {
        throw new HiveException(exception);
    }
}

private void loadFromFile(String filePath) throws HiveException {
    set = new HashSet<String>();

    try (BufferedReader reader = getReaderFor(filePath)) {
        String line;
        while((line = reader.readLine()) != null) {
            set.add(line);
        }
    } catch (IOException e) {
        throw new HiveException(e);
    }
}