Permission denied: user=administrator, access=WRITE, inode="/":root:supergroup:drwxr-xr-x


參考博文:http://blog.csdn.net/xiaoshunzi111/article/details/52062640

http://www.udpwork.com/item/7047.html

在此篇文章里面作者分析了hadoop的整個登錄過程,對於我有用的是其中的這一段:

2.login.login();
這個會調用HadoopLoginModule的login()和commit()方法。
HadoopLoginModule的login()方法是一個空函數,只打印了一行調試日志 LOG.debug("hadoop login");
commit()方法負責把Principal添加到Subject中。
此時一個首要問題是username是什么?
在使用了kerberos的情況下,從javax.security.auth.kerberos.KerberosPrincipal的實例獲取username。
在未使用kerberos的情況下,優先讀取HADOOP_USER_NAME這個系統環境變量,如果不為空,那么拿它作username。否則,讀取HADOOP_USER_NAME這個java環境變量。否則,從com.sun.security.auth.NTUserPrincipal或者com.sun.security.auth.UnixPrincipal的實例獲取username。
如果以上嘗試都失敗,那么拋出異常LoginException("Can’t find user name")。
最終拿username構造org.apache.hadoop.security.User的實例添加到Subject中。

看完這一段,我明白了執行login.login的時候調用了hadoop里面的HadoopLoginModule方法,而關鍵是在commit方法里面,在這里優先讀取HADOOP_USER_NAME系統環境變量,然后是java環境變量,如果再沒有就從NTUserPrincipal等里面取。關鍵代碼為:

  1. if (!isSecurityEnabled() && (user == null)) {
  2.   String envUser = System.getenv(HADOOP_USER_NAME);
  3.   if (envUser == null) {
  4.     envUser = System.getProperty(HADOOP_USER_NAME);
  5.   }
  6.   user = envUser == null ? null : new User(envUser);
  7. }

OK,看到這里我的需求也就解決了,只要在系統的環境變量里面添加HADOOP_USER_NAME=hadoop(HDFS上的有權限的用戶,具體看自己的情況),或者在當前JDK的變量參數里面添加HADOOP_USER_NAME這個Java變量即可。我的情況添加系統環境變量更方法。

如果是在Eclipse里面運行,修改完環境變量后,記得重啟一下eclipse,不然可能不會生效。


免責聲明!

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



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