2018.10.26
前言
某项目使用HDFS Java API操作HDFS,常用操作如put、getMerge等,但一旦涉及到本地文件系统和HDFS间的上传下载,就会报错,在StackOverflow上找到了解决方法1。
方法
这是一个典型的maven-assembly-plugin
所导致的问题。不同的Jar包中可能存在不同org.apache.hadoop.fs.FileSystem
抽象类的实现,如hadoop-commons包中LocalFileSystem
的祖先类和hadoop-hdfs包中DistributedFileSystem
的祖先类。当采用maven-assembly-plugin
时,包名类名相同的类就会出现相互覆盖,最终只保留一份实现,并打成一个Jar包。
方法一:配置类中指定实现类
在Hadoop的配置Configuration
中配置:
Configuration conf = new Configuration();
conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName());
conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName());
方法二:打成fat包
pom.xml中使用maven-shade-plugin
插件,将项目打成fat包:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${shadeVersion}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>