Reputation: 689
I have a Springboot application that runs a CLI app.
Here's my main class:
@SpringBootApplication
public class MyApplication {
@Autowired
GameClient gameClient;
@PostConstruct
public void postConstruct(){
gameClient.runGame();
}
public static void main(String[] args) {
SpringApplication.run(GameApplication.class, args);
}
}
When I run the command mvn package
to generate a JAR, Spring executes the postConstruct()
method and starts my CLI application instead of properly generating my JAR.
When I remove the postConstruct()
the JAR is successfully generated, but I need this method becaus it is responsible for running my CLI app.
How can I solve it?
Upvotes: 2
Views: 1396
Reputation: 11
First you need to update in pom file.
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.eg</groupId>
<artifactId>eg</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
then run this command (mvn package -Dmaven.test.skip=true)
Upvotes: 0
Reputation: 44665
The issue is that gameClient.runGame()
appears to block your test, either by running infinitely, or by requesting user input. If you have any tests running your Spring boot application, your test (and your build) will block as well.
Even though you can pass the -Dmaven.test.skip=true
parameter to skip tests (as mentioned in this answer), it still means that that specific test is broken. Either remove it if you don't need it, or make sure that gameClient.runGame()
isn't invoked during a test by doing the following:
Move your logic to a separate class that implements the CommandLineRunner
(or ApplicationRunner
) interface:
@Component
public class GameRunner implements CommandLineRunner {
@Autowired
GameClient gameClient;
@Override
public void run(String...args) throws Exception {
gameClient.runGame();
}
}
After that, annotate the component with the @Profile
annotation, for example:
@Component
@Profile("!test") // Add this
public class GameRunner implements CommandLineRunner {
@Autowired
GameClient gameClient;
@Override
public void run(String...args) throws Exception {
gameClient.runGame();
}
}
By using the @Profile
annotation, you can tell Spring to only load the component when certain profiles are active. By using the exclamination mark !
, we tell Spring to only load the component if the test profile is not active.
Now, within your test, you can add the @ActiveProfiles("test")
annotation. This will enable the test profile when running the test, and that means that the GameRunner
bean will not be created.
Upvotes: 2
Reputation: 689
I solved it by skiping the tests when generationg the JAR:
mvn package -Dmaven.test.skip=true
mvn package
was invoking my tests, which internally initialized all the beans and, as part of initialization, Spring invokes @PostConstruct
methods.
Upvotes: 2