我正试图使用 hadoop 运行一个简单的 "NaiveBayesClassifer",结果出现以下错误
Exception in thread "main" java.io.IOException: No FileSystem for scheme: file
at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:1375)
at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:66)
at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:1390)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:196)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:95)
at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:180)
at org.apache.hadoop.fs.Path.getFileSystem(Path.java:175)
at org.apache.mahout.classifier.naivebayes.NaiveBayesModel.materialize(NaiveBayesModel.java:100)
代码 :
Configuration configuration = new Configuration();
NaiveBayesModel model = NaiveBayesModel.materialize(new Path(modelPath), configuration);// error in this line..
modelPath "指向 "NaiveBayes.bin "文件,配置对象正在打印--"Configuration: core-default.xml, core-site.xml
我想这是因为 jars 的缘故,有什么办法吗?
这是 maven-assembly
插件破坏工作的典型案例。
不同的 JAR("hadoop-commons "用于 "本地文件系统","hadoop-hdfs "用于 "分布式文件系统")都在其 "META-INFO/services "目录中包含一个名为 "org.apache.hadoop.fs.FileSystem "的不同文件。该文件列出了它们要声明的文件系统实现的规范类名(这称为通过 java.util.ServiceLoader
实现的服务提供者接口,参见 org.apache.hadoop.FileSystem
第 2622 行)。
当我们使用 maven-assembly-plugin
时,它会将我们所有的 JAR 合并为一个,并且所有的 META-INFO/services/org.apache.hadoop.fs.FileSystem
都会相互覆盖。这些文件只剩下一个(最后添加的那个)。在这种情况下,来自 hadoop-commons
的 FileSystem
列表覆盖了来自 hadoop-hdfs
的列表,因此不再声明 DistributedFileSystem
。
在加载 Hadoop 配置后,但就在执行任何与 FileSystem
相关的操作之前,我们调用以下命令:
hadoopConfig.set("fs.hdfs.impl",
org.apache.hadoop.hdfs.DistributedFileSystem.class.getName()
);
hadoopConfig.set("fs.file.impl",
org.apache.hadoop.fs.LocalFileSystem.class.getName()
);
krookedking "告诉我,有一种基于配置的方法可以让 "maven-assembly "使用所有 "FileSystem "服务声明的合并版本,请查看下面的他的回答。
假设您使用的是 mvn 和 hadoop 的 cloudera 发行版。我使用的是 cdh4.6,添加这些依赖对我来说很有效。我认为您应该检查一下 hadoop 和 mvn 依赖的版本。
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-core</artifactId>
<version>2.0.0-mr1-cdh4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.0.0-cdh4.6.0</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.0.0-cdh4.6.0</version>
</dependency>
别忘了添加 cloudera mvn 仓库。
<repository>
<id>cloudera</id>
<url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
</repository>
我猜你是用 maven 构建样本的。
请检查您要运行的 JAR 的内容。特别是 META-INFO/services
目录中的文件 org.apache.hadoop.fs.FileSystem
。那里应该有文件系统实现类的列表。检查行 org.apache.hadoop.hdfs.DistributedFileSystem
是否出现在 HDFS 的列表中,以及 org.apache.hadoop.fs.LocalFileSystem
是否出现在本地文件方案的列表中。
如果是这种情况,您必须在构建过程中覆盖引用的资源。
另一种可能是你的类路径中没有 hadoop-hdfs.jar
,但这种可能性很低。通常情况下,如果你有正确的 hadoop-client
依赖关系,就不会出现这种情况。