IOException: No FileSystem for scheme: hdfs

java.io.IOException: No FileSystem for scheme: hdfs

 

這篇文章中,介紹瞭如何將Maven依賴的包一塊兒打包進jar包。使用maven-assembly打成jar後,將這個jar提供給其餘工程引用的時候,報出以下錯誤:html

log4j:WARN No appenders could be found for logger (org.apache.hadoop.metrics2.lib.MutableMetricsFactory).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
Exception in thread "main" java.io.IOException: No FileSystem for scheme: hdfs
     at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2421)
     at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2428)
     at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:88)
     at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2467)
     at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2449)
     at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:367)
     at org.apache.hadoop.fs.FileSystem$1.run(FileSystem.java:156)
     at org.apache.hadoop.fs.FileSystem$1.run(FileSystem.java:153)
     at java.security.AccessController.doPrivileged(Native Method)
     at javax.security.auth.Subject.doAs(Subject.java:422)
     at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1491)
     at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:153)
     at com.cetc.di.HDFSFileSystem.<init>(HDFSFileSystem.java:41)
     at callhdfs.Main.main(Main.java:11)

可是,在沒有打成jar包的工程中,是能夠正常運行的,經過長時間的觀察和分析,發現與hadoop filesystem相關的包有兩個,分別是:hadoop-hdfs-2.7.1.jar和hadoop-common-2.7.1.jar,這兩個包的META-INF中的services目錄下,都有以下的內容:java

image

image

能夠看到,這兩個包的services目錄下都有,org.apache.hadoop.fs.FileSystem這個文件。使用Maven-assembly-plugin的時候,會將全部依賴的包unpack,而後在pack,這樣就會出現,一樣的文件被覆蓋的狀況,咱們看下打好的包中保留的是啥:apache

image

能夠看到,maven-assembly-plugin(fatjar也是同樣的),將hadoop-common.jar中的services內容打進了最終的jar包中,而hadoop-hdfs.jar包中,services的內容被覆蓋了。因爲咱們的函數調用是這樣寫的:api

 

image  image

在函數中使用了hdfs://IP : port的schema,而在生成的最終jar包中,沒法找到這個schema的實現。因此就拋出了服務器

java.io.IOException: No FileSystem for scheme: hdfsoracle

解決方案是,在設置hadoop的配置的時候,顯示設置這個類:"org.apache.hadoop.hdfs.DistributedFileSystem:app

configuration.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");

image

而後在從新打包,一切works ok了。eclipse

 

jar包中META-INF中的services文件下的內容,牽涉到servicelocator的概念:maven

image

詳細的介紹,看java官方文檔:http://docs.oracle.com/javase/7/docs/api/java/util/ServiceLoader.htmlide

查看這篇文章,能夠知道servicelocator具體是如何運做的http://www.concretepage.com/java/serviceloader-java-example 

最近幾個項目模塊要從hadoop1升級到hadoop2,不過在修改的過程當中出現了一些問題,其中一個問題就是在使用 FileSystem fs = FileSystem.get(conf);調用hdfs時報錯,具體報錯信息以下:

        查看FileSystem類發現經過FileSystem.get()初始化的時候,須要經過靜態加載的方式來實現,具體實現以下:

        從代碼中能夠看出最終須要調用getFileSystemClass(String scheme, Configuration conf)方法,在此方法中須要讀取core-default.xml文件中定義的「fs.」 + scheme + ".impl"(在本例中應讀取fs.hdfs.impl)的配置信息,但此配置信息在默認的配置文件中沒有配置(Hadoop-common-x.jar中的core-default.xml文件中).

------------------------------------------

解決辦法:

在配置文件core-default.xml中添加以下配置信息:

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

程序打成jar包後,放到服務器上去執行,程序可以按預期去正確執行,但看到以下錯誤仍是很不爽: 

Java代碼  

2014-08-13 17:16:49 [WARN]-[main]-[org.apache.hadoop.hbase.util.DynamicClassLoader] Failed to identify the fs of dir /tmp/hbase-ecm2/hbase/lib, ignored  
java.io.IOException: No FileSystem for scheme: file  
    at org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2385) ~[ecm.jar:na]  
    at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2392) ~[ecm.jar:na]  
    at org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:89) ~[ecm.jar:na]  
    at org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2431) ~[ecm.jar:na]  
    at org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2413) ~[ecm.jar:na]  
    at org.apache.hadoop.fs.FileSystem.get(FileSystem.java:368) ~[ecm.jar:na]  


        【問題分析:】 
        eclipse打包完成後,jar包中core-site.xml配置文件中不存在如下兩個配置項。 

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

        只要將上面兩個配置加到core-site.xml中,而後替換jar包中的xml,從新扔到服務器上,就能夠成功運行了。

相關文章
相關標籤/搜索