【问题标题】:hadoop No FileSystem for scheme: filehadoop 没有用于方案的文件系统:文件
【发布时间】:2013-06-20 08:11:58
【问题描述】:

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

我认为是因为罐子,有什么想法吗?

【问题讨论】:

  • 需要更多信息...
  • 不认识自己,但在 google 上的快速浏览表明存在一些未按照您的建议引用的罐子的问题。也许以下链接会产生答案。 groups.google.com/a/cloudera.org/forum/#!topic/scm-users/…grokbase.com/t/cloudera/cdh-user/134r64jm5t/…
  • 我正在将 hadoop-common-2.0.0-cdh4.3.0-sources.jar 和 hadoop-core-0.20.2.jar 添加到类路径中,我先删除了它,它工作不知道为什么。
  • 嗯..你能告诉我你的环境吗?另外,请给我看完整的异常信息。
  • modelPath 的值是多少?你试过file:///path/to/dir

标签: java hadoop io


【解决方案1】:

如果您使用的是 Gradle Shadow 插件,那么这是您必须添加的配置:

shadowJar {
    mergeServiceFiles()
}

【讨论】:

  • 为我工作,谢谢您的评论
【解决方案2】:

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

在我这边,根本原因是 hdfs 在路径开头遇到// 时试图解析权威:

$ hdfs dfs -ls //dev
ls: No FileSystem for scheme: null

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

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

【讨论】:

    【解决方案3】:

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

    为什么这会发生在我们身上

    不同的 JAR(hadoop-commons 用于 LocalFileSystemhadoop-hdfs 用于 DistributedFileSystem)每个都在其 META-INFO/services 目录中包含一个名为 org.apache.hadoop.fs.FileSystem 的不同文件。该文件列出了他们想要声明的文件系统实现的规范类名(这称为通过java.util.ServiceLoader 实现的服务提供者接口,参见org.apache.hadoop.FileSystem#loadFileSystems)。

    当我们使用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 服务声明的合并版本,请查看下面的his answer

    【讨论】:

    • 这是在 Spark 中执行相同操作所需的等效代码:val hadoopConfig: Configuration = spark.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)
    • 其实我只是将这个maven依赖http://mvnrepository.com/artifact/org.apache.hadoop/hadoop-hdfs/2.2.0添加到maven中,问题就解决了。
    • 我尝试添加 hadoop-hdfs、hadoop-core、hadoop-common、hadoop-client,Aslo 尝试添加 hadoopConfig.set("fs.hdfs.impl", org.apache.hadoop.hdfs .DistributedFileSystem.class.getName()); hadoopConfig.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName() );但不工作,从 eclipse 运行时运行正常,但从 java -cp 命令运行时显示上述错误
    • Harish,你看到了什么?这里有同样的问题,但是 intellij
    • 只是对精彩答案的补充:如果有人使用 hadoop JARS 但在非 hadoop 集群中运行作业,则 """hadoopConfig.set("fs.hdfs.impl... .."""" 将不起作用。在这种情况下,我们将依靠管理程序集构建。例如,在 sbt 中,我们可以执行 concat 甚至 filterDistinctLines 的 mergeStrategy
    【解决方案4】:

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

    对于使用 Flink 的人,需要下载Pre-bundled Hadoop 并放入/opt/flink/lib

    【讨论】:

      【解决方案5】:

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

      使用 WinRar(或类似工具)打开 jar 文件。转到 Meta-info > services ,并通过追加编辑“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>
      

      【讨论】:

        【解决方案6】:

        对于 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)
          }
        }
        

        【讨论】:

          【解决方案7】:

          我也遇到过类似的问题。 添加 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 文件中,依赖项的版本为 2.7.1,则将其更改为 2.8.1) 再次运行 Maven 安装。

          这为我解决了错误。

          【讨论】:

            【解决方案8】:
            Configuration conf = new Configuration();
            conf.set("fs.defaultFS", "hdfs://nameNode:9000");
            FileSystem fs = FileSystem.get(conf);
            

            set fs.defaultFS 对我有用! Hadoop-2.8.1

            【讨论】:

              【解决方案9】:

              如果您使用的是 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
              )
              

              【讨论】:

                【解决方案10】:

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

                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)
                

                我使用的是 Spark 2.1

                我的build.sbt中有这部分

                assemblyMergeStrategy in assembly := {
                  case PathList("META-INF", xs @ _*) => MergeStrategy.discard
                  case x => MergeStrategy.first
                }
                

                【讨论】:

                  【解决方案11】:

                  我花了很长时间才用 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"
                  

                  希望对你有帮助!

                  【讨论】:

                    【解决方案12】:

                    另一个可能的原因(尽管 OPs 问题本身并没有受到此影响)是如果您创建了一个不加载默认值的配置实例:

                    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()));
                    

                    【讨论】:

                      【解决方案13】:

                      使用这个插件

                      <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>
                      

                      【讨论】:

                        【解决方案14】:

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

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

                        【讨论】:

                          【解决方案15】:

                          对于那些使用 shade 插件的人,按照 david_p 的建议,您可以通过将 ServicesResourceTransformer 添加到插件配置中来合并 shaded 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 服务合并到一个文件中

                          【讨论】:

                          • 我最喜欢这个解决方案。从源头(构建)修复问题,而不是事后通过配置更改修补它。
                          • 很好的答案。修复了我的类似错误。尝试使用 maven-assembly-plugin 以及 maven-jar-plugin/maven-dependency-plugin 组合,但没有奏效。这个解决方案使我的 Spark 应用程序正常工作。非常感谢!
                          • 很好的答案!非常感谢!
                          • 这应该被标记为接受的答案。当 jar 文件使用 META-INF/services 目录将接口映射到实现时,ServicesResourceTransformer 是必需的。更多信息可以在这里找到:maven.apache.org/plugins/maven-shade-plugin/examples/…
                          • 优秀的答案。
                          【解决方案16】:

                          感谢 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>
                          

                          【讨论】:

                          【解决方案17】:

                          为了记录,这仍然发生在 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>
                          

                          【讨论】:

                            【解决方案18】:

                            我使用 sbt 程序集来打包我的项目。我也遇到这个问题。我的解决方案在这里。 Step1:在你的 build.sbt 中添加 META-INF 合并策略

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

                            Step2:将 hadoop-hdfs lib 添加到 build.sbt

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

                            第三步:sbt clean; sbt 汇编

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

                            【讨论】:

                            • 更好的解决方案可能是合并:case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") =&gt; MergeStrategy.filterDistinctLines 这将保留所有已注册的文件系统
                            • 感谢@ravwojdyla,非常简洁的解决方案。你救了我的头发。对于为 Apache spark 发现这个答案的迷失灵魂。当 sbt-assembly 正常工作时,将此添加到 build.sbt。
                            • @ravwojdyla 提供的解决方案是唯一对我有用的解决方案。
                            • @ravwojdyla 给出的解决方案是理想的。我在 build.sbt 中做了类似的设置并使用了: ``` assemblyMergeStrategy in assembly := { case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard case PathList("META-INF", "services", "org.apache.hadoop.fs.FileSystem") => MergeStrategy.concat case _ => MergeStrategy.first } ```
                            【解决方案19】:

                            假设您正在使用 mvn 和 cloudera 分发的 hadoop。我正在使用 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>
                            

                            【讨论】:

                              【解决方案20】:

                              我假设您使用 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 依赖项,则它不是一个选项。

                              【讨论】:

                              • 嗨 Roman ..我有同样的问题,META-INFO/services/org.apache.hadoop.fs.FileSystem 没有 hdfs 行。我有 2.0.0-mr1-cdh4。 4.0 作为唯一的依赖。我需要做什么?有关于此的任何文档?使用 Maven 构建
                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 2021-05-25
                              • 2018-02-11
                              • 1970-01-01
                              • 1970-01-01
                              • 2023-03-16
                              • 1970-01-01
                              • 2021-12-12
                              相关资源
                              最近更新 更多