为什么当我在JUnit测试模式下执行Spring批处理作业时,Sping Boot Admin @EnableAdminServer会抛出此异常?(无法确定本地端口)

dtcbnfnu  于 2022-11-11  发布在  Spring
关注(0)|答案(2)|浏览(142)

我正在处理一个Spring Batch项目,当我执行单元测试方法测试整个作业时遇到以下问题。当我在JUnit测试模式下处理作业时,该问题似乎是由Sping Boot Admin工具引起的。
问题是我在我的控制台中获得了这个异常。这不是阻塞,我仍然可以测试我的作业,也可以调试它,但是让这个日志进入我的堆栈跟踪控制台是非常不舒服的(这是因为大约每5秒就会出现一个这种类型的新日志)。
只有在调试执行整个作业的单元测试时才会出现此异常。当执行作业时(不是在单元测试模式下),没有出现此异常。
这是我在堆栈跟踪控制台中每隔5秒获得的异常消息:

java.lang.IllegalStateException: couldn't determine local port. Please set spring.boot.admin.client.instance.service-base-url.
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getLocalServerPort(DefaultApplicationFactory.java:192) ~[spring-boot-admin-client-2.4.3.jar:2.4.3]
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getServiceBaseUrl(DefaultApplicationFactory.java:104) ~[spring-boot-admin-client-2.4.3.jar:2.4.3]
    at de.codecentric.boot.admin.client.registration.ServletApplicationFactory.getServiceUrl(ServletApplicationFactory.java:63) ~[spring-boot-admin-client-2.4.3.jar:2.4.3]
    at de.codecentric.boot.admin.client.registration.ServletApplicationFactory.getManagementBaseUrl(ServletApplicationFactory.java:76) ~[spring-boot-admin-client-2.4.3.jar:2.4.3]
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.getHealthUrl(DefaultApplicationFactory.java:154) ~[spring-boot-admin-client-2.4.3.jar:2.4.3]
    at de.codecentric.boot.admin.client.registration.DefaultApplicationFactory.createApplication(DefaultApplicationFactory.java:80) ~[spring-boot-admin-client-2.4.3.jar:2.4.3]
    at de.codecentric.boot.admin.client.registration.DefaultApplicationRegistrator.register(DefaultApplicationRegistrator.java:56) ~[spring-boot-admin-client-2.4.3.jar:2.4.3]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.3.9.jar:5.3.9]
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) ~[na:na]
    at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) ~[na:na]
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]

奇怪的是,当作业不是在Junit测试模式下运行时(当它的调度程序运行它时),我没有异常。
正如开头所说,问题的原因似乎是Sping Boot Admin工具,当我在JUnit测试模式下工作时。实际上,从应用程序类禁用**@EnableAdminServer**时,我没有这些异常。

@SpringBootApplication
@EnableBatchProcessing
@EnableScheduling
//@EnableAdminServer
public class UpdateInfoBatchApplication {

    public static void main(String[] args) {
        SpringApplication.run(UpdateInfoBatchApplication.class, args);
    }

}

为什么在JUnit测试模式下会出现这个错误?我的想法是,当我在测试模式下时,它没有检索某些属性(可能是这个spring. Boot .admin.client.instance.service-base-url)。奇怪的是,在我的application.properties文件中,我有这样的配置行:

spring.boot.admin.client.url=http://localhost:8080

(but而不是异常日志中指出的那个:spring. Boot .管理员.客户端.示例.服务库URL)
并插入到我的application-test.properties文件中(它应该是在Junit测试模式中使用的peroperties文件),我有相同的行:

spring.boot.admin.client.url=http://localhost:8080

好吧,避免出现这个恼人的异常非常简单,最后,我只能从我的UpdateInfoBatchApplication类中注解掉**@EnableAdminServer注解(包含main()方法的那个)。但是我想知道为什么我会得到这个错误,以及什么是好的解决方案(当我在测试模式下运行作业时,正确地检索导致异常的信息,或者类似于自动禁用@EnableAdminServer**注解之类的操作)。
为了完整性起见,请遵循我的JUnit测试类:

@SpringBootTest
@RunWith(SpringRunner.class)
@ContextConfiguration(classes={ TestBatchConfiguration.class, 
    UpdateNotaryListInfoJobTest.TestConfig.class, UpdateNotaryListInfoJobConfig.class})
@ActiveProfiles("test")
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public class UpdateNotaryListInfoJobTest 
{
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Configuration
    @ComponentScan({"com.xxx.service", "com.xxx.updateInfo.adapter"})
    public static class TestConfig {
        @Bean
        public JobLauncherTestUtils getJobLauncherTestUtils(){
            return new JobLauncherTestUtils() {
                @Autowired
                @Override
                public void setJob(@Qualifier("updateNotaryListInfoJob") Job job) {
                    super.setJob(job);
                }
            };
        }        
    }

    @Autowired
    private JobLauncherTestUtils jobLauncherTestUtils;

    @Test
    public void testUpdateNotaryListInfoJob() throws Exception {
        logger.info("Update Notary List Info Job Test STARTED");

        JobExecution jobExecution = jobLauncherTestUtils.launchJob();

        Assert.assertEquals("COMPLETED", jobExecution.getExitStatus().getExitCode());

        logger.info("Update Notary List Info Job Test COMPLETED");
    }    

}
fdbelqdn

fdbelqdn1#

您应该查看您的application.properties| yml。可能与src/main/resources中的属性相比,您缺少了一些属性。
这个问题可以解释您的2种不同行为(测试模式和运行模式)

5kgi1eie

5kgi1eie2#

正如所提到的,
使用@SpringBootTest运行测试在默认情况下会启动一个嵌入式服务器。默认情况下,它运行在MOCK环境中。
这解释了测试模式和运行模式之间的不同行为。例如,如果你使用SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT),那么嵌入式Tomcat将被启动,你将不会得到任何错误。
另一种防止该错误的方法是,通过在application-test.properties文件中添加以下行来禁用管理客户端

spring.boot.admin.client.enabled=false

相关问题