H2数据库CSVRead抛出FileNotFoundException问题求助
问题描述
我有一个使用JPA搭配H2数据库的Spring Boot应用,data.sql的内容如下:
INSERT INTO artists SELECT * FROM CSVREAD('/usr/local/data/artists.csv');
本地运行时(已修改为对应本地目录)可正常工作,但使用以下Docker镜像构建后,启动时抛出java.nio.file.NoSuchFileException: /usr/local/data/artists.csv异常。通过docker export查看镜像确认文件确实存在于该路径,且Docker以超级用户运行,不清楚是否与文件访问权限有关?
对应的Dockerfile内容:
# Build stage FROM maven:3.8.6-amazoncorretto-17 AS build COPY src /home/app/src COPY pom.xml /home/app RUN mvn -f /home/app/pom.xml clean package -DskipTests # Package state FROM amazoncorretto:17-alpine COPY --from=build /home/app/target/webusengus-0.0.1-SNAPSHOT.jar /usr/local/lib/webusengus.jar COPY --from=build /home/app/src/main/resources/artists.csv /usr/local/data/artists.csv EXPOSE 8080 ENTRYPOINT ["java","-jar","/usr/local/lib/webusengus.jar"]
排查与解决方案
1. 修复文件权限
Alpine镜像的目录默认权限可能存在限制,即使容器以root运行,复制的文件可能继承了构建阶段的非可读权限。可以在Dockerfile中添加权限配置:
# 在COPY artists.csv的步骤后添加 RUN mkdir -p /usr/local/data && chmod 755 /usr/local/data RUN chmod 644 /usr/local/data/artists.csv
2. 改用类路径读取(推荐方案)
由于artists.csv原本位于src/main/resources下,打包后会被包含在Jar的类路径中,直接通过类路径读取可以彻底避免路径和权限问题:
修改data.sql内容:
INSERT INTO artists SELECT * FROM CSVREAD('classpath:artists.csv');
同时可以删除Dockerfile中复制artists.csv到/usr/local/data的步骤,因为文件已经内置在Jar包中,无需额外挂载或复制。
3. 验证H2路径解析逻辑
如果坚持使用绝对路径,需要确认H2在容器环境中的路径解析规则:
- 确保容器启动时,
/usr/local/data/artists.csv确实处于可访问状态,可以在Dockerfile的ENTRYPOINT前添加验证命令(比如RUN cat /usr/local/data/artists.csv),确认文件内容可正常读取。 - 若使用H2的内嵌数据库模式,可检查Spring Boot配置中是否有影响路径解析的参数。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

