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


這篇文章中,介紹了如何將Maven依賴的包一起打包進jar包。使用maven-assembly打成jar后,將這個jar提供給其他工程引用的時候,報出如下錯誤:

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目錄下,都有如下的內容:

image

image

可以看到,這兩個包的services目錄下都有,org.apache.hadoop.fs.FileSystem這個文件。使用Maven-assembly-plugin的時候,會將所有依賴的包unpack,然后在pack,這樣就會出現,同樣的文件被覆蓋的情況,我們看下打好的包中保留的是啥:

image

可以看到,maven-assembly-plugin(fatjar也是一樣的),將hadoop-common.jar中的services內容打進了最終的jar包中,而hadoop-hdfs.jar包中,services的內容被覆蓋了。由於我們的函數調用是這樣寫的:

 

image  image

 

在函數中使用了hdfs://IP : port的schema,而在生成的最終jar包中,無法找到這個schema的實現。所以就拋出了

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

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

 

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

image

 

然后在重新打包,一切works ok了。

 

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

image

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

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

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM