我正在尝试NaiveBayesClassifer使用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
modelPath
NaiveBayes.bin
Configuration: core-default.xml, core-site.xml
这是maven-assembly插件破坏事情的典型情况。
maven-assembly
为什么这发生在我们身上 不同的JAR(hadoop-commonsfor LocalFileSystem,hadoop-hdfsfor DistributedFileSystem)各自org.apache.hadoop.fs.FileSystem在其META-INFO/services目录中包含一个不同的文件。该文件列出了要声明的文件系统实现的规范类名(这称为通过实现的服务提供者接口java.util.ServiceLoader,请参见org.apache.hadoop.FileSystem#loadFileSystems)。
hadoop-commonsfor LocalFileSystem,hadoop-hdfsfor DistributedFileSystem
org.apache.hadoop.fs.FileSystem在其META-INFO/services
java.util.ServiceLoader
org.apache.hadoop.FileSystem#loadFileSystems
当使用时maven-assembly-plugin,它将所有的JAR合并为一个,并且全部META-INFO/services/org.apache.hadoop.fs.FileSystem覆盖彼此。这些文件仅保留其中一个(添加的最后一个)。在这种情况下,FileSystemfrom 的列表将hadoop-commons覆盖from 的列表hadoop-hdfs,因此DistributedFileSystem不再声明。
maven-assembly-plugin
META-INFO/services/org.apache.hadoop.fs.FileSystem
FileSystemfrom
hadoop-commons
hadoop-hdfs
DistributedFileSystem
我们如何解决它
在加载Hadoop配置之后,但在进行任何FileSystem相关操作之前,我们将其称为:
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服务声明的合并版本