Java 格拉德尔在当地建造工厂。在docker容器中,它没有';T为什么?

Java 格拉德尔在当地建造工厂。在docker容器中,它没有';T为什么?,java,docker,gradle,redis,Java,Docker,Gradle,Redis,情况很简单: 这是我的本地环境: cbongiorno at wa-cbongiorno-mba in /Volumes/dev/sterling/java-user-login-service on master [!$] $ gradle -v ------------------------------------------------------------ Gradle 4.0 ----------------------------------------------------

情况很简单:

这是我的本地环境:

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
测试失败,在我得到的日志中:

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
分别。结果是一致的。我甚至考虑了文件系统的jar加载顺序如何影响类加载和比较依赖项。完全相同的为简洁起见省略


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

您有三种选择:

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

  • 这不是与任何依赖项相关的问题。看来你把一切都配置好了。我的猜测是,问题在于snappy库本身——它不能在docker平台上运行——可能缺少一些本机库?请注意理解我在说什么。也许试着在docker容器上运行snappy本身,看看它是否有效。酷答案!你怎么知道的这么清楚@欧泊我在阿尔卑斯山的容器中处理过这个库,所以我知道具体的情况。一般来说,虽然我经常使用容器和不同的操作系统,所以我知道在不同的基本操作系统上运行不同库的怪癖。可以编辑你的帖子,现在有
    snappy
    dependency@Lorenz您能否澄清是否需要将org.xerial.snappy.use.systemlib=true设置为打算使用snappy的应用程序的Java属性?是的,它需要是Java属性。SnappyJava只是在内部调用
    System.getProperty()