3

I have a springboot application in the form

src/main/java/example
 - Application.java
 - JobConfiguration.java
   scheduler
    - Job1.java
    - Job1Runner.java
    - Job2.java
    - Job2Runner.java

I like to be able to run my jobs on demand locally so I create a seperate Runner class for every job (e.g JobRunner.java) but currently when I run my Application class it also runs my Job1Runner class because it extends CommandLineRunner. Is there a way I can keep my runners seperate? (so the Application class doesnt run them, and the JobRunners dont run each other etc)

Application

@SpringBootApplication
public class Application {

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

JobConfiguration

@Configuration
@EnableScheduling
public class JobConfiguration implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // Register jobs
    }

}

Example JobRunner

@SpringBootApplication(scanBasePackages = "com.example")
public class JobXRunner implements CommandLineRunner { // Where X is my job index

    @Autowired
    private final JobX job;

    @Override
    public void run(String... args) throws Exception {
        job.run();
    }

    public static void main(String[] args) throws Exception {
        SpringApplication.run(JobXRunner.class, args);

    }
}
Eduardo
  • 6,900
  • 17
  • 77
  • 121
  • The whole purpose of `CommandLineRunner` is to run at startup. If you don't want that, don't implement it. – Abhijit Sarkar Nov 24 '17 at 18:54
  • 1
    @AbhijitSarkar I dont have to implement it. I'm just not aware of another way of doing it. – Eduardo Nov 24 '17 at 19:09
  • Another way of doing what? Your question states `CommandLineRunner` classes run at startup, and that's not what you want? Is this what you really want to do "run my jobs on demand locally"? – Abhijit Sarkar Nov 24 '17 at 19:11
  • @AbhijitSarkar Yep exactly what I want to do. I tried CommandLineRunner as I thought it would acheive what I want but its not meant for this purpose. – Eduardo Nov 24 '17 at 19:48
  • Does the answer I posted help? If not, please clarify in a comment why not. If it does help, go ahead and accept it. One of the biggest issues here is with people who ask for help, get it, but never acknowledge it. – Abhijit Sarkar Nov 27 '17 at 19:10
  • Here is an article on CommandLineRunner : -https://jhooq.com/commandlinerunner-spring-boot/ – Rahul Wagh May 26 '19 at 21:27

1 Answers1

1

There are more than one ways to solve this problem:

  1. Create multiple profiles and assign them to the job runners. Activate one from command line using spring.profiles.active=jobrunner1, or spring.profiles.active=jobrunner1,jobrunner2 if you want to run more than one job. This solution lets you keep multiple CommandLineRunner implementations.
  2. Specify which class to run, which in turn depends on how you're executing the code. If running using an IDE or a build tool like Maven or Gradle, you'll have to specify the main class name since the default resolution won't work. See this thread for a Maven-specific solution. If you're running the jar, see this thread. CommandLineRunner has a main method, so you can keep them, or just convert to regular main classes.
Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219
  • I guess this could work although feels a little much, I really was hoping for a way just to run a main method that can create some spring managed beans. The jobs are just development scripts that only get run inside an IDE so the simpler the process to run them the better. – Eduardo Nov 28 '17 at 08:47
  • @Edd If all you want is to run each file individually, just right click in your file, and choose run from the menu. Since you asked a question, I assumed you are looking for something beyond trivial. I didn't think you were looking for suggestions on how to execute a main class from your IDE. That'll work just fine as long as don't extend `CommandLineRunner` – Abhijit Sarkar Nov 28 '17 at 09:23
  • I'm perfectly fine creating main methods, its more "how do I then get Spring to create me all the beans I need in my script?" I had assumed CommandLineRunner was springs equivelent of doing this but its clearly for a different purpose like you say. – Eduardo Nov 28 '17 at 09:28
  • @Edd the beans are found by component scan, or you can create them manually in `@Configuration` classes. It sounds like you’re not clear about the spring configuration. If you’ve further questions, I suggest you create a [mvce](https://stackoverflow.com/help/mcve), so that we don’t end up wasting time on something that you don’t really need – Abhijit Sarkar Nov 28 '17 at 09:38