背景介绍:因langchain4j最新版本(>=0.36.0)(Min JDK version has been upgraded to 17)需JDK17起,故直接使用Amazon Corretto JDK 21作为基础镜像。
在使用 JDK21 进行开发或运行相关应用时,有时会遭遇令人困扰的问题。今天运行 java -jar xxx.jar时出现 “Error: An unexpected error occurred while trying to open file xxx.jar” 这样的错误提示,给开发进程带来阻碍。接下来我们将逐步重现该过程以及如何绕过该问题。
容器环境
宿主机:CentOS Linux release 7.6.1810 (Core)
Docker版本:
containerd.io.x86_64 1.2.13-3.2.el7 @docker-ce-stable
docker-ce.x86_64 3:19.03.12-3.el7 @docker-ce-stable
docker-ce-cli.x86_64 1:19.03.12-3.el7 @docker-ce-stable
Docker-Compose:docker-compose version 1.26.2, build eefe0d31
镜像构建脚本
直接复制 corretto-docker-debain-21 的脚本
FROM debian:buster-slimARG version=21.0.5.11-1
# In addition to installing the Amazon corretto, we also install
# fontconfig. The folks who manage the docker hub's
# official image library have found that font management
# is a common usecase, and painpoint, and have
# recommended that Java images include font support.
#
# See:
# https://github.com/docker-library/official-images/blob/master/test/tests/java-uimanager-font/container.javaRUN set -eux \&& apt-get update \&& apt-get install -y --no-install-recommends \curl ca-certificates gnupg software-properties-common fontconfig java-common \&& curl -fL https://apt.corretto.aws/corretto.key | apt-key add - \&& add-apt-repository 'deb https://apt.corretto.aws stable main' \&& mkdir -p /usr/share/man/man1 || true \&& apt-get update \&& apt-get install -y java-21-amazon-corretto-jdk=1:$version \&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \curl gnupg software-properties-commonENV LANG=C.UTF-8
ENV JAVA_HOME=/usr/lib/jvm/java-21-amazon-corretto
测试代码
代码结构
├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─sample
│ │ └─resources
│ └─test└─java
pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.sample</groupId><artifactId>Sample</artifactId><version>1.0-SNAPSHOT</version><properties><jdk-version>21</jdk-version><maven.compiler.source>21</maven.compiler.source><maven.compiler.target>21</maven.compiler.target><maven-source-plugin>3.2.1</maven-source-plugin><maven-compiler-plugin-version>3.11.0</maven-compiler-plugin-version><maven-surefire-plugin-version>3.1.0</maven-surefire-plugin-version></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.0</version></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-source-plugin</artifactId><version>${maven-source-plugin}</version><executions><execution><id>attach-sources</id><phase>install</phase><goals><goal>jar</goal></goals></execution></executions></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>${jdk-version}</source><target>${jdk-version}</target><parameters>true</parameters></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><version>${maven-surefire-plugin-version}</version><configuration><forkCount>1</forkCount><reuseForks>true</reuseForks><argLine>-Dfile.encoding=UTF-8</argLine></configuration></plugin><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.1.6</version><configuration><mainClass>com.sample.Application</mainClass></configuration><executions><execution><goals><goal>repackage</goal></goals><configuration><classifier>exec</classifier></configuration></execution></executions></plugin></plugins></build>
</project>
Application
package com.sample;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration><property name="log.pattern"value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}] [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/><logger name="org.springframework.web" level="INFO"/><logger name="org.springframework.jdbc" level="INFO"/><logger name="com.sample" level="INFO"/><appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><pattern>${log.pattern}</pattern></encoder><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>debug</level></filter></appender><springProfile name="dev"><root level="INFO"><appender-ref ref="consoleAppender"/></root></springProfile><springProfile name="test"><property name="log.path" value="/data/logs"/><appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/log4i.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/log4i.log.%d{yyyy-MM-dd}</fileNamePattern><maxHistory>180</maxHistory></rollingPolicy><encoder><pattern>${log.pattern}</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>DEBUG</level><onMatch>ACCEPT</onMatch><onMismatch>ACCEPT</onMismatch></filter></appender><appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/log4e.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/log4e.log.%d{yyyy-MM-dd}</fileNamePattern><maxHistory>365</maxHistory></rollingPolicy><encoder><pattern>${log.pattern}</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><root level="info"><appender-ref ref="file_info"/><appender-ref ref="file_error"/></root></springProfile><springProfile name="prod"><property name="log.path" value="/data/logs"/><appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/log4i.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/log4i.log.%d{yyyy-MM-dd}</fileNamePattern><maxHistory>180</maxHistory></rollingPolicy><encoder><pattern>${log.pattern}</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/log4e.log</file><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/log4e.log.%d{yyyy-MM-dd}</fileNamePattern><maxHistory>180</maxHistory></rollingPolicy><encoder><pattern>${log.pattern}</pattern></encoder><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><root level="info"><appender-ref ref="file_info"/><appender-ref ref="file_error"/></root></springProfile>
</configuration>
构建工程
mvn clean package
容器内运行工程
什么问题引起?
暂时未知,只好换旧版的JDK21(21.0.0.35.1)试试
安装完成后验证版本
root@e3bd319b01b7:/home# java -version
openjdk version "21" 2023-09-19 LTS
OpenJDK Runtime Environment Corretto-21.0.0.35.1 (build 21+35-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.0.35.1 (build 21+35-LTS, mixed mode, sharing)
运行工程
至此绕过 Error: An unexpected error occurred while trying to open file Sample-1.0-SNAPSHOT-exec.jar 的问题。
最后,若你知道如何解决该问题,请留言。