文章目录

  • 下载源码
  • 编译源码
  • 编译前奏
  • ant-ivy源码修改

下载源码

我们从 github 上下载 zookeeper 的源码,地址是

https://github.com/apache/zookeeper/archive/release-3.4.12.tar.gz

这里我们选择用 3.4.12 版本的源码作为学习。

编译源码

由于 zk 是 ant 编译环境的,所以这里我们需要先安装 ant 的环境,我本地目前的是1.10.1版本

## 下载 zk 源码包
wget https://github.com/apache/zookeeper/archive/release-3.4.12.tar.gz
## 解压目录
tar -xzvf zookeeper-3.4.12.tar.gz
## 进入到zk 目录
cd zookeeper-3.4.12
## 以 eclipse 方式编译源码,然后导入到 IDEA
ant eclipse

进行上面的命令后,我们就可以将编译好的源码直接导入到 IDEA 中,因为 IDEA 对 eclipse 的工程做了兼容,所以可以直接导入到 IDEA 中。

TIPS:由于默认使用的 maven 中心仓库下载 jar 包,速度会很慢,对于国内程序猿来说,简直要命。所以我们这里换成 aliyun 的 maven 地址。不过你能忍受或者速度很快的,下面的就可以直接忽略了。

编译前奏

我们修改zk 源码目录下的ivysettings.xml文件,添加阿里云的 maven 镜像地址。

<ivysettings>
    <!-- 加入阿里云镜像  -->
    <property name="repo.aliyun.org"
              value="https://maven.aliyun.com/repository/public" override="false"/>

    <property name="repo.maven.org"
              value="https://repo1.maven.org/maven2/" override="false"/>
    <property name="repo.jboss.org"
              value="https://repository.jboss.org/nexus/content/groups/public/" override="false"/>
    <property name="maven2.pattern"
              value="[organisation]/[module]/[revision]/[module]-[revision]"/>
    <property name="maven2.pattern.ext" value="${maven2.pattern}.[ext]"/>
    <include url="${ivy.default.conf.dir}/ivyconf-local.xml"/>
    <settings defaultResolver="default"/>
    <resolvers>
        <!-- 加入阿里云镜像  -->
        <ibiblio name="aliyun-maven2" root="${repo.aliyun.org}"
                 pattern="${maven2.pattern.ext}" m2compatible="true"/>

        <ibiblio name="maven2" root="${repo.maven.org}"
                 pattern="${maven2.pattern.ext}" m2compatible="true"/>
        <ibiblio name="jboss-maven2" root="${repo.jboss.org}"
                 pattern="${maven2.pattern.ext}" m2compatible="true"/>
        <chain name="default" dual="true">
            <!-- 加入阿里云镜像  -->
            <resolver ref="aliyun-maven2"/>
            <resolver ref="maven2"/>
            <resolver ref="jboss-maven2"/>
        </chain>
    </resolvers>
</ivysettings>

那么我们下面就愉快的去编译了,继续执行ant eclipse命令,发现并没有我们想象中的顺畅,这个时候发现出像下面的报错信息。

[ivy:retrieve]          [FAILED     ] log4j#log4j;1.2.17!log4j.jar(bundle): The HTTP response code for https://maven.aliyun.com/repository/central/log4j/log4j/1.2.17/log4j-1.2.17.jar did not indicate a success. See log for more detail. (559ms)

肿么回事!!!!心中是千万个草泥马奔腾而过,好不容易换成阿里云镜像,居然来这一出。

错误截图:

如何学习zookeeper源码 zookeeper源码视频_jar

预知后事如何,请看下一小节分析

ant-ivy源码修改

这个 ivy 就是 ant 的 jar 包依赖的工具,里面下载 jar 包默认是用的是 java 的 URLConnection 这个,这个访问阿里云的 maven 的资源的时候会进行 302 的重定向,这里我们就使出我们的绝招-修改源代码。

ant-ivy 源码下载链接是:https://github.com/apache/ant-ivy/archive/2.4.0.tar.gz,然后ant ecplise-default 编译后倒入到 idea 中。修改BasicURLHandler这个类。代码行数大概在200 行左右,方法是download(URL src, File dest, CopyProgressListener l)这个方法。

修改后的代码如下:

public void download(URL src, File dest, CopyProgressListener l) throws IOException {
  // Install the IvyAuthenticator
  if ("http".equals(src.getProtocol()) || "https".equals(src.getProtocol())) {
    IvyAuthenticator.install();
  }
  URLConnection srcConn = null;
  try {
    src = normalizeToURL(src);
    srcConn = src.openConnection();
    srcConn.setRequestProperty("User-Agent", getUserAgent());
    srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate");
    if (srcConn instanceof HttpURLConnection) {
      HttpURLConnection httpCon = (HttpURLConnection) srcConn;
      /** 修复阿里云的问题 */
      if (httpCon.getResponseCode() == 302 && src.getHost().contains("aliyun.com")) {
        // System.out.println("请求的 code 是" + httpCon.getResponseCode());
        // System.out.println("地址是:" + httpCon.getHeaderField("Location"));
        srcConn = new URL(httpCon.getHeaderField("Location")).openConnection();
        httpCon = (HttpURLConnection) srcConn;
      }
      if (!checkStatusCode(src, httpCon)) {
        throw new IOException("The HTTP response code for " + src
                              + " did not indicate a success." + " See log for more detail.");
      }
    }
    // do the download
    InputStream inStream = getDecodingInputStream(srcConn.getContentEncoding(),
                                                  srcConn.getInputStream());
    FileUtil.copy(inStream, dest, l);
    // check content length only if content was not encoded
    if (srcConn.getContentEncoding() == null) {
      int contentLength = srcConn.getContentLength();
      if (contentLength != -1 && dest.length() != contentLength) {
        dest.delete();
        throw new IOException(
          "Downloaded file size doesn't match expected Content Length for " + src
          + ". Please retry.");
      }
    }
    // update modification date
    long lastModified = srcConn.getLastModified();
    if (lastModified > 0) {
      dest.setLastModified(lastModified);
    }
  } finally {
    disconnect(srcConn);
  }
}

然后我们重新打包,执行ant jar的打包命令。就可以在build/artifact/jars/ivy.jar这个目录发现我们新的 jar 包。那么这个 jar 包怎么用了?

ant 默认是使用用户目录下的.ant/lib/ant-2.3.0.jar这个作为 ivy 的 jar。我这里就是/Users/pizhihui/.ant/lib/ivy-2.4.0.jar。这里我们将上面的 jar 重名为ivy-2.4.0.jar,然后放入这个目录下面,删除之前的 jar 就 OK 喽。

下面就是接着执行ant eclipse,可以看见已经愉快的从阿里云的 maven 的镜像下载 jar 包了。如下图所示:

如何学习zookeeper源码 zookeeper源码视频_如何学习zookeeper源码_02

编译完成后,就会出现下面的截图,表示已经编译完成了,接下来就是导入 IDEA 中,愉快的进行源码的阅读了

如何学习zookeeper源码 zookeeper源码视频_jar_03