1

I am working on a Spring Batch project and I have the following problem when I execute a unit test method testing an entire job. The problem seems to be caused by Spring Boot Admin tool when I am in JUnit test mode on my job.

The problem is that I am obtaining this exception in my console. This is not blocking, I can still test my job and also debug it but it is very uncomfortable have this log into my stack trace console (this because approximately every 5 seconds it appears a new log of this type).

It appears only when I am debugging a unit test performing the entire job. When the job is executed (not in unit test mode) I have not this exception.

This is the exception message that I obtain every 5 seconds in my stack trace console:

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]

The strange thing is that when the job run not in Junit test mode (when its scheduler run it) I have no exception.

As said ad the beginning the cuase of the problem seems to be Spring Boot Admin tool when I am in JUnit test mode of my job. Infact disabling @EnableAdminServer from the application class I have not these exceptions.

@SpringBootApplication
@EnableBatchProcessing
@EnableScheduling
//@EnableAdminServer
public class UpdateInfoBatchApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(UpdateInfoBatchApplication.class, args);
    }
    
}

Why this error when I am in JUnit test mode? My idea is that when I am in testing mode it is not retrieving some properties (maybe this spring.boot.admin.client.instance.service-base-url). The strange thing is that into my application.properties file I have this configuration line:

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

(but not the one indicated in the exception log: spring.boot.admin.client.instance.service-base-url)

and into my application-test.properties file (it should be the peroperties file used in Junit test mode) I have the same line:

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

Ok it is pretty simple avoid to not have this annoying exception, at the end I can only comment out the @EnableAdminServer annotation from my UpdateInfoBatchApplication class (the one containing the main() method). But I want udersatnd why I am obtaining this error and what could be a good solution (correctly retrieve the information that cause the exception or something like automatically disable the @EnableAdminServer annotation when I am running the job in test mode). What could be a decent solution?

For the sake of completeness following my JUnit test class:

@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");
    }    
    
}
AndreaNobili
  • 40,955
  • 107
  • 324
  • 596
  • Do you use the same port for your Spring App and your Admin in the Junit Config? 8080 could be the standard port for spring itself – Marvin Feb 22 '22 at 13:44
  • @Marvin so what can I try to do? – AndreaNobili Feb 22 '22 at 13:47
  • Try changing spring.boot.admin.client.url=http://localhost:8080 to spring.boot.admin.client.url=http://localhost:8000 or something similar. It has to be an unused port though. If a config is not existant try adding a junit profile in test/resources – Marvin Feb 22 '22 at 14:14

2 Answers2

0

You shoud check your application.properties|yml in src/test/resources. Perhaps you are missing some properties compared to the one located in src/main/resources.

This issue could explain the 2 different behaviors you have (test mode & running mode)

sixrandanes
  • 2,483
  • 2
  • 11
  • 10
0

As metioned here,

Running a test with @SpringBootTest does start an embedded server by default. By default, it runs in the MOCK environment.

This explains the different behavior between test mode and running mode. For example if you use SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT), then embedded tomcat will be started and you will not get any error.

Another way to prevent the error, disabling admin client by adding the following line to your application-test.properties file

spring.boot.admin.client.enabled=false
Kasifibs
  • 76
  • 4