java - gradle 构建本地工程。在 docker 容器中它没有。为什么?

标签 java docker gradle redis

情况很简单:

这是我的本地环境:

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

这是我运行的构建命令:

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

测试失败,在我得到的日志中:

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 容器会从相同的工件存储库中提取。所以,我什至不知道从哪里开始

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

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

gradle printDependencyHashes | sort > hashes.log

分别。结果是相同的。我什至考虑过文件系统的 jar 加载顺序如何影响类加载并比较依赖关系。完全相同的。为简洁起见省略。

MD5 hash of all dependencies compared

最佳答案

Java Snappy 的本地库(通过 JNI 加载)是针对 glibc 编译的。 Alpine Linux(你的容器所基于的)使用 musl libc,它是源代码兼容的,但不是二进制兼容的(基本上意味着如果你针对 musl 编译 native 库它会工作,但如果它针对 glibc 编译它不会工作与肌肉)。

你有三个选择:

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

关于java - gradle 构建本地工程。在 docker 容器中它没有。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45339943/

相关文章:

java - 直接通过eclipse工作运行,但在webapps中上传war文件,然后开始不工作

docker - 服务 “nginx-proxy”使用未定义的网络 “nginx-proxy”

android - 错误 :Unable to resolve dependency. ..无法解析项目

java - ZipException : transform duplicate entry com/google/android/gms/internal/zzez. 类

android - 无法在 Android Studio 中升级 gradle 版本

当单击按钮而调用 JavaFX AnimationTimer 时,它不会启动

java - 移动数据时的空指针

java - Java 相当于 Python 的 reduce 函数是什么?

docker - 无法启动超过 1 个 cassandra 节点

mysql - Docker:MySQL准备就绪时, “wait-for-it”脚本无法启动应用程序