Reputation: 1025
I have seen many solutions for the problem of getting a port from the command line. But I am interested in the following problem. I want the launch to be a line
-p 9030 -t JDBC -sql postgresql
As you can see, it is important for me that the port is set using the "-p " parameter.
NOT
-Dspring-boot.run.arguments=--server.port=8085
I have some variables that need to be retrieved, before running the spring context. I have a crutch solution, directly catching arguments and overwriting them. But I have a large number of input parameters and my solution looks ugly (see the picture) I will be glad to hear your advice.
Upvotes: 0
Views: 1873
Reputation: 3739
You could also use Airline 2. Airline 2 is a Java library providing an annotation-based framework for parsing command line interfaces.
Airline 2 is focused on building command-line applications, so it might be an overkill if you just want to parse some arguments. 馃檪
Definition of a command with its arguments:
@Command(name = "run", description = "Run application")
public static class RunCmd implements Runnable {
@Option(name = {"-p", "--port"}, description = "The server's port.")
public int port = 8080;
public void run() {
runCmd = this;
SpringApplication.run(App.class);
}
}
Here's a example which uses TomcatServletWebServerFactory
to configure the server port:
@Cli(name = "App", commands = {App.RunCmd.class})
@SpringBootApplication
public class App {
@Command(name = "run", description = "Run application")
public static class RunCmd implements Runnable {
@Option(name = { "-p", "--port" }, description = "The server's port.")
public int port = 8080;
public void run() {
runCmd = this;
SpringApplication.run(App.class);
}
}
private static com.github.rvesse.airline.Cli<Runnable> cli;
private static RunCmd runCmd;
public static void main(String[] args) throws IOException {
cli = new com.github.rvesse.airline.Cli<>(App.class);
ParseResult<Runnable> parseResult = parseArguments(args);
if (parseResult != null) {
executeCommand(parseResult);
} else {
showUsage();
}
}
private static ParseResult<Runnable> parseArguments(String[] args) {
try {
return cli.parseWithResult(args);
} catch (ParseCommandMissingException e) {
return null;
} catch (ParseException e) {
System.out.println("Invalid arguments: " + e.getMessage());
throw e;
}
}
private static void executeCommand(ParseResult<Runnable> parseResult) {
Runnable r = parseResult.getCommand();
r.run();
}
private static void showUsage() throws IOException {
GlobalUsageGenerator<Runnable> helpGenerator = new CliGlobalUsageGenerator<>();
helpGenerator.usage(cli.getMetadata(), System.out);
}
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(connector -> connector.setPort(runCmd.port));
return factory;
}
}
Upvotes: 2
Reputation: 3739
You can use TomcatServletWebServerFactory
to configure the server port.
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(connector -> connector.setPort(port));
return factory;
}
Here's a little example which uses a static field to hold the port number, so it can later be used at the bean creation.
@SpringBootApplication
public class App {
private static int port;
public static void main(String[] args) throws Exception {
Options options = createOptions();
parseOptions(options, args);
SpringApplication.run(App.class);
}
private static Options createOptions() {
Option portOption = Option.builder("p")
.desc("The server's port")
.longOpt("port")
.hasArg(true)
.type(Integer.class)
.required(true)
.build();
Options options = new Options();
options.addOption(portOption);
return options;
}
private static void parseOptions(Options options, String[] args) throws Exception {
CommandLineParser parser = new DefaultParser();
CommandLine commandLine;
try {
commandLine = parser.parse(options, args);
} catch (ParseException e) {
System.out.println("Could not parse arguments!");
throw e;
}
try {
port = Integer.parseInt(commandLine.getOptionValue("p"));
} catch (NumberFormatException e) {
System.out.println("Could not parse port argument value!");
throw e;
}
}
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
factory.addConnectorCustomizers(connector -> connector.setPort(port));
return factory;
}
}
Upvotes: 1