HADOOP中的VersionInfo类

这个类是个比较普通的类,但是管理了hadoop的版本信息,包括用户、编译时间、版本信息等内容。在这个类中,封装了HadoopVersionAnnotation这个注释类。由于个人觉得这个设置挺巧妙,值得学习,所以特别拿出来说明进行分享。

下面就VersionInfo的几个调用场景进行说明

(1)打印系统版本信息。运行hadoop VERSION时,对应的执行类即为VersionInfo在main中直接打印消息。

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());
    System.out.println("From source with checksum " + getSrcChecksum());
  }

(2)在namenode等后台进程启动时,会调用StringUtils.startupShutdownMessage(NameNode.class, argv, LOG);打印当前的进程和系统消息。

其中startupShutdownMessage打印进程启动或停止的消息日志。

当进程启动时:

LOG.info(
        toStartupShutdownString("STARTUP_MSG: ", new String[] {
            "Starting " + classname,  //打印类名
            "  host = " + hostname,   //机器名和IP地址
            "  args = " + Arrays.asList(args), //参数列表
            "  version = " + VersionInfo.getVersion(), //后面的都是从VersionInfo获取的系统信息。
            "  build = " + VersionInfo.getUrl() + " -r "  
                         + VersionInfo.getRevision() 
                         + "; compiled by '" + VersionInfo.getUser()
                         + "' on " + VersionInfo.getDate()}
        )
      );

当进程停止时,执行run中的内容。可以搜索addShutdownHook,即可理解这部分代码。这个部分和VersionInfo无关,只是顺便说明。

Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
        LOG.info(toStartupShutdownString("SHUTDOWN_MSG: ", new String[]{
          "Shutting down " + classname + " at " + hostname}));
      }
    });

好了,到此为止,对VersionInfo的功能进行了介绍,下面介绍其工作的原理。

(3)VersionInfo的工作原理。

定义了静态变量:myPackeage和version。其中version是HadoopVersionAnnotation的实例。HadoopVersionAnnotation是Annotation接口类,在这里,hadoop项目组通过这种方式来获取系统版本信息。并不是直接写在代码中。后面会说到,这实际是从build过程就开始的工作。

private static Package myPackage;
  private static HadoopVersionAnnotation version;
  
  static {
    myPackage = HadoopVersionAnnotation.class.getPackage();
    version = myPackage.getAnnotation(HadoopVersionAnnotation.class);
  }


  /**
   * Get the meta-data for the Hadoop package.
   * @return
   */
  static Package getPackage() {
    return myPackage;
  }
  
  /**
   * Get the Hadoop version.
   * @return the Hadoop version string, eg. "0.6.3-dev"
   */

//代码较多,这里就取getVersion()方法来说明,实际是获取了HadoopVersionAnnotation实例的version()方法的返回值。
  public static String getVersion() {
    return version != null ? version.version() : "Unknown";
  }

}

(4)话不多说,介绍HadoopVersionAnnotation类

package org.apache.hadoop;
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PACKAGE) //是对包的注释,很多地方都是用ElementType.METHOD类型来对方法进行定义,但是这里用PACKAGE类型。
public @interface HadoopVersionAnnotation {
 
  /**
   * Get the Hadoop version
   * @return the version string "0.6.3-dev"
   */
  String version(); //这个version()方法就是上面VersionInfo中getVersion()方法中调用的方法。

}

但是纵观全类,这只是个接口类,并没有实现。查看整个项目的源码,也没有找到初始化的地方。

因为之前不了解Annotation是什么,自己也是查的百度,才大概理解,就不在这里介绍了,不了解的朋友可自行百度或谷歌。

总之,如果类型设置为PACKAGE,则需要在这个Annotation所在的包中,有一个package-info.java类,并且定义如下:

@HadoopVersionAnnotation(version="1.0.4-SNAPSHOT")

package org.apache.hadoop;

这样,在调用HadoopVersionAnnotation的version()方法时,就可以得到在package-info.java中对该方法的返回值的定义了。

(5)下面,就要介绍这个package-info.java是怎么来的了。

比如build date,或者user这样的参数,不可能事先人为的写在package-info.java文件中的,而且查看源码,其实这个文件本来是没有的~

下面贴出package-info.java文件的源码,可以发现,原来这个文件是由src目录下的saveVersion.sh文件生成的!

/*
 * Generated by src/saveVersion.sh
 */
@HadoopVersionAnnotation(version="1.0.4-SNAPSHOT", revision="", 
                         user=aperson", date="Tue Aug 21 01:28:38 PDT 2012", url="",
                         srcChecksum="ec890fc9af4c24bcba23ee1b2dca7857")
package org.apache.hadoop;

到这里为止,就对整个过程了解了。

下面就需要知道在什么地方调用了saveVersion.sh脚本,可以查看build.xml文件,发现有下面一句话:

<exec executable="sh">

       <arg line="src/saveVersion.sh ${version} ${build.dir}"/>

</exec>

到此为止,就了解了VersionInfo的整个工作过程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值