我观察到Clojure编译器的一个奇怪现象:它可以对相同的输入产生不同的输出。也就是说,生成的.class文件包含不同的字节,但运行时行为却完全相同。为什么会有这种现象?我已经创建了一个Docker容器和脚本,展示了这个问题。
虽然对于结果的Java程序功能来说是无害的,但这对试图基于简单的字节平等缓存编译过的类的方法是个问题,例如在Docker层次结构缓存中。理想情况下,可以编译第三方Clojure库,并将这些库存储在容器中Clojure应用的单独Docker层。如果这个层在特定的固定依赖集给定的情况下产生了相同的字节输出,那么在推送到仓库时可以认出这个层已经存在。这将避免由于创建整个新的uberjar而造成的存储和网络成本,每当您的应用程序代码中的任何源代码更改时,都需要创建新的uberjar。
在没有使用AOT编译时可以进行此类缓存,但这是以较慢的应用程序启动速度为代价的。