问题背景
实验室要求复现一篇论文SAMC:Semantic-Aware Model Checking for Fast Discovery of Deep Bugs in Cloud Systems (osdi,2014),学长之前找到了作者的源码,但是没有实际运行过。我需要把源码在自己电脑上运行起来。
这篇论文的源码中的一部分是对原有Zookeeper框架的修改。作者在原有框架的基础上加入了一些自己的逻辑代码。因此在使用时就需要对修改过的Zookeeper代码重新编译。
作者使用的Zookeeper版本是3.5.0,这个版本的Zookeeper还必须要使用Ant来编译。最新的Zookeeper已经可以使用Maven了。
关于Ant, Maven和Gradle的相关演化,读者可以参考这篇文章。
构建工具的进化:ant, maven, gradle
Ant的编译还是比较简单的,我们到达项目的根目录(有build.xml存在的目录),然后在终端中输入ant
即可。
出现问题。
问题
在稍微修改过的Zookeeper-3.5.0源码上运行ant命令编译,编译失败,返回多个下列格式的错误
[ivy:retrieve] SERVER ERROR: HTTPS Required url=http://repo1.maven.org/....
系统配置
虚拟机容器:VMWare 15.5 Pro
(下列都是虚拟机相关配置)
操作系统:Ubuntu 18.04.1
JDK:openjdk-8
Ant:Ant-1.10.5
Zookeeper:修改过的Zookeeper-3.5.0
问题分析
maven仓库代是否能正常下载?
这是我在面对这样的错误时的第一反应,因为由于国外仓库导致的无法下载问题已经快成了我的日经了。
所以我先检查了一下自己设置的代理能否正常运行,发现可以正常运行,这说明应该不是由于这类原因导致的错误。
是否是由于HTTP不再受支持?
观察一下报错信息发现,所有下载错误的依赖都是http开头的,这很可能是由于HTTP现在已经不受支持导致的。在HTTPS逐渐被要求强制使用的现在,这个问题也坑过我好几次了。
在网上搜了一下,果然找到了相关的解释。
相关的两个参考网站如下:
- Requests to http://repo1.maven.org/maven2/ return a 501 HTTPS Required status and a body [duplicate]
- The Central Repository is Moving to HTTPS
于是我就把build.xml中所有的http检查了一遍,把认为应该替换的都替换成了https。重新使用ant
命令编译,仍然有很多错误。问题没有得到解决,而且我也没有去仔细检查这个做法是否真的产生了一些效果。
是否是由于使用了Ivy?
重新观察输出,发现开头都是[ivy:retrieve],莫非玄机在这里?
Ivy是Apache的另一个项目,它为Ant提供了许多强大的扩展功能。比如说Ant本身其实并没有仓库的概念,我们想要添加一个依赖必须要手动下载并且放到项目的相关目录下。而Maven则可以直接通过声明依赖,让系统在编译时自动从远程仓库里下载相关的代码包。Ant显得很不方便,而Ivy则可以为Ant提供从Maven仓库中下载依赖的能力。
Ivy官网网址:
https://ant.apache.org/ivy/history/latest-milestone/tutorial.html
对于有Ivy参与的项目,一般来说根目录下除了build.xml外,还会有一个lvy-setting.xml文件,我回到项目的根目录看了一下,果然。
打开,果然发现里面有许多使用http的指向Maven仓库的依赖,我把它们全部改为https.
再次编译,成功。
一些额外的经验
检查build.xml使用的jdk版本
实际上,在修改了Ivy之后,我的编译命令只是成功下载了所有需要的依赖,但是仍然没有完全执行成功,错误信息提示
jute: [javac] Compiling 39 source files to ....... [javac] 错误: 不再支持目标选项 1.5。请使用 1.6 或更高版本。
网上搜索得知,这是由于在编译文件中指定的编译jdk是1.5版本,而该版本已经不受支持,我们修改编译文件,将其更新为我们安装的1.8版本即可。
参考网站:
打开Zookeeper的build.xml,发现其javac标签的target和source都指向了一个变量。
在build.xml中寻找javac.target和javac.source变量,修改即可。
再次编译,编译成功。
搜索时去除无关内容
直接搜索和Ant相关的问题时,搜索引擎很容易提供许多与Ant Design相关的结果
当然实际上Ant并没有代码仓库的概念,这里只是做个例子。
Ant Design是和React前端框架配套的一个前端组件库。在前端和React大火的现在,显然已经比我们本文提到的Apache Ant构建工具热度大多了。
在搜索时,我们可以使用-
来去除掉搜索结果中包含某个关键字的部分,比如上面的搜索内容我们可以换为
ant的代码库 -design
直接筛去了所有与Ant Design相关的内容,舒适多了。
问题解决
参考问题分析中提到的三点,我成功地编译了论文作者修改过的Zookeeper-3.5.0代码。
其中“是否是由于使用了Ivy?”是此问题最核心的部分。
后记
SAMC:Semantic-Aware Model Checking for Fast Discovery of Deep Bugs in Cloud Systems这篇文章的发表时间是2014年,作者写代码的时间应该要再往前。在那个时候,Ant应该还是主流的构建工具,但是Maven已经兴起了而且确实很方便。所以在那时使用Ant + Ivy应该是一种非常主流的做法。
但是到了现在2021年,项目构建已经基本上都是用的Maven了,一些比较激进的团队可能会使用更先进的Gradle或者其他工具。Ant已经销声匿迹。现在的我再去看过去的Ant项目已经需要花费一定时间的入门成本和大量的查找出现的问题所需要的时间成本。尤其是面对Ivy这样将后期之秀Maven的功能扩展给前辈Ant的作品(显然它应该是一个Maven时期的作品),如果之前只对Ant和Maven的特性有个简单印象的话,在编译过程中出现问题时真的很容易困惑(尤其是当你之前可能不知道有Ivy这么一个东西存在时)。
想必再过5年或者10年,未来的学生/开发者在面对我们如今使用gradle和一些我们已经习以为常的插件构建的项目时也会产生同样的困惑。我们可以为其留下我们自认为“详细”的文档和说明,但是可能他们仍然会难以理解,因为我们可能会忽略一些我们认为理所当然的东西。
也许一种思考在于。既然后来的工具一般要能支持之前的工具的功能,那么应该存在着一种方法可以把原来的项目的逻辑直接转接到新的工具上。
程序的本质也许是逻辑在某一种特定语言/工具/框架上的表达。比如我们可以用java+Spring或者Python+Djando实现同样的服务器逻辑。当然这两者可能不具有转化性,因为它们是同时期的不具备继承关系的两个存在。但是这不妨碍我们拿它来做个例子。如果我们能够把程序的逻辑抽取出来,弄成一种独立于语言/工具/框架之外的表达形式,也许会有些大用。
也许到时候我们可以把这种逻辑称之为软件?然后具体到语言之类上的实现称之为程序?嘶,这好像就有点计算机软件理论这种研究的味了。
(胡扯而已2333,真正的理论上对软件和程序的定义都不是这样的,作者也没有去了解过,在这里口嗨和yy罢了。)
到时候我们面对新的工具时,我们可以考虑在转换时怎么加入些新的工具能提供的特性,不过想必会很难。好在这种添加新特性的做法是可选的,因为原有的老工具的特性应该已经足以完成相关的逻辑任务了。由此看来,新老工具在功能上的继承性应该是个基础。
从现在的主流框架/工具来看,一些框架会对之前的框架进行近乎“重构”似的修改,也许从开发者的角度看两个框架在实现和使用上都没有任何相似之处。但是能不能实现继承并不能只看表面,而是需要对其功能进行抽象,对使用这两者构建的程序能否进行演化进行某些证明,也许需要用到些形式化的推导和方法。这会是个很难的事情。对一个东西进行抽象一向是个非常难的事情。