gradlebuild立本地作品。 在docker集装箱它不。 为什么?

情况很简单:

这里是我的本地环境:

cbongiorno at wa-cbongiorno-mba in /Volumes/dev/sterling/java-user-login-service on master [!$] $ gradle -v ------------------------------------------------------------ Gradle 4.0 ------------------------------------------------------------ Build time: 2017-06-14 15:11:08 UTC Revision: 316546a5fcb4e2dfe1d6aa0b73a4e09e8cecb5a5 Groovy: 2.4.11 Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015 JVM: 1.8.0_131 (Oracle Corporation 25.131-b11) OS: Mac OS X 10.12.5 x86_64 

这里是我运行的构build命令:

 gradle compileJava check assemble && history | tail -3 

这里是结果:

 BUILD SUCCESSFUL in 3m 3s 38 actionable tasks: 38 executed 1496 gradle clean 1497 gradle compileJava check assemble && history | tail -2 

现在,当我在Docker中运行这个相同的安排时:

 docker run --rm gradle:alpine gradle -v ------------------------------------------------------------ Gradle 4.0 ------------------------------------------------------------ Build time: 2017-06-14 15:11:08 UTC Revision: 316546a5fcb4e2dfe1d6aa0b73a4e09e8cecb5a5 Groovy: 2.4.11 Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015 JVM: 1.8.0_131 (Oracle Corporation 25.131-b11) OS: Linux 4.9.36-moby amd64 docker run --rm -v "$PWD":/project -w /project gradle:alpine gradle compileJava check assemble 

testing失败,并在日志中得到:

 Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.xerial.snappy.Snappy build_1 | at org.redisson.codec.SnappyCodec$2.encode(SnappyCodec.java:68) build_1 | at org.redisson.client.handler.CommandEncoder.encode(CommandEncoder.java:103) build_1 | at org.redisson.client.handler.CommandEncoder.encode(CommandEncoder.java:45) build_1 | at io.netty.handler.codec.MessageToByteEncoder.write(MessageToByteEncoder.java:107) build_1 | ... 31 more build_1 | build_1 | build_1 | io.netty.handler.codec.EncoderException: java.lang.NoClassDefFoundError: Could not initialize class org.xerial.snappy.Snappy 

当我的应用程序尝试与Redis进行互动时。

这怎么可能? 这是一个红鲱鱼,问题是与docker环境本身? 我想一个档案是腐败/错误,但docker容器将从相同的工件存储库拉。 所以,我甚至不知道从哪里开始

我用这里的答案将每个jar的哈希值转储到一个文件中:

 docker run --rm -v "$PWD":/project -w /project gradle:alpine gradle printDependencyHashes | sort > hashes-docker.log gradle printDependencyHashes | sort > hashes.log 

分别。 结果是一样的。 我甚至想过如何从文件系统加载命令可以影响类加载和比较依赖。 相同。 为简洁起见,省略。

比较所有依赖项的MD5哈希

Java Snappy的本地库(通过JNI加载)是针对glibc编译的。 高山Linux(你的容器是基于什么)使用musl libc这是源兼容的,但不是二进制兼容的(基本上意味着如果你编译本机库反对musl它将工作,但如果它编译对glibc它将无法正常工作与musl)。

你有三个select:

  1. 在您的Alpine容器中安装java-snappy-native (其中包含为musl构build的本地库),并设置org.xerial.snappy.use.systemlib=true (告诉Java库使用预先安装的本地lbrary)。 目前您还需要安装snappy因为有人无法将依赖关系添加到上述包中。
  2. 使用glibc的基础容器
  3. 在你的Alpine容器中安装glibc(不推荐)