问题:
- 在pom.xml文件所在目录执行命令mvn clean compile -U,镜像可以构建成功,但是控制台输出了警告信息,如下图:
- 尝试用此镜像创建容器,行命令docker run --name=test bolingcavalry/hellojib:0.0.1-SNAPSHOT,报错如下:
CN0014005932:~ zhaoqin$ docker run --name=test bolingcavalry/hellojib:0.0.1-SNAPSHOT
Error: Could not find or load main class ${start-class}
- docker ps -a查看容器信息如下,只能看到状态是"退出",别的没啥了:
CN0014005932:~ zhaoqin$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d618f6588821 bolingcavalry/hellojib:0.0.1-SNAPSHOT “java -Xms4g -Xmx4g …” 4 minutes ago Exited (1) 4 minutes ago test
- 不甘心,用命令docker ps -a --no-trunc查看未截断的容器信息:
CN0014005932:~ zhaoqin$ docker ps -a --no-trunc
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d618f6588821f00d3bd0b67a85ff92988b90dfff710370c9d340d5c544c550af bolingcavalry/hellojib:0.0.1-SNAPSHOT “java -Xms4g -Xmx4g -cp /app/resources:/app/classes:/app/libs/* ${start-class}” 7 minutes ago Exited (1) 7 minutes ago test
- 这次有新发现,容器启动时执行命令是java -Xms4g -Xmx4g -cp /app/resources:/app/classes:/app/libs/* s t a r t − c l a s s ,怪哉!这个 {start-class},怪哉!这个 start−class,怪哉!这个{start-class}是什么?我们来看一个正常镜像的启动命令:
java -Xms4g -Xmx4g -cp /app/resources:/app/classes:/app/libs/* com.bolingcavalry.jiberrordemo.JibErrorDemoApplication
如上所示,com.bolingcavalry.jiberrordemo.JibErrorDemoApplication是main方法所在类,此命令可以正常运行JibErrorDemoApplication类的main方法;
6. 小结问题:容器启动时执行java命令,把${start-class}作为参数传给java,导致java无法处理此参数,所以进程报错,导致容器退出;
问题原因
此问题的原因很简单:java工程中带有main方法的类不止一个,去查看jib-error-demo工程的代码,发现Utils.java中果然有个main方法:
public class Utils {
public static String time(){
return new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”).format(new Date()).toString();
}
public static void main(String[] args){
System.out.println(time());
}
}
将上述main方法删除掉,再构建镜像并运行容器,证实问题已经解决。
另一种解决问题的方法
如果不想动Utils类的代码(也许jar包中某个类带有main方法),请打开pom.xml文件,在jib插件的配置中增加mainClass节点,节点内容是指定的class类,如下图红框所示:
经过上面的设置,问题也可以解决。
接下来,如果您有兴趣了解更深层次的原因,咱们一起来深度探险吧。
查找问题
- 这个问题在Jib的官方GitHub上是有记录的,先看第一条,地址是:https://github.com/GoogleContainerTools/jib/issues/1601 ,如下图红框所示,同样的问题,最后issue的发起人自己关闭了这个issue,因为他发现这自己的项目中有两个带有main方法的类:
- 再来看看这个issue, https://github.com/GoogleContainerTools/jib/issues/170 ,Jib的作者Q Chen推测是Spring将 s t a r t − c l a s s 这个字符串设置为 M a i n − C l a s s 属性的值 ( 个人感觉,这里说的 S p r i n g 应该是 s p r i n g b o o t 的 m a v e 插件吧 ) ,于是 J i b 插件在使用 M a i n − C l a s s 的值得时候,拿到的就是 {start-class}这个字符串设置为Main-Class属性的值(个人感觉,这里说的Spring应该是spring boot的mave插件吧),于是Jib插件在使用Main-Class的值得时候,拿到的就是 start−class这个字符串设置为Main−Class属性的值(个人感觉,这里说的Spring应该是springboot的mave插件吧),于是Jib插件在使用Main−Class的值得时候,拿到的就是{start-class}这个字符串了:
- 170这个issue的后续情节很有意思,Jib作者Q Chen对这个问题也很纠结,如果Java工程中发现了多个带有main方法的类,Jib究竟该如何处理呢?Q Chen最后决定输出警告,如下图:
- 一起来看看这段代码吧,也就是上图中#288,地址是:https://github.com/GoogleContainerTools/jib/pull/228/files/c8757e1f9ea47edd78df18142de7836a68f22034 ,如果mainClass不像一个class类的名称,就输出警告,这个逻辑在Gradle和Maven插件中都写入了:
- 最后一个问题:上面代码中的mainClass从哪来的?打开上图的源码,地址是:https://github.com/GoogleContainerTools/jib/blob/c8757e1f9ea47edd78df18142de7836a68f22034/jib-maven-plugin/src/main/java/com/google/cloud/tools/jib/maven/BuildImageMojo.java ,如下图红框,从方法名可以推测,该值来自构建SpringBoot工程的maven插件,所以前面Q Chen提到main-class变量的值是Spring修改的,应该是来自这段代码:
此时的您,如果依然意犹未尽,咱们再来巩固一下SpringBoot的start-class
关于start-class
-
熟悉SpringBoot的同学其实对${start-class}并不陌生,当工程中多个类中都有main方法时,使用该参数来指定SpringBoot的启动类;
-
先看SpringBoot官方文档熟悉一下start-class,地址是:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/ ,下图内容比较关键:我们设置的启动类被指定到Start-Class属性中,而Main-Class属性变成了org.springframework.boot.loader.JarLauncher,这才是SpringBoot真正的启动类:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
总结
对于面试还是要好好准备的,尤其是有些问题还是很容易挖坑的,例如你为什么离开现在的公司(你当然不应该抱怨现在的公司有哪些不好的地方,更多的应该表明自己想要寻找更好的发展机会,自己的一些现实因素,比如对于我而言是现在应聘的公司离自己的家更近,又或者是自己工作到达了迷茫期,想跳出迷茫期等等)
Java面试精选题、架构实战文档
整理不易,觉得有帮助的朋友可以帮忙点赞分享支持一下小编~
你的支持,我的动力;祝各位前程似锦,offer不断!
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
得有帮助的朋友可以帮忙点赞分享支持一下小编~**
你的支持,我的动力;祝各位前程似锦,offer不断!
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-ETn5sYJB-1712856368904)]