开发者

SpringBoot项目启动报错踩坑实战记录

开发者 https://www.devze.com 2023-02-08 10:54 出处:网络 作者: 一宿君
目录一、Redis和jedis版本不匹配二、spring循环编程客栈依赖2.1、方法12.2、方法2三、允许DefaultServlet默认注册3.1、方法13.2、方法2四、debug运行报错4.1、方法14.2、方法2总结一、redis和jedis版本不匹配
目录
  • 一、Redis和jedis版本不匹配
  • 二、spring循环编程客栈依赖
    • 2.1、方法1
    • 2.2、方法2
  • 三、允许DefaultServlet默认注册
    • 3.1、方法1
    • 3.2、方法2
  • 四、debug运行报错
    • 4.1、方法1
    • 4.2、方法2
  • 总结

    一、redis和jedis版本不匹配

    报错日志如下:

    Caused by: Java.lang.ClassNotFoundException: redis.clients.jedis.DefaultJedisClientConfig
    	at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
    	at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    	... 127 common frames omitted
    

    原因就是SpringBoot和jedis版本不匹配导致的,项目中引入redis默认版本为2.7.0

    <!-- spring redis session 默认2.7.0 -->
    <dependency>
         <groupId>org.springframework.session</groupId>
         <artifactId>spring-session-data-redis</artifactId>
    </dependency>
    

    通过https://mvnrepository.com/artifact/org.springframework.data/spring-data-redis查看对应jedis版本应该为3.8.0,而项目中是3.0.0,修改为3.8.0即可

    <dependency>
         <groupId>redis.clients</groupId>
         <artifactId>jedis</artifactId>
         <version>3.8.0</version>
    </dependency>
    

    二、spring循环依赖

    ***************************

    APPLICATION FAILED TO START

    ***************************

    Description:

    The dependencies of some of the beans in the application context form a cycle:

       projectRelatedController (field private cn......EstimateServiceImpl cn......ProjectRelatedController.estimateService)

    ┌─────┐

    |  estimateServiceImpl (field cn...FillDataAlarmService cn......fillDataAlarmService)

    ↑     ↓

    |  fillDataAlarmServiceImpl (field cn......EstimateServiceImpl cn......FillDataAlarmServiceImpl.estimateService)

    └─────┘

    Action:

    Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.

    Disconnected from the target VM, address: '127.0.0.1:1499', transport: 'socket'

    Process finished with exit code 1

    可以看到estimateServiceImpl 依赖了fillDataAlarmServiceImpl fillDataAlarmServiceImpl 又循环依赖了estimateServiceImpl ,这在代码层面是可以的,但在逻辑上是不允许的。

    2.1、方法1

    最简单粗暴的方法是在全局配置文件中允许循环引用存在,此属性默认值为false,显示声明为true,可回避项目启动时控制台循环引用异常。

    spring.main.allow-circular-references=true
    

    2.2、方法2

    spring的核心是控制反转依赖注入,循环依赖就是在依赖注入这一步造成的,也就是说AB相互依赖的时候,初始化A必须要初始化B,初始化B必须也要初始化A,所以就会有死循环。

    Spring2.6之前的版本会自动处理循环依赖,通过提前暴露出bean的注入方式,将实例化和初始化分开做,2.6之后的版本不会自动处理了。

    那如果业务场景实在需要循环依赖调用,有一个优雅的方式:控制反转,我们把控制权转到自己手上,使用方法的返回值获取实例对象,替换调通过成员变量注入实例对象,等我们用到的时候再去获取bean实例,不在初始化的时候注入,这样就优雅的避免了项目初始化的时候循环依赖导致的死循环。

    示例如下:

    A依赖B

    @Service
    @RequiredArgsConstructor
    public class AServiceImpl implements AService {
    
        private final ConfigurableListableBeanFactory beanFactory;
    
        @Override
        public BService getBService() {
            return beanFactory.getBean(BService.class);
        }
    }
    

    B依赖A

    @Service
    @RequiredArgsConstructor
    public class BServiceImpl implements BService {
    
        private final ConfigurableListableBeanFactory beanFactory;
    
        @Override
        public AService getAService() {
            return beanFactory.getBean(AService.class);
        }
    
    }
    

    三、允许DefaultServlet默认注册

    Caused by: java.lang.IllegalStateException: Unable to locate the default servlet for serving static content. Please set the 'defaultServletName' property explicitly.
    	at org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler.setServletContext(DefaultSerphpvletHttpRequestHandler.java:111)
    	at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.enable(DefaultServletHandlerConfigurer.java:85)
    	at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.enable(DefaultServletHandlerConfigurer.java:71)
    	at cn.sto.financial.estimate.interceptor.WebMvcConfig.configureDefaultServletHandling(WebMvcConfig.java:44)
    	at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultSephprvletHandlerMapping(WebMvcConfigurationSupport.java:644)
    	at 
    Disconnected from the target VM, address: '127.0.0.1:8711', transport: 'socket'
    
    Process finished with exit code 1
    

    Spring嵌入式Servlet容器提供的DefaultServlet不再注册,如果应用程序需要要它,需要进行一定的配置。

    3.1、方法1

    server.servlet.register-default-servlet=true
    

    3.2、方法2

    @SpringBootApplication
    public class StarterApplication {
        
        @Bean
        WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> enableDefaultServlet() {
            return factory -> factory.setRegisterDefaultServlet(true);
        }
        
        public static void main(String[] args) {
            Spring编程客栈Application.run(StarterApplication.class,args);
        }
    }
    

    四、debug运行报错

    项目debug报错如下:

    Error running ‘MallTest.testRun’: Command line is too long. Shorten command line for MallTest.testRun.

    出现这个的原因一般是因为项目需要打印的环境变量太长,超过了限制,需要你缩短命令行来解决问题。

    4.1、方法1

    修改运行配置Configurations,将默认的Shorten command line的值user-local default 改为 JAR mainifest 或者 classpath file,这种办法每次需要对每个类单独设置。

    SpringBoot项目启动报错踩坑实战记录

    4.2、方法2

    想一步到位,在项目的.idea/workspace.XML文件中添加配置,找到

    <component name="开发者_C教程PropertiesComponent"></component>
    

    在内部最下面添加一行

    <property name=android"dynamic.classpath" value="true" />

    这种方式一次设置就行。

    SpringBoot项目启动报错踩坑实战记录

    总结

    到此这篇关于SpringBoot项目启动报错踩坑的文章就介绍到这了,更多相关SpringBoot项目启动报错内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号