參考博文: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等里面取。關鍵代碼為:
- if (!isSecurityEnabled() && (user == null)) {
- String envUser = System.getenv(HADOOP_USER_NAME);
- if (envUser == null) {
- envUser = System.getProperty(HADOOP_USER_NAME);
- }
- user = envUser == null ? null : new User(envUser);
- }
OK,看到這里我的需求也就解決了,只要在系統的環境變量里面添加HADOOP_USER_NAME=hadoop(HDFS上的有權限的用戶,具體看自己的情況),或者在當前JDK的變量參數里面添加HADOOP_USER_NAME這個Java變量即可。我的情況添加系統環境變量更方法。
如果是在Eclipse里面運行,修改完環境變量后,記得重啟一下eclipse,不然可能不會生效。
