????在bin目录下打印系统版本信息。
执行命令 |
结果 |
hadoop?version |
|
结果显示,当前的hadoop版本为1.0.0。
接下来就一步步地跟踪代码,详细了解一下版本显示的实现逻辑。
首先打开hadoop脚本(目录${HADOOP_HOME}/BIN),查看脚本接收到命令version后调用哪个类来处理。相关脚本如下:
...?... elif?[?"$COMMAND"?=?"version"?]?;?then ??CLASS=org.apache.hadoop.util.VersionInfo ??HADOOP_OPTS="$HADOOP_OPTS?$HADOOP_CLIENT_OPTS" ...?... |
从上表可知,脚本接收到version命令后,对应的执行类是org.apache.hadoop.util.VersionInfo。
运行时,对应的执行类VersionInfo在main中直接打印消息。相关代码如下:
/** ?*?This?class?finds?the?package?info?for?Hadoop?and?the?HadoopVersionAnnotation ?*?information. ?*/ public?class?VersionInfo?{ ??private?static?Package?myPackage; ??private?static?HadoopVersionAnnotation?version; ??static?{ ????myPackage?=?HadoopVersionAnnotation.class.getPackage(); ????version?=?myPackage.getAnnotation(HadoopVersionAnnotation.class); ??} ??...?... ??/** ???*?获取了HadoopVersionAnnotation实例的version()方法的返回值。 ???*?@return?the?Hadoop?version?string,?eg.?"0.6.3-dev" ???*/ ??public?static?String?getVersion()?{ ????return?version?!=?null???version.version()?:?"Unknown"; ??} ?? ??/** ???*?Get?the?subversion?revision?number?for?the?root?directory ???*?@return?the?revision?number,?eg.?"451451" ???*/ ??public?static?String?getRevision()?{ ????return?version?!=?null???version.revision()?:?"Unknown"; ??} ?? ??/** ???*?获取了HadoopVersionAnnotation实例的date()方法的返回值。 ???*?@return?the?compilation?date?in?unix?date?format ???*/ ??public?static?String?getDate()?{ ????return?version?!=?null???version.date()?:?"Unknown"; ??} ?? ??/** ???*?获取了HadoopVersionAnnotation实例的user()方法的返回值。 ???*?@return?the?username?of?the?user ???*/ ??public?static?String?getUser()?{ ????return?version?!=?null???version.user()?:?"Unknown"; ??} ?? ??/** ???*?Get?the?subversion?URL?for?the?root?Hadoop?directory. ???*/ ??public?static?String?getUrl()?{ ????return?version?!=?null???version.url()?:?"Unknown"; ??} ??...?... ??public?static?void?main(String[]?args)?{ ????System.out.println("Hadoop?"?+?getVersion()); ????System.out.println("Subversion?"?+?getUrl()?+?"?-r?"?+?getRevision()); ????System.out.println("Compiled?by?"?+?getUser()?+?"?on?"?+?getDate()); ??} } |
定义了静态变量:myPackeage和version。其中version是HadoopVersionAnnotation的实例。?HadoopVersionAnnotation是Annotation接口类,在这里,hadoop项目组通过这种方式来获取系统版本信息。并不是直接写在代码中。
这个类是个比较普通的类,但是管理了Hadoop的版本信息,包括用户、编译时间、版本信息等内容。在这个类中,封装了HadoopVersionAnnotation这个注释类。
相关代码如下:
/** ?*?A?package?attribute?that?captures?the?version?of?Hadoop?that?was?compiled. ?*/ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PACKAGE)//是对包的注释,很多地方都是用 public?@interface?HadoopVersionAnnotation?{ ? ??/** ???*?Get?the?Hadoop?version ???*?@return?the?version?string?"0.6.3-dev" ???*/ ??String?version(); ?? ??/** ???*?Get?the?username?that?compiled?Hadoop. ???*/ ??String?user(); ?? ??/** ???*?Get?the?date?when?Hadoop?was?compiled. ???*?@return?the?date?in?unix?‘date‘?format ???*/ ??String?date(); ?? ??/** ???*?Get?the?url?for?the?subversion?repository. ???*/ ??String?url(); ?? ??/** ???*?Get?the?subversion?revision. ???*?@return?the?revision?number?as?a?string?(eg.?"451451") ???*/ ??String?revision(); } |
????这只是个接口类,但是纵观整个项目工程,并没有找到实现类;查看整个项目的源码,也没有找到初始化的地方。
????根据JDK语法,如果类型设置为PACKAGE,则需要在这个Annotation所在的包中,有一个package-info.java类,并且定义如下:
@HadoopVersionAnnotation(version="1.0.0-SNAPSHOT")
package?org.apache.hadoop;
????这样,在调用HadoopVersionAnnotation的version()方法时,才可以得到在package-info.java中对该方法的返回值。
????下面,就要介绍这个package-info.java是怎么来的了。
?????查看编译后生成的hadoop-core-1.0.0.jar包,是可以看到package-info.class类的,相关信息如下:
|
由此可以推测,package-info类应该是在项目工程编译过程中生成的,接下来看一下build.xml文件,虽然没有package-info字眼,但确看到了version字眼,而且执行该脚本是在init目标下。如下所示:
??<!--?======================================================?--> ??<!--?Stuff?needed?by?all?targets????????????????????????????--> ??<!--?======================================================?--> <target?name="init"?depends="ivy-retrieve-common"> ...?... <exec?executable="sh"> ???<arg?line="src/saveVersion.sh?${version}?${build.dir}"/> </exec> ...?... </target> |
????接下来将目光转移到saveVersion.sh脚本。
????打开脚本saveVersion.sh,终于发现生成package-info.java类的源码了。相关脚本如下:
...?... mkdir?-p?$build_dir/src/org/apache/hadoop cat?<<?EOF?|?\ ??sed?-e?"s/VERSION/$version/"?-e?"s/USER/$user/"?-e?"s/DATE/$date/"?\ ??????-e?"s|URL|$url|"?-e?"s/REV/$revision/"?\ ??????>?$build_dir/src/org/apache/hadoop/package-info.java /* ?*?Generated?by?src/saveVersion.sh ?*/ @HadoopVersionAnnotation(version="VERSION",?revision="REV",? ?????????????????????????user="USER",?date="DATE",?url="URL") package?org.apache.hadoop; EOF |
打开hadoop编译时创建的目录,确实找到了package-info.java类,如下所示:
|
再打开package-info.java类,文件内容正是我们所期待的。如下所示:
/* ?*?Generated?by?src/saveVersion.sh ?*/ @HadoopVersionAnnotation(version="1.0.0",?revision="",? ?????????????????????????user="e40-nb2-pcmyuser",?date="Mon?Nov?17?14:40:26?????2014",?url="") package?org.apache.hadoop; |
?
?
原文:http://seandeng888.iteye.com/blog/2164141