(已解决)报错no main manifest attribute 和NoClassDefFoundError , ClassNotFoundException
问题现象:
今天在项目中遇到了一个问题:
当我将服务打包并创建为docker容器发布为8090端口,部署到linux之后,启动这个容器后,再用postman去访问,发现访问不了:
通过docker ps -a 查看容器列表发现,刚刚部署的服务显示的是退出(exited)状态.
通过docker logs 5b93753d9f52 -f -t命令查看该容器的日志信息,可以了解到报错信息,如下:
2020-09-24T03:22:55.590187000Z no main manifest attribute, in xxxxxxxxxxx-0.0.1.jar
在经过一轮修改之后,再次打包发布;但是却发生第二个报错:java.lang.IllegalStateException报错,具体如下:
java.lang.IllegalStateException: Error processing condition on org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration.propertySourcesPlaceholderConfigurer
Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.xxxxxxxxxxx.xxxxxxxxxxx.config.HikariCustomConfig] from ClassLoader [[email protected]]
Caused by: java.lang.NoClassDefFoundError: org/springframework/transaction/PlatformTransactionManager
Caused by: java.lang.ClassNotFoundException: org.springframework.transaction.PlatformTransactionManager
问题分析:
第一个报错:2020-09-24T03:22:55.590187000Z no main manifest attribute, in xxxxxxxxxxx-0.0.1.jar
这个报错的意思是说,xxxxxxxxxxx-0.0.1.jar包中没有主清单属性,
要解决这个问题很简单,就是因为pom.xml文件中没有配置号maven打包插件
在解决这个问题后,又出现新的问题了:第二个报错:java.lang.IllegalStateException报错,需要注意的是:
这个报错是在我将项目打包并部署到linux系统后才会出现的,而在本地windows跑的话是不会报错的.
通过查看报错信息可知:
Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.xxxxxxxxxxx.xxxxxxxxxxx.config.HikariCustomConfig] from ClassLoader
Caused by: java.lang.NoClassDefFoundError: org/springframework/transaction/PlatformTransactionManager
Caused by: java.lang.ClassNotFoundException: org.springframework.transaction.PlatformTransactionManager
问题出现在 config 路径下的 一个类文件 : HikariCustomConfig,其中的 PlatformTransactionManager 这个贵鬼东西,在它引入的包路径(org.springframework.transaction)中找不到.
通过查看这个java文件,可以发现原始代码如下:
可以看到这是用于事务管理的配置,这个方法返回值是一个 DataSourceTransactionManager 对象,
由此我推测是因为,在包路径(org.springframework.transaction)找不到这个对象.
通过追溯这个对象的源代码,我发现 :
DataSourceTransactionManager 对象 继承自 AbstractPlatformTransactionManager抽象类 ,而这个抽象类又实现了PlatformTransactionManager 接口,由此可知:
PlatformTransactionManager 是个接口,而这个犯法的返回值是PlatformTransactionManager类型,而接口interface是不可以用@Bean注解来创建实例对象的,因此返回值应该修改为实例对象类型.
解决方法:
1.第一个报错:2020-09-24T03:22:55.590187000Z no main manifest attribute, in xxxxxxxxxxx-0.0.1.jar,解决方法:
在需要打包的服务的pom.xml文件中配置号插件,如下:
2.第二个报错:java.lang.ClassNotFoundException: org.springframework.transaction.PlatformTransactionManager,解决方法如下:
将 transactionManager 方法的返回值修改为 DataSourceTransactionManager ,如下:
修改为:
即可: