我正在尝试使用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
我认为这是因为罐子,任何想法?
答案 0 :(得分:153)
这是maven-assembly
插件破坏事物的典型案例。
不同的JAR(hadoop-commons
为LocalFileSystem
,hadoop-hdfs
为DistributedFileSystem
),每个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安装。
这解决了我的错误。