Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defining "spring.config.location" causes picocli parser to fail. #604

Closed
alistairrutherford opened this issue Jan 14, 2019 · 7 comments
Closed
Milestone

Comments

@alistairrutherford
Copy link

The Spring Boot parameter 'spring.config.location' allows you to specify an alternative location for your application.properties file. When I attempted to pass this along with other picocli define parameters it causes the parser to fail and I get help message. The only way I could get this to work was to define the 'spring.config.location' as an optional parameter. I can see why you wouldn't want to add special handling for spring boot for this so you might want to put a note into the documentation.

@remkop
Copy link
Owner

remkop commented Jan 14, 2019

Thanks for raising this!
Improving Spring support is on the todo list so this is very useful!

My first thought is that defining --spring.config.location as a (non-required) option in the application is a good workaround. You may consider defining this as a “hidden” option if you don’t want this option to appear in the usage help message.

I’ll probably add a Spring Integration section to the user manual. Any other things that should be mentioned in this section?

@remkop remkop added this to the 3.9.2 milestone Jan 14, 2019
@remkop
Copy link
Owner

remkop commented Jan 16, 2019

@alistairrutherford Would you mind sharing (a potentially simplified version of) your code to show how to integrate picocli-based commands with Spring?

@alistairrutherford
Copy link
Author

alistairrutherford commented Jan 17, 2019

In order to use picocli with Spring Boot you create an application based on CommandLineRunner I.e.

@SpringBootApplication
public class MyApplication implements CommandLineRunner {

	@Autowired
	private MyRunner  myRunner;
	
	public static void main(String[] args) {
		SpringApplication.run(UserServiceApplication.class, args);
	}

	/**
	 * Main run method.
	 * 
	 */
	@Override
	public void run(String... args) {
		logger.info("EXECUTING : command line runner");

		CommandLine.call(myRunner, args);
	}
}

The class MyRunner is a Callable class which implements the main functionality:

@Component
@Command(name = "My Runner", mixinStandardHelpOptions = true, version = "My runner 1.0")
public class MyRunner implements Callable<Void> {

	@Option(names = { "-v", "--verbose" }, description = "Verbose mode. Helpful for troubleshooting. Multiple -v options increase the verbosity.")
	private boolean[] verbose = new boolean[0];
	
	@Option(names = { "-p1", "--param1" }, paramLabel = "Sample Param 1", description = "the sample param 1", required=true)
	private File sampleParam1;

	@Option(names = { "-p2", "--param2" }, paramLabel = "Sample Param 2", description = "the sample param 2", required=true)
	private File sampleParam1;

	@Option(names = { "--spring.config.location"}, paramLabel = "Config File", description = "the target config file", required=false, hidden=true)
	private String springConfigLocation;
	
	/**
	 * Construct service.
	 * 
	 * @param userService
	 */
	public MyRunner() {
        // Do stuff
	}
	
	/**
	 * Execute
	 * 
	 */
	@Override
	public Void call() throws Exception {

        // Do stuff

		return null;
	}
}

Note, in order the allow the Spring Boot application to accept the "spring.config.location" you simply add it to your Callable element. This will allow Spring boot to pick it up and stop picocli rejecting an unknown parameter.

You would follow this pattern for any other Spring Boot parameter you required.

@remkop
Copy link
Owner

remkop commented Jan 17, 2019

Perfect, thank you!

@remkop remkop closed this as completed in 67e40e0 Jan 19, 2019
@remkop
Copy link
Owner

remkop commented Jan 19, 2019

For the next release, I updated the user manual: Dependency Injection is now a top-level section, with subsections for Guice, Spring Boot and Micronaut.

I used your code to create the Spring Boot example, and mentioned the --spring.config.location tip.
Can you verify?

If you run gradlew ascii the updated user manual is generated in build/docs/html5/index.html.

remkop added a commit that referenced this issue Jan 19, 2019
@alistairrutherford
Copy link
Author

alistairrutherford commented Jan 22, 2019

I have reviewed the documentation section and it's looks fine.

@remkop
Copy link
Owner

remkop commented Jan 22, 2019

Thanks for the confirmation!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants