apache依赖性bug?在apache库中找不到org.apache.parquet.hadoop.codec.snappycodec错误

vaj7vani  于 2021-07-13  发布在  Hadoop
关注(0)|答案(1)|浏览(369)

目前正在尝试读取java中的Parquet文件而不使用spark。以下是我到目前为止得到的,基于亚当·梅尔尼克关于这个问题的博客文章。
代码

ParquetFileReader reader = ParquetFileReader.open(file);
        MessageType schema = reader.getFooter().getFileMetaData().getSchema();
        List<Type> fields = schema.getFields();
        PageReadStore pages;
-->     while ((pages = reader.readNextRowGroup()) != null) {
            long rows = pages.getRowCount();
            LOG.info("Number of rows: " + rows);
            MessageColumnIO columnIO = new ColumnIOFactory().getColumnIO(schema);
            RecordReader recordReader = columnIO.getRecordReader(pages, new GroupRecordConverter(schema));

            for (int i = 0; i < rows; i++) {
                SimpleGroup simpleGroup = (SimpleGroup) recordReader.read();
                simpleGroups.add(simpleGroup);
            }
        }

(请注意,箭头是代码中抛出错误的行(167)
错误消息

org.apache.parquet.hadoop.BadConfigurationException: Class org.apache.parquet.hadoop.codec.SnappyCodec was not found
        at org.apache.parquet.hadoop.CodecFactory.getCodec(CodecFactory.java:243)
        at org.apache.parquet.hadoop.CodecFactory$HeapBytesDecompressor.<init>(CodecFactory.java:96)
        at org.apache.parquet.hadoop.CodecFactory.createDecompressor(CodecFactory.java:212)
        at org.apache.parquet.hadoop.CodecFactory.getDecompressor(CodecFactory.java:201)
        at org.apache.parquet.hadoop.CodecFactory.getDecompressor(CodecFactory.java:42)
        at org.apache.parquet.hadoop.ParquetFileReader$Chunk.readAllPages(ParquetFileReader.java:1519)
        at org.apache.parquet.hadoop.ParquetFileReader$Chunk.readAllPages(ParquetFileReader.java:1402)
        at org.apache.parquet.hadoop.ParquetFileReader.readChunkPages(ParquetFileReader.java:1023)
        at org.apache.parquet.hadoop.ParquetFileReader.readNextRowGroup(ParquetFileReader.java:928)
        at [myClassPath]([myClass].java:167)

依赖项

<groupId>org.apache.hadoop</groupId>
   <artifactId>hadoop-hdfs</artifactId>
   <version>3.1.1.3.1.4.0-315</version>
 </dependency>
 <dependency>
   <groupId>org.apache.hadoop</groupId>
   <artifactId>hadoop-common</artifactId>
   <version>3.1.1.3.1.4.0-315</version>
 </dependency>
 <dependency>
   <groupId>org.apache.spark</groupId>
   <artifactId>spark-launcher_2.12</artifactId>
   <version>3.0.0-preview2</version>
 </dependency>
 <dependency>
   <groupId>org.apache.parquet</groupId>
   <artifactId>parquet-avro</artifactId>
   <version>1.12.0</version>
 </dependency>

似乎在codecfactory类中找不到snappycodec类,但我查看了引用的库,发现该类就在那里:引用的库
codecfactory应该能够识别snappycodec类。有什么建议吗?谢谢

o2gm4chl

o2gm4chl1#

找到了解决办法。
所以问题是snappycodec类被我为应用程序配置的maven shade插件着色了。
在用maven打包jar、用winzip打开jar并检查打包jar的codec目录(在那里我发现sanppycodec.class不再存在)之后,我意识到了这一点。
解决方案是,我需要在maven shade插件的配置中添加以下过滤器:

<filter>
    <artifact>org.apache.parquet:parquet-hadoop</artifact>
    <includes>
          <include>**</include>
    </includes>
</filter>
<filter>
    <artifact>org.apache.parquet:parquet-column</artifact>
    <includes>
          <include>**</include>
    </includes>
</filter>
<filter>
    <artifact>org.apache.parquet:parquet-encoding</artifact>
    <includes>
          <include>**</include>
    </includes>
</filter>

基本上,maven shade对来自parquet hadoop工件的看似随机的类进行着色,因此通过添加 <include> filter,maven shade没有对其中的任何类进行着色处理,因此没有对其中的snappycodec.class文件进行着色处理。
这样做之后,我需要添加另外两个过滤器,因为通过使用 <include> 在parquet hadoop工件上添加一个标签,然后它将所有其他parquet-*工件排除在已编译jar之外。所以,我需要显式地告诉它包括parquet列和parquet编码,因为我的应用程序在这些工件中使用了一些其他类。
这种配置意味着maven着色器不会触及这三个工件,这意味着在编译时之前存在于这些工件中的任何类和每个类在用maven编译/打包它们之后都会保留在那里(因此,在运行时它们会在那里,而在编译前它们不会在那里,从而导致最初的错误)。令人惊叹的!

相关问题