I'm experimenting with an ability of Spring Boot to start a main class supplied to it via -Dloader.main
parameter, as described in its documentation.
Currently we use Spring Boot 2.7.13.
Here's a simple shell for a sample Boot application with a main()
being executed:
@Slf4j
@SpringBootApplication
@PropertySource(value = "classpath:feeds-config.yml", factory = YamlPropertySourceFactory.class)
public class DownstreamDataFactoryApplication implements CommandLineRunner {
@Autowired
private DataAcquisitionService dataAcquisitionService;
@Autowired
private DataMarshallerService dataMarshallerService;
public static void main(String[] args) {
new SpringApplicationBuilder(DownstreamDataFactoryApplication.class)
.web(WebApplicationType.NONE)
.run(args);
}
@Override
public void run(String... args) throws Exception {
log.debug("Starting execution");
for (int i = 0; i < args.length; ++i) {
log.info("args[{}]: {}", i, args[i]);
}
//read data
Map<String, Object> context = new HashMap<>();
//Flux<?> data = dataAcquisitionService.obtainData(context);
List<?> data = dataAcquisitionService.obtainData(context);
log.info("Obtained data: "+data);
//process data
log.info("Processed data: ");
//write data
//log.debug("Report saved to {}", dataMarshallerService.getOutputFileLocation());
//log.debug("Ending execution");
log.info("Marshalled data to a file: ");
//distribute data
log.info("Send marshalled data to a remote location: ");
}
}
My goal is to have several independent Spring Boot applications segregated by package structure in the codebase such that depending on what's being passed via -Dloader.main
different Boot application is being run.
Consequently, the mainClass
stanza in spring-boot-maven-plugin
's section is disabled:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<mainClass>
<!--
com.p.g.f.d.DownstreamDataFactoryApplication
-->
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M6</version>
</plugin>
So far, so good.
What I'm noticing is that the runtime seems to behave exactly the same whether I'm passing the org.springframework.boot.loader.PropertiesLauncher
as a second argument or not.
Here's what the output looks like with the org.springframework.boot.loader.PropertiesLauncher
being supplied:
>java -jar target\downstream-data-factory-0.0.1-SNAPSHOT.jar -Dloader.main=com.xxx.globalpayments.feeds.downstream.DownstreamDataFactoryApplication org.springframework.boot.loader.PropertiesLauncher
2023-07-31 16:14:03.287 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Started DownstreamDataFactoryApplication in 2.981 seconds (JVM running for 4.425)
2023-07-31 16:14:03.291 [main] DEBUG o.s.b.a.ApplicationAvailabilityBean - Application availability state LivenessState changed to CORRECT
2023-07-31 16:14:03.292 [main] DEBUG c.p.g.f.d.DownstreamDataFactoryApplication - Starting execution
2023-07-31 16:14:03.293 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - args[0]: -Dloader.main=com.pru.globalpayments.feeds.downstream.DownstreamDataFactoryApplication
2023-07-31 16:14:03.293 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - args[1]: org.springframework.boot.loader.PropertiesLauncher
2023-07-31 16:14:03.294 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Obtained data: null
2023-07-31 16:14:03.295 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Processed data:
2023-07-31 16:14:03.296 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Marshalled data to a file:
2023-07-31 16:14:03.297 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Marshalled data to a remote location:
2023-07-31 16:14:03.300 [main] DEBUG o.s.b.a.ApplicationAvailabilityBean - Application availability state ReadinessState changed to ACCEPTING_TRAFFIC
2023-07-31 16:14:03.306 [SpringApplicationShutdownHook] DEBUG o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6c130c45, started on Mon Jul 31 16:14:01 EDT 2023
2023-07-31 16:14:03.310 [SpringApplicationShutdownHook] DEBUG o.s.c.s.DefaultLifecycleProcessor - Stopping beans in phase -2147483647
2023-07-31 16:14:03.311 [SpringApplicationShutdownHook] DEBUG o.s.c.s.DefaultLifecycleProcessor - Bean 'springBootLoggingLifecycle' completed its stop procedure
and without it being supplied:
>java -jar target\downstream-data-factory-0.0.1-SNAPSHOT.jar -Dloader.main=com.xxx.globalpayments.feeds.downstream.DownstreamDataFactoryApplication
2023-07-31 16:18:39.720 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Started DownstreamDataFactoryApplication in 2.931 seconds (JVM running for 4.313)
2023-07-31 16:18:39.725 [main] DEBUG o.s.b.a.ApplicationAvailabilityBean - Application availability state LivenessState changed to CORRECT
2023-07-31 16:18:39.726 [main] DEBUG c.p.g.f.d.DownstreamDataFactoryApplication - Starting execution
2023-07-31 16:18:39.726 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - args[0]: -Dloader.main=com.pru.globalpayments.feeds.downstream.DownstreamDataFactoryApplication
2023-07-31 16:18:39.728 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Obtained data: null
2023-07-31 16:18:39.728 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Processed data:
2023-07-31 16:18:39.729 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Marshalled data to a file:
2023-07-31 16:18:39.729 [main] INFO c.p.g.f.d.DownstreamDataFactoryApplication - Marshalled data to a remote location:
2023-07-31 16:18:39.731 [main] DEBUG o.s.b.a.ApplicationAvailabilityBean - Application availability state ReadinessState changed to ACCEPTING_TRAFFIC
2023-07-31 16:18:39.734 [SpringApplicationShutdownHook] DEBUG o.s.c.a.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@6c130c45, started on Mon Jul 31 16:18:37 EDT 2023
2023-07-31 16:18:39.739 [SpringApplicationShutdownHook] DEBUG o.s.c.s.DefaultLifecycleProcessor - Stopping beans in phase -2147483647
2023-07-31 16:18:39.740 [SpringApplicationShutdownHook] DEBUG o.s.c.s.DefaultLifecycleProcessor - Bean 'springBootLoggingLifecycle' completed its stop procedure
My assumption was that the org.springframework.boot.loader.PropertiesLauncher
carries within itself certain keys that the mainclass-less invocation via -Dloader.main=AppwithMainMethod
would be dependent upon and would otherwise failed, but it doesn't seem to be the case.
What are the proper use cases for this PropertiesLauncher
parameter with some samples and documentation? Is it optional? Required? Can one safely skip supplying it? When?
Thank you in advance.