在JIB插件中配置-Djava.library.path后Docker运行报错求助
问题描述
我尝试在pom.xml中使用以下JIB插件配置构建镜像:
<configuration> <from> <image>{artifactory-location}/container-release/managedbaseimages/oracle-jdk:11-stable</image> </from> <to> <image>{artifactory-location}/container-sandbox/abc/bot-sample-image</image> </to> <container> <creationTime>${maven.build.timestamp}</creationTime> <jvmFlags> <jvmFlag>-Djava.library.path=.</jvmFlag> <jvmFlag>-Dlog4j2.configurationFile=log4j2_default.xml</jvmFlag> </jvmFlags> <!--<args>--> <!-- <arg>-Djava.library.path</arg>--> <!-- <arg>.</arg>--> <!--</args>--> </container> </configuration>
执行docker run运行该镜像时,出现如下错误(尽管jni.so文件已存在于指定目录,我也尝试过修改路径):
ERROR StatusLogger Reconfiguration failed: No configuration found for '4b85612c' at 'null' in 'null' 22:02:21.085 [main] ERROR TRACE.Casp - no casp_jni in java.library.path: [.] java.lang.UnsatisfiedLinkError: no casp_jni in java.library.path: [.] at java.lang.ClassLoader.loadLibrary(ClassLoader.java:2660) ~[?:?] at java.lang.Runtime.loadLibrary0(Runtime.java:827) ~[?:?] at java.lang.System.loadLibrary(System.java:1871) ~[?:?]
但直接使用以下命令运行应用时一切正常:
java -Djava.library.path=. -jar bot_sample.jar
容器入口点已设置为 [java, -Djava.library.path=., -Dlog4j2.configurationFile=., -cp, /app/resources:/app/classes:/app/libs/*, com.abc.def.bot.Main],请问该如何解决此问题?
解决方法
1. 替换相对路径为绝对路径
容器默认工作目录通常是/,而非你的应用文件所在的/app目录,导致相对路径.无法指向正确位置。直接把JVM参数改成绝对路径:
<jvmFlags> <jvmFlag>-Djava.library.path=/app</jvmFlag> <jvmFlag>-Dlog4j2.configurationFile=/app/resources/log4j2_default.xml</jvmFlag> </jvmFlags>
同时修正入口点里的-Dlog4j2.configurationFile参数,把.替换为上述绝对路径。
2. 指定容器工作目录
在JIB的<container>配置中添加工作目录设置,让相对路径和本地运行时上下文一致:
<container> <creationTime>${maven.build.timestamp}</creationTime> <workingDirectory>/app</workingDirectory> <jvmFlags> <jvmFlag>-Djava.library.path=.</jvmFlag> <jvmFlag>-Dlog4j2.configurationFile=log4j2_default.xml</jvmFlag> </jvmFlags> </container>
3. 验证文件实际位置
进入容器内部确认文件是否在预期路径:
docker run --rm -it <你的镜像名> /bin/bash # 查看应用目录文件 ls /app # 查看配置文件位置 ls /app/resources
确保casp_jni.so在/app下,log4j2_default.xml在/app/resources下(匹配classpath配置)。
4. 确保JIB正确拷贝.so文件
如果.so文件不在默认打包目录(如src/main/resources),需要在JIB配置中添加额外目录映射:
<configuration> <!-- 其他原有配置 --> <extraDirectories> <paths> <path> <from>src/main/native</from> <!-- 本地.so文件所在目录 --> <into>/app</into> <!-- 容器内目标目录 --> </path> </paths> </extraDirectories> </configuration>
5. 改用jar运行的入口方式
既然本地java -jar可以正常运行,修改JIB配置让容器直接采用相同逻辑:
<container> <creationTime>${maven.build.timestamp}</creationTime> <mainClass>com.abc.def.bot.Main</mainClass> <jvmFlags> <jvmFlag>-Djava.library.path=.</jvmFlag> <jvmFlag>-Dlog4j2.configurationFile=log4j2_default.xml</jvmFlag> </jvmFlags> <workingDirectory>/app</workingDirectory> </container>
JIB会自动生成java -jar格式的入口命令,避免classpath配置差异问题。
内容的提问来源于stack exchange,提问作者Aayush Garg
相关产品推荐
相关产品推荐

