【填坑向】我可能也就是踩了dockrfile部署jar包(需读取resource目录下的文件)全部的坑吧。。。

FileNotFoundException。。没错、这篇还是从读取的文件找不到的问题开始,今天来个终极版( ̄∇ ̄)/

一开始我把要读取的文件放在了项目根路径,package就没把它打进去,显然是找不到的,于是我把这个JSON文件移到了resources中

此时可以看到,这个文件也打进了target中,这部分可以参考

【填坑向】Linux获取Java程序resource下的文件路径(这次的坑好像没填住……

之前的一篇的文章,那里有记录过获取路径失败的原因,这里就不重复赘述叻

今天这篇是有新发现!算是填上一篇文章的坑( ̄∇ ̄)/

在官网上了解到可以通过解包的方式,来读取jar包中的内容

官方地址:https://docs.spring.io/spring-boot/docs/2.3.12.RELEASE/reference/html/deployment.html#deployment

于是在本地的终端中对打好的jar包依次执行了这两行命令,运行无比顺滑然后我就也在Dockerfile中加了如下红框框内的两行

CMD ["jar","-xf","my-1.0.0-SNAPSHOT.jar"] CMD ["java","org.springframework.boot.loader.JarLauncher"]

推到服务器上。。。就是=[,,_,,]:3哭死在阿里云。。。

报找不到org.springframework.boot.loader.JarLauncher

找不到org.springframework.boot.loader.JarLauncher

最初单纯的俺一直觉得是没有填对路径,于是按照各种文章尝试:比如切换WORKDIR,改绝对路径、改相对路径。。。

服务器日志都是坚持告诉我:Could not find the main class: org.springframework.boot.loader.JarLauncher

即将哭死的我一不小心从旁边大佬处得知CMD指令只有最后一个有效。。。

WHAT?! RUN、CMD 和 ENTRYPOINT 指令都可以用来执行具体的命令RUN 指令是在 Docker 镜像构建时发挥作用, 可以使用多个该命令,且执行结果会记录到镜像中CMD 和 ENTYPOINT 指令是在容器启动时自动执行,均只有最后一个该指令有效,且均可以在 docker run 中被覆盖ENTRYPOINT 指令和 CMD 的区别在于使用 ENTRYPOINT 时 CMD 指令会被作为其默认参数,而用户也可以在启动容器时通过覆盖 CMD 指令来输入参数;此外, 这也意味着 ENTRYPOINT 指令的内容不易被用户命令覆盖。

好吧(谁让我不好好学docker=[,,_,,]:3)

怪不得看到很多案例使都是使用entrypoint.sh文件来执行多条脚本的,俺也来!

于是我在Dockerfile同级目录下新建了一个entrypoint.sh文件,把多条命令写在这个文件中

在Dockerfile中添加执行这个脚本的代码

ENTRYPOINT ["/app/docker/entrypoint.sh"]

又是一顿找不到。。。

no such file or directory

我们先来分析下这个异常记录📝,找不到文件?

我进入到了这个容器的终端中,使用find命令全局搜索🔍,仍然未找到,即不是路径的问题,在我看到ADD xxx.jar那句的时候,忽然意识到,并没有将这个文件复制进镜像,自然不会在启动后能找的到

但是对docker并不是很熟悉的我并不知道这个文件会在具体哪个路径下,算了,成年人不做选择!

全复制!加一行搞定(。・ω・。)ノ

COPY . /app/

就在我好不容易识别到了entrypoint.sh这个文件

它终于开始执行叻。。。。md

permission denied

caused: exec: "/app/docker/entrypoint.sh": permission denied: unknown

一顿搜索🔍主要有两种加权限的方法(如下图1、2)

我用的第二种

容器启动(。・ω・。)ノ

=[,,_,,]:3这个月都没今天哭的次数多、又又又又tmd报错叻!!!》〉冷静ing

算了继续刨错吧。。。

jar: command not found

又报了jar: command not found,明明以前java命令都是可以正常执行(_ _).。o○java命令可以正常执行,但是jar命令不行,这俩明明安装了JDK都会有的呀。。。

我抬头瞅了一眼运维同学提供的基础镜像,我又哭了

请问,这是只装了jre的意思吗?

运维同学:这个基础镜像只提供了运行jar包的基本环境哦,而且按照一般流程是只传jar包到服务器上的(运维同学表示这个锅我不背)

针对这个情况,目前想到的解决方案有两个

解决方案一

引用一个拥有完整JDK的基础镜像

解决方案二

放弃执行jar的解包命令,直接将要读取的文件跟jar包一起COPY到服务器上(这样可以不替换基础镜像,但是需要在代码中判断当前环境,根据不同环境选择不同的路径获取方式)

俺选了方案二,主要不想麻烦运维同学(我真体贴(*≧ω≦)ノ

但是我并不知道这些文件在启动起来的容器中的位置,由于之前用COPY . /app/把target中所有文件都复制了过去,所以我只需要在容器中看下,就知道这些文件的路径了,那么首先我需要把容器启动起来,于是把脚本文件里的代码替换成了单纯启动jar包的

java -server -Xms2048m -Xmx2048m -D java.security.egd=file:/dev./urandom -jar /app/ras-data-1.0.0-SNAPSHOT.jar

果然,容器正常启动了,进入容器后ls查看下,发现果然一句COPY . /app/复制进来了好多东西

再进入docker文件夹看到了我想要执行的脚本文件,但其实已经不重要了,因为俺选了方案二、=_=

然后进入classes文件夹看到了我想要拿路径的JSON文件。。。开心

所以我只需要在Dockerfile里加了如下这一行代码将JSON文件复制到jar包的同目录下

COPY ./target/classes/myJson.json /app/myJson.json

由于按此方案只有一条启动命令需要执行,所以就不需要entrypoint.sh这个脚本文件了,直接在Dockerfile里加即可(其实用的就是原来的启动命令)

ENTRYPOINT ["java","-server","-Xms2048m","-Xmx2048m","-D java.security.egd=file:/dev./urandom","-jar","/app/ras-data-1.0.0-SNAPSHOT.jar"]

Dockerfile成品图如下

启动成功!>> 终于填了之前耿耿于怀的坑坑、今天的花要撒满全世界!(。・ω・。)ノ🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AQin1012

求小鱼干呢~~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值