hadoop No FileSystem for scheme:file

时间:2013-06-23 20:27:58

标签: java hadoop io

我正在尝试使用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

我认为这是因为罐子,任何想法?

19 个答案:

答案 0 :(得分:153)

这是maven-assembly插件破坏事物的典型案例。

为什么这发生在我们身上

不同的JAR(hadoop-commonsLocalFileSystemhadoop-hdfsDistributedFileSystem),每个JAR在org.apache.hadoop.fs.FileSystem目录中都包含一个名为META-INFO/services的文件。此文件列出了他们要声明的文件系统实现的规范类名(这称为通过java.util.ServiceLoader实现的服务提供者接口,请参阅org.apache.hadoop.FileSystem line 2622)。

当我们使用maven-assembly-plugin时,它会将我们所有的JAR合并为一个,并且所有META-INFO/services/org.apache.hadoop.fs.FileSystem都会相互覆盖。只剩下其中一个文件(最后添加的文件)。在这种情况下,FileSystem中的hadoop-commons列表会覆盖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服务声明的合并版本。 将以下插件添加到pom.xml文件中:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>2.3</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>

答案 1 :(得分:53)

对于那些使用shade插件的人,按照david_p的建议,你可以通过将ServicesResourceTransformer添加到插件配置来合并阴影jar中的服务:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.3</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>

这会将所有org.apache.hadoop.fs.FileSystem服务合并到一个文件中

答案 2 :(得分:8)

为了记录,这仍然发生在hadoop 2.4.0中。太令人沮丧......

我能够按照此链接中的说明操作:http://grokbase.com/t/cloudera/scm-users/1288xszz7r/no-filesystem-for-scheme-hdfs

我将以下内容添加到我的core-site.xml中并且工作正常:

<property>
   <name>fs.file.impl</name>
   <value>org.apache.hadoop.fs.LocalFileSystem</value>
   <description>The FileSystem for file: uris.</description>
</property>

<property>
   <name>fs.hdfs.impl</name>
   <value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
   <description>The FileSystem for hdfs: uris.</description>
</property>

答案 3 :(得分:7)

感谢david_p,scala

conf.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName);
conf.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName);

<property>
 <name>fs.hdfs.impl</name>
 <value>org.apache.hadoop.hdfs.DistributedFileSystem</value>
</property>

答案 4 :(得分:7)

花了我很多时间用Spark 2.0.2来解决这个问题,但是我的意思是:

val sparkBuilder = SparkSession.builder
.appName("app_name")
.master("local")
// Various Params
.getOrCreate()

val hadoopConfig: Configuration = sparkBuilder.sparkContext.hadoopConfiguration

hadoopConfig.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName)

hadoopConfig.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName)

build.sbt的相关部分:

scalaVersion := "2.11.8"
libraryDependencies += "org.apache.spark" %% "spark-core" % "2.0.2"

我希望这可以提供帮助!

答案 5 :(得分:5)

对于maven,只需为hadoop-hdfs添加maven依赖(请参阅下面的链接)即可解决问题。

http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.7.1

答案 6 :(得分:4)

假设你正在使用hadoop的mvn和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>

答案 7 :(得分:4)

我使用sbt程序集打包我的项目。我也遇到了这个问题。我的解决方案在这里。 第1步:在build.sbt中添加META-INF mergestrategy

case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", ps @ _*) => MergeStrategy.first

步骤2:将hadoop-hdfs lib添加到build.sbt

"org.apache.hadoop" % "hadoop-hdfs" % "2.4.0"

Step3:sbt clean;集会

希望以上信息对您有所帮助。

答案 8 :(得分:2)

另一个可能的原因(虽然OP问题本身不会受此影响)是你创建了一个不加载默认值的配置实例:

Configuration config = new Configuration(false);

如果您没有加载默认值,那么您将无法获得FileSystem实现之类的默认设置,这些设置会在尝试访问HDFS时导致相同的错误。切换到传递true以加载默认值的无参数构造函数可以解决此问题。

此外,如果要将自定义配置位置(例如,在文件系统上)添加到Configuration对象,请注意您使用的addResource()过载。例如,如果您使用addResource(String),则Hadoop会假定该字符串是类路径资源,如果您需要指定本地文件,请尝试以下操作:

File configFile = new File("example/config.xml");
config.addResource(new Path("file://" + configFile.getAbsolutePath()));

答案 9 :(得分:2)

我假设你使用maven构建样本。

请检查您尝试运行的JAR的内容。特别是META-INFO/services目录,文件org.apache.hadoop.fs.FileSystem。应该有filsystem实现类列表。检查行org.apache.hadoop.hdfs.DistributedFileSystem出现在HDFS列表中,org.apache.hadoop.fs.LocalFileSystem出现在本地文件方案中。

如果是这种情况,则必须在构建期间覆盖引用的资源。

其他可能性是你的类路径中没有hadoop-hdfs.jar,但这种可能性很小。通常,如果您具有正确的hadoop-client依赖性,那么它就不是一种选择。

答案 10 :(得分:1)

由于我的新手,我花了一些时间从给定的答案中找出解决方法。这就是我提出的,如果其他人从一开始就需要帮助的话:

free(a);

我正在使用Spark 2.1

我在import org.apache.spark.SparkContext import org.apache.spark.SparkConf object MyObject { def main(args: Array[String]): Unit = { val mySparkConf = new SparkConf().setAppName("SparkApp").setMaster("local[*]").set("spark.executor.memory","5g"); val sc = new SparkContext(mySparkConf) val conf = sc.hadoopConfiguration conf.set("fs.hdfs.impl", classOf[org.apache.hadoop.hdfs.DistributedFileSystem].getName) conf.set("fs.file.impl", classOf[org.apache.hadoop.fs.LocalFileSystem].getName)

中有这个部分
build.sbt

答案 11 :(得分:1)

Configuration conf = new Configuration();
conf.set("fs.defaultFS", "hdfs://nameNode:9000");
FileSystem fs = FileSystem.get(conf);

设置fs.defaultFS适合我! Hadoop的2.8.1

答案 12 :(得分:1)

对于SBT,请使用build.sbt中的mergeStrategy

mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) => {
    case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.filterDistinctLines
    case s => old(s)
  }
}

答案 13 :(得分:1)

这个问题很老了,但我最近遇到了同样的问题,错误的根源与这里的答案不同。

在我看来,根本原因是由于 hdfs 在路径开头遇到 var result = createStringXY(7) var [long, lat] = result.split(",") // Or doing it in one line // var [long, lat] = createStringXY(7).split(",") 时试图解析权威:

//

因此,请尝试在代码的路径构建部分中查找双斜杠或空变量。

相关 Hadoop 票证:https://issues.apache.org/jira/browse/HADOOP-8087

答案 14 :(得分:0)

如果您使用 sbt

//hadoop
lazy val HADOOP_VERSION = "2.8.0"

lazy val dependenceList = Seq(

//hadoop
//The order is important: "hadoop-hdfs" and then "hadoop-common"
"org.apache.hadoop" % "hadoop-hdfs" % HADOOP_VERSION

,"org.apache.hadoop" % "hadoop-common" % HADOOP_VERSION
)

答案 15 :(得分:0)

我遇到了同样的问题。我发现了两种解决方案: (1)手动编辑jar文件:

使用WinRar(或类似工具)打开jar文件。转到元信息>服务,然后通过添加以下内容来编辑“ org.apache.hadoop.fs.FileSystem”:

org.apache.hadoop.fs.LocalFileSystem

(2)如下更改依存关系的顺序

<dependencies>
<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-hdfs</artifactId>
  <version>3.2.1</version>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-common</artifactId>
  <version>3.2.1</version>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-mapreduce-client-core</artifactId>
  <version>3.2.1</version>
</dependency>

<dependency>
  <groupId>org.apache.hadoop</groupId>
  <artifactId>hadoop-client</artifactId>
  <version>3.2.1</version>
</dependency>



</dependencies>

答案 16 :(得分:0)

这与Flink无关,但是我也在Flink中发现了这个问题。

对于使用Flink的用户,您需要下载Pre-bundled Hadoop并将其放入/opt/flink/lib中。

答案 17 :(得分:-1)

使用此插件

<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>1.5</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>

                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <shadedClassifierName>allinone</shadedClassifierName>
                            <artifactSet>
                                <includes>
                                    <include>*:*</include>
                                </includes>
                            </artifactSet>
                            <transformers>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
                                    <resource>reference.conf</resource>
                                </transformer>
                                <transformer
                                    implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                </transformer>
                                <transformer 
                                implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

答案 18 :(得分:-1)

我也遇到过类似的问题。 添加了core-site.xml和hdfs-site.xml作为conf(object)的资源

Configuration conf = new Configuration(true);    
conf.addResource(new Path("<path to>/core-site.xml"));
conf.addResource(new Path("<path to>/hdfs-site.xml"));

pom.xml中也编辑了版本冲突。 (例如,如果已配置的hadoop版本为2.8.1,但在pom.xml文件中,dependancies的版本为2.7.1,则将其更改为2.8.1) 再次运行Maven安装。

这解决了我的错误。