Related
in order to make use of Machine Learning in Java, I'm trying to train a model in TensorFlow, save it as ONNX file and then use the file for inference in Java. While this works fine with simple models, it's getting more complicated using pre-processing layers, as they seem to depend on custom operators.
https://www.tensorflow.org/tutorials/keras/text_classification
As an example, this Colab deals with text classification and uses an TextVectorization layer this way:
#tf.keras.utils.register_keras_serializable()
def custom_standardization2(input_data):
lowercase = tf.strings.lower(input_data)
stripped_html = tf.strings.regex_replace(lowercase, '<br />',' ')
return tf.strings.regex_replace(stripped_html, '[%s]' % re.escape(string.punctuation), '')
vectorize_layer = layers.TextVectorization(
standardize=custom_standardization2,
max_tokens=max_features,
output_mode='int',
output_sequence_length=sequence_length
)
It is used as pre-processing layer in the compiled model:
export_model = tf.keras.Sequential([
vectorize_layer,
model,
layers.Activation('sigmoid')
])
export_model.compile(loss=losses.BinaryCrossentropy(from_logits=False), optimizer="adam", metrics=['accuracy'])
In order to create the ONNX file I save the model as protobuf and then convert it to ONNX:
export_model.save("saved_model")
python -m tf2onnx.convert --saved-model saved_model --output saved_model.onnx --extra_opset ai.onnx.contrib:1 --opset 11
Using onnxruntime-extensions it is now possible to register the custom ops and to run the model in Python for inference.
import onnxruntime
from onnxruntime import InferenceSession
from onnxruntime_extensions import get_library_path
so = onnxruntime.SessionOptions()
so.register_custom_ops_library(get_library_path())
session = InferenceSession('saved_model.onnx', so)
res = session.run(None, { 'text_vectorization_2_input': example_new })
This raises the question if it's possible to use the same model in Java in a similar way. Onnxruntime for Java does have a SessionOptions#registerCustomOpLibrary function, so I thought of something like this:
OrtEnvironment env = OrtEnvironment.getEnvironment();
OrtSession.SessionOptions options = new OrtSession.SessionOptions();
options.registerCustomOpLibrary(""); // reference the library
OrtSession session = env.createSession("...", options);
Does anyone have an idea if the use case described is feasable or how to use models with pre-processing layers in Java (without using TensorFlow Java)?
UPDATE:
Spotted a potential solution. If I understand the comments in this GitHub Issue correctly, one possibility is to build the ONNXRuntime Extensions package from source (see this explanation) and reference the generated library file by calling registerCustomOpLibrary in the ONNX Runtime Library for Java. However, as I have no experience with tools like cmake this might become a challenge for me.
The solution you propose in your update is correct, you need to compile the ONNX Runtime extension package from source to get the dll/so/dylib, and then you can load that into ONNX Runtime in Java using the session options. The Python whl doesn't distribute the binary in a format that can be loaded outside of Python, so compiling from source is the only option. I wrote the ONNX Runtime Java API, so if this approach fails open an issue on Github and we'll fix it.
Is there any code (Java, for example) that creates a file in .xml format and saves it in a folder?
I can't find...
I've searched in several places, but to no success. =//
Thanks in advance!
Have you really tried to search? There is an official documentation for Java, i.e. check Writing Out a DOM as an XML File guide
Also be aware that there is no Java support in JMeter (unless you decide to develop your own plugin) and it's recommended to use Groovy for scripting so it might be a better idea to look for code to copy and paste in Groovy documentation. A quote from the above page:
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.records() {
car(name: 'HSV Maloo', make: 'Holden', year: 2006) {
country('Australia')
record(type: 'speed', 'Production Pickup Truck with speed of 271kph')
}
car(name: 'Royale', make: 'Bugatti', year: 1931) {
country('France')
record(type: 'price', 'Most Valuable Car at $15 million')
}
}
def records = new XmlSlurper().parseText(writer.toString())
To my knowledge, there aren't any out of box features in JMeter to process XML. You can use Groovy XML objects/operations to read/write XML
I am using cucumber for ui testing written in java. I am trying to implement the cucumber plugin for rerunning failed scenarios, and created a second class to be the runner for those scenarios:
first class
#RunWith(Cucumber.class)
#CucumberOptions(
monochrome = true,
strict = true,
tags = {"#lakeisha"},
features = ".",
format = {"html:target/cucumber", "json:target/cucumber.json"},
plugin = {
"pretty", "html:target/cucumber-reports",
"json:target/cucumber.json",
"rerun:src/test/resources/rerun.txt" //Creates a text file with failed scenarios
})
public class RunCukeTestsIT extends BaseCucumberRunner {
}
second class:
#RunWith(Cucumber.class)
#CucumberOptions(
monochrome = true,
tags = {"#lakeisha"},
features = "#src/test/resources/rerun.txt", //Cucumber picks the failed scenarios from this file
format = {"html:target/cucumber", "json:target/cucumber.json"}
)
public class ReRunCukeTestsIT extends BaseCucumberRunner{
}
and i am running the tests using
mvn clean verify -Dcucumber.options=" --tags #lakeisha"
the problem is that running it through terminal doesn't seem to generate anything in the rerun.txt, but running it through IJ does. I also tried putting the plugin into Dcucumber.options portion of command, to no avail . Help much appreciated!
What is a good way of parsing command line arguments in Java?
Check these out:
http://commons.apache.org/cli/
http://www.martiansoftware.com/jsap/
Or roll your own:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
For instance, this is how you use commons-cli to parse 2 string arguments:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws Exception {
Options options = new Options();
Option input = new Option("i", "input", true, "input file path");
input.setRequired(true);
options.addOption(input);
Option output = new Option("o", "output", true, "output file");
output.setRequired(true);
options.addOption(output);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd = null;//not a good practice, it serves it purpose
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("utility-name", options);
System.exit(1);
}
String inputFilePath = cmd.getOptionValue("input");
String outputFilePath = cmd.getOptionValue("output");
System.out.println(inputFilePath);
System.out.println(outputFilePath);
}
}
usage from command line:
$> java -jar target/my-utility.jar -i asd
Missing required option: o
usage: utility-name
-i,--input <arg> input file path
-o,--output <arg> output file
Take a look at the more recent JCommander.
I created it. I’m happy to receive questions or feature requests.
I have been trying to maintain a list of Java CLI parsers.
Airline
Active Fork: https://github.com/rvesse/airline
argparse4j
argparser
args4j
clajr
cli-parser
CmdLn
Commandline
DocOpt.java
dolphin getopt
DPML CLI (Jakarta Commons CLI2 fork)
Dr. Matthias Laux
Jakarta Commons CLI
jargo
jargp
jargs
java-getopt
jbock
JCLAP
jcmdline
jcommander
jcommando
jewelcli (written by me)
JOpt simple
jsap
naturalcli
Object Mentor CLI article (more about refactoring and TDD)
parse-cmd
ritopt
Rop
TE-Code Command
picocli has ANSI colorized usage help and autocomplete
It is 2022, time to do better than Commons CLI... :-)
Should you build your own Java command line parser, or use a library?
Many small utility-like applications probably roll their own command line parsing to avoid the additional external dependency. picocli may be an interesting alternative.
Picocli is a modern library and framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It lives in 1 source file so apps can include it as source to avoid adding a dependency.
It supports colors, autocompletion, subcommands, and more. Written in Java, usable from Groovy, Kotlin, Scala, etc.
Features:
Annotation based: declarative, avoids duplication and expresses programmer intent
Convenient: parse user input and run your business logic with one line of code
Strongly typed everything - command line options as well as positional parameters
POSIX clustered short options (<command> -xvfInputFile as well as <command> -x -v -f InputFile)
Fine-grained control: an arity model that allows a minimum, maximum and variable number of parameters, e.g, "1..*", "3..5"
Subcommands (can be nested to arbitrary depth)
Feature-rich: composable arg groups, splitting quoted args, repeatable subcommands, and many more
User-friendly: usage help message uses colors to contrast important elements like option names from the rest of the usage help to reduce the cognitive load on the user
Distribute your app as a GraalVM native image
Works with Java 5 and higher
Extensive and meticulous documentation
The usage help message is easy to customize with annotations (without programming). For example:
(source)
I couldn't resist adding one more screenshot to show what usage help messages are possible. Usage help is the face of your application, so be creative and have fun!
Disclaimer: I created picocli. Feedback or questions very welcome.
Someone pointed me to args4j lately which is annotation based. I really like it!
I've used JOpt and found it quite handy: http://jopt-simple.sourceforge.net/
The front page also provides a list of about 8 alternative libraries, check them out and pick the one that most suits your needs.
I know most people here are going to find 10 million reasons why they dislike my way, but nevermind. I like to keep things simple, so I just separate the key from the value using a '=' and store them in a HashMap like this:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
You could always maintain a list with the arguments you are expecting, to help the user in case he forgot an argument or used a wrong one... However, if you want too many features this solution is not for you anyway.
This is Google's command line parsing library open-sourced as part of the Bazel project. Personally I think it's the best one out there, and far easier than Apache CLI.
https://github.com/pcj/google-options
Installation
Bazel
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)
Gradle
dependencies {
compile 'com.github.pcj:google-options:1.0.0'
}
Maven
<dependency>
<groupId>com.github.pcj</groupId>
<artifactId>google-options</artifactId>
<version>1.0.0</version>
</dependency>
Usage
Create a class that extends OptionsBase and defines your #Option(s).
package example;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;
/**
* Command-line options definition for example server.
*/
public class ServerOptions extends OptionsBase {
#Option(
name = "help",
abbrev = 'h',
help = "Prints usage info.",
defaultValue = "true"
)
public boolean help;
#Option(
name = "host",
abbrev = 'o',
help = "The server host.",
category = "startup",
defaultValue = ""
)
public String host;
#Option(
name = "port",
abbrev = 'p',
help = "The server port.",
category = "startup",
defaultValue = "8080"
)
public int port;
#Option(
name = "dir",
abbrev = 'd',
help = "Name of directory to serve static files.",
category = "startup",
allowMultiple = true,
defaultValue = ""
)
public List<String> dirs;
}
Parse the arguments and use them.
package example;
import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;
public class Server {
public static void main(String[] args) {
OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
parser.parseAndExitUponError(args);
ServerOptions options = parser.getOptions(ServerOptions.class);
if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
printUsage(parser);
return;
}
System.out.format("Starting server at %s:%d...\n", options.host, options.port);
for (String dirname : options.dirs) {
System.out.format("\\--> Serving static files at <%s>\n", dirname);
}
}
private static void printUsage(OptionsParser parser) {
System.out.println("Usage: java -jar server.jar OPTIONS");
System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
OptionsParser.HelpVerbosity.LONG));
}
}
https://github.com/pcj/google-options
Take a look at the Commons CLI project, lots of good stuff in there.
Yeap.
I think you're looking for something like this:
http://commons.apache.org/cli
The Apache Commons CLI library provides an API for processing command line interfaces.
If you are already using Spring Boot, argument parsing comes out of the box.
If you want to run something after startup, implement the ApplicationRunner interface:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(ApplicationArguments args) {
args.containsOption("my-flag-option"); // test if --my-flag-option was set
args.getOptionValues("my-option"); // returns values of --my-option=value1 --my-option=value2
args.getOptionNames(); // returns a list of all available options
// do something with your args
}
}
Your run method will be invoked after the context has started up successfully.
If you need access to the arguments before you fire up your application context, you can just simply parse the application arguments manually:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
ApplicationArguments arguments = new DefaultApplicationArguments(args);
// do whatever you like with your arguments
// see above ...
SpringApplication.run(Application.class, args);
}
}
And finally, if you need access to your arguments in a bean, just inject the ApplicationArguments:
#Component
public class MyBean {
#Autowired
private ApplicationArguments arguments;
// ...
}
Maybe these
JArgs command line option parsing
suite for Java - this tiny project provides a convenient, compact, pre-packaged and comprehensively documented suite of command line option parsers for the use of Java programmers. Initially, parsing compatible with GNU-style 'getopt' is provided.
ritopt, The Ultimate Options Parser for Java - Although, several command line option standards have been preposed, ritopt follows the conventions prescribed in the opt package.
I wrote another one: http://argparse4j.sourceforge.net/
Argparse4j is a command line argument parser library for Java, based on Python's argparse.
If you are familiar with gnu getopt, there is a Java port at: http://www.urbanophile.com/arenn/hacking/download.htm.
There appears to be a some classes that do this:
http://docs.sun.com/source/816-5618-10/netscape/ldap/util/GetOpt.html
http://xml.apache.org/xalan-j/apidocs/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.html
airline # Github looks good. It is based on annotation and is trying to emulate Git command line structures.
Argparse4j is best I have found. It mimics Python's argparse libary which is very convenient and powerful.
I want to show you my implementation: ReadyCLI
Advantages:
for lazy programmers: a very small number of classes to learn, just see the two small examples on the README in the repository and you are already at 90% of learning; just start coding your CLI/Parser without any other knowledge;
ReadyCLI allows coding CLIs in the most natural way;
it is designed with Developer Experience in mind; it largely uses the Builder design pattern and functional interfaces for Lambda Expressions, to allow a very quick coding;
it supports Options, Flags and Sub-Commands;
it allows to parse arguments from command-line and to build more complex and interactive CLIs;
a CLI can be started on Standard I/O just as easily as on any other I/O interface, such as sockets;
it gives great support for documentation of commands.
I developed this project as I needed new features (options, flag, sub-commands) and that could be used in the simplest possible way in my projects.
If you want something lightweight (jar size ~ 20 kb) and simple to use, you can try argument-parser. It can be used in most of the use cases, supports specifying arrays in the argument and has no dependency on any other library. It works for Java 1.5 or above. Below excerpt shows an example on how to use it:
public static void main(String[] args) {
String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
InputData inputData = (InputData) argParser.parse(args);
showData(inputData);
new StatsGenerator().generateStats(inputData);
}
More examples can be found here
As one of the comments mentioned earlier (https://github.com/pcj/google-options) would be a good choice to start with.
One thing I want to add-on is:
1) If you run into some parser reflection error, please try use a newer version of the guava. in my case:
maven_jar(
name = "com_google_guava_guava",
artifact = "com.google.guava:guava:19.0",
server = "maven2_server",
)
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
server = "maven2_server",
)
maven_server(
name = "maven2_server",
url = "http://central.maven.org/maven2/",
)
2) When running the commandline:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) When you need the usage help, just type:
bazel run path/to/your:project -- --help
Take a look at Spring Shell
Spring Shell’s features include
A simple, annotation driven, programming model to contribute custom commands
Use of Spring Boot auto-configuration functionality as the basis for a command plugin strategy
Tab completion, colorization, and script execution
Customization of command prompt, shell history file name, handling of results and errors
Dynamic enablement of commands based on domain specific criteria
Integration with the bean validation API
Already built-in commands, such as clear screen, gorgeous help, exit
ASCII art Tables, with formatting, alignment, fancy borders, etc.
For Spring users, we should mention also https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html and his twin brother https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/JOptCommandLinePropertySource.html (JOpt implementation of the same functionality).
The advantage in Spring is that you can directly bind the command line arguments to attributes, there is an example here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/CommandLinePropertySource.html
What is a good way of parsing command line arguments in Java?
Check these out:
http://commons.apache.org/cli/
http://www.martiansoftware.com/jsap/
Or roll your own:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
For instance, this is how you use commons-cli to parse 2 string arguments:
import org.apache.commons.cli.*;
public class Main {
public static void main(String[] args) throws Exception {
Options options = new Options();
Option input = new Option("i", "input", true, "input file path");
input.setRequired(true);
options.addOption(input);
Option output = new Option("o", "output", true, "output file");
output.setRequired(true);
options.addOption(output);
CommandLineParser parser = new DefaultParser();
HelpFormatter formatter = new HelpFormatter();
CommandLine cmd = null;//not a good practice, it serves it purpose
try {
cmd = parser.parse(options, args);
} catch (ParseException e) {
System.out.println(e.getMessage());
formatter.printHelp("utility-name", options);
System.exit(1);
}
String inputFilePath = cmd.getOptionValue("input");
String outputFilePath = cmd.getOptionValue("output");
System.out.println(inputFilePath);
System.out.println(outputFilePath);
}
}
usage from command line:
$> java -jar target/my-utility.jar -i asd
Missing required option: o
usage: utility-name
-i,--input <arg> input file path
-o,--output <arg> output file
Take a look at the more recent JCommander.
I created it. I’m happy to receive questions or feature requests.
I have been trying to maintain a list of Java CLI parsers.
Airline
Active Fork: https://github.com/rvesse/airline
argparse4j
argparser
args4j
clajr
cli-parser
CmdLn
Commandline
DocOpt.java
dolphin getopt
DPML CLI (Jakarta Commons CLI2 fork)
Dr. Matthias Laux
Jakarta Commons CLI
jargo
jargp
jargs
java-getopt
jbock
JCLAP
jcmdline
jcommander
jcommando
jewelcli (written by me)
JOpt simple
jsap
naturalcli
Object Mentor CLI article (more about refactoring and TDD)
parse-cmd
ritopt
Rop
TE-Code Command
picocli has ANSI colorized usage help and autocomplete
It is 2022, time to do better than Commons CLI... :-)
Should you build your own Java command line parser, or use a library?
Many small utility-like applications probably roll their own command line parsing to avoid the additional external dependency. picocli may be an interesting alternative.
Picocli is a modern library and framework for building powerful, user-friendly, GraalVM-enabled command line apps with ease. It lives in 1 source file so apps can include it as source to avoid adding a dependency.
It supports colors, autocompletion, subcommands, and more. Written in Java, usable from Groovy, Kotlin, Scala, etc.
Features:
Annotation based: declarative, avoids duplication and expresses programmer intent
Convenient: parse user input and run your business logic with one line of code
Strongly typed everything - command line options as well as positional parameters
POSIX clustered short options (<command> -xvfInputFile as well as <command> -x -v -f InputFile)
Fine-grained control: an arity model that allows a minimum, maximum and variable number of parameters, e.g, "1..*", "3..5"
Subcommands (can be nested to arbitrary depth)
Feature-rich: composable arg groups, splitting quoted args, repeatable subcommands, and many more
User-friendly: usage help message uses colors to contrast important elements like option names from the rest of the usage help to reduce the cognitive load on the user
Distribute your app as a GraalVM native image
Works with Java 5 and higher
Extensive and meticulous documentation
The usage help message is easy to customize with annotations (without programming). For example:
(source)
I couldn't resist adding one more screenshot to show what usage help messages are possible. Usage help is the face of your application, so be creative and have fun!
Disclaimer: I created picocli. Feedback or questions very welcome.
Someone pointed me to args4j lately which is annotation based. I really like it!
I've used JOpt and found it quite handy: http://jopt-simple.sourceforge.net/
The front page also provides a list of about 8 alternative libraries, check them out and pick the one that most suits your needs.
I know most people here are going to find 10 million reasons why they dislike my way, but nevermind. I like to keep things simple, so I just separate the key from the value using a '=' and store them in a HashMap like this:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
You could always maintain a list with the arguments you are expecting, to help the user in case he forgot an argument or used a wrong one... However, if you want too many features this solution is not for you anyway.
This is Google's command line parsing library open-sourced as part of the Bazel project. Personally I think it's the best one out there, and far easier than Apache CLI.
https://github.com/pcj/google-options
Installation
Bazel
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)
Gradle
dependencies {
compile 'com.github.pcj:google-options:1.0.0'
}
Maven
<dependency>
<groupId>com.github.pcj</groupId>
<artifactId>google-options</artifactId>
<version>1.0.0</version>
</dependency>
Usage
Create a class that extends OptionsBase and defines your #Option(s).
package example;
import com.google.devtools.common.options.Option;
import com.google.devtools.common.options.OptionsBase;
import java.util.List;
/**
* Command-line options definition for example server.
*/
public class ServerOptions extends OptionsBase {
#Option(
name = "help",
abbrev = 'h',
help = "Prints usage info.",
defaultValue = "true"
)
public boolean help;
#Option(
name = "host",
abbrev = 'o',
help = "The server host.",
category = "startup",
defaultValue = ""
)
public String host;
#Option(
name = "port",
abbrev = 'p',
help = "The server port.",
category = "startup",
defaultValue = "8080"
)
public int port;
#Option(
name = "dir",
abbrev = 'd',
help = "Name of directory to serve static files.",
category = "startup",
allowMultiple = true,
defaultValue = ""
)
public List<String> dirs;
}
Parse the arguments and use them.
package example;
import com.google.devtools.common.options.OptionsParser;
import java.util.Collections;
public class Server {
public static void main(String[] args) {
OptionsParser parser = OptionsParser.newOptionsParser(ServerOptions.class);
parser.parseAndExitUponError(args);
ServerOptions options = parser.getOptions(ServerOptions.class);
if (options.host.isEmpty() || options.port < 0 || options.dirs.isEmpty()) {
printUsage(parser);
return;
}
System.out.format("Starting server at %s:%d...\n", options.host, options.port);
for (String dirname : options.dirs) {
System.out.format("\\--> Serving static files at <%s>\n", dirname);
}
}
private static void printUsage(OptionsParser parser) {
System.out.println("Usage: java -jar server.jar OPTIONS");
System.out.println(parser.describeOptions(Collections.<String, String>emptyMap(),
OptionsParser.HelpVerbosity.LONG));
}
}
https://github.com/pcj/google-options
Take a look at the Commons CLI project, lots of good stuff in there.
Yeap.
I think you're looking for something like this:
http://commons.apache.org/cli
The Apache Commons CLI library provides an API for processing command line interfaces.
If you are already using Spring Boot, argument parsing comes out of the box.
If you want to run something after startup, implement the ApplicationRunner interface:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Override
public void run(ApplicationArguments args) {
args.containsOption("my-flag-option"); // test if --my-flag-option was set
args.getOptionValues("my-option"); // returns values of --my-option=value1 --my-option=value2
args.getOptionNames(); // returns a list of all available options
// do something with your args
}
}
Your run method will be invoked after the context has started up successfully.
If you need access to the arguments before you fire up your application context, you can just simply parse the application arguments manually:
#SpringBootApplication
public class Application implements ApplicationRunner {
public static void main(String[] args) {
ApplicationArguments arguments = new DefaultApplicationArguments(args);
// do whatever you like with your arguments
// see above ...
SpringApplication.run(Application.class, args);
}
}
And finally, if you need access to your arguments in a bean, just inject the ApplicationArguments:
#Component
public class MyBean {
#Autowired
private ApplicationArguments arguments;
// ...
}
Maybe these
JArgs command line option parsing
suite for Java - this tiny project provides a convenient, compact, pre-packaged and comprehensively documented suite of command line option parsers for the use of Java programmers. Initially, parsing compatible with GNU-style 'getopt' is provided.
ritopt, The Ultimate Options Parser for Java - Although, several command line option standards have been preposed, ritopt follows the conventions prescribed in the opt package.
I wrote another one: http://argparse4j.sourceforge.net/
Argparse4j is a command line argument parser library for Java, based on Python's argparse.
If you are familiar with gnu getopt, there is a Java port at: http://www.urbanophile.com/arenn/hacking/download.htm.
There appears to be a some classes that do this:
http://docs.sun.com/source/816-5618-10/netscape/ldap/util/GetOpt.html
http://xml.apache.org/xalan-j/apidocs/org/apache/xalan/xsltc/cmdline/getopt/GetOpt.html
airline # Github looks good. It is based on annotation and is trying to emulate Git command line structures.
Argparse4j is best I have found. It mimics Python's argparse libary which is very convenient and powerful.
I want to show you my implementation: ReadyCLI
Advantages:
for lazy programmers: a very small number of classes to learn, just see the two small examples on the README in the repository and you are already at 90% of learning; just start coding your CLI/Parser without any other knowledge;
ReadyCLI allows coding CLIs in the most natural way;
it is designed with Developer Experience in mind; it largely uses the Builder design pattern and functional interfaces for Lambda Expressions, to allow a very quick coding;
it supports Options, Flags and Sub-Commands;
it allows to parse arguments from command-line and to build more complex and interactive CLIs;
a CLI can be started on Standard I/O just as easily as on any other I/O interface, such as sockets;
it gives great support for documentation of commands.
I developed this project as I needed new features (options, flag, sub-commands) and that could be used in the simplest possible way in my projects.
If you want something lightweight (jar size ~ 20 kb) and simple to use, you can try argument-parser. It can be used in most of the use cases, supports specifying arrays in the argument and has no dependency on any other library. It works for Java 1.5 or above. Below excerpt shows an example on how to use it:
public static void main(String[] args) {
String usage = "--day|-d day --mon|-m month [--year|-y year][--dir|-ds directoriesToSearch]";
ArgumentParser argParser = new ArgumentParser(usage, InputData.class);
InputData inputData = (InputData) argParser.parse(args);
showData(inputData);
new StatsGenerator().generateStats(inputData);
}
More examples can be found here
As one of the comments mentioned earlier (https://github.com/pcj/google-options) would be a good choice to start with.
One thing I want to add-on is:
1) If you run into some parser reflection error, please try use a newer version of the guava. in my case:
maven_jar(
name = "com_google_guava_guava",
artifact = "com.google.guava:guava:19.0",
server = "maven2_server",
)
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
server = "maven2_server",
)
maven_server(
name = "maven2_server",
url = "http://central.maven.org/maven2/",
)
2) When running the commandline:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) When you need the usage help, just type:
bazel run path/to/your:project -- --help
Take a look at Spring Shell
Spring Shell’s features include
A simple, annotation driven, programming model to contribute custom commands
Use of Spring Boot auto-configuration functionality as the basis for a command plugin strategy
Tab completion, colorization, and script execution
Customization of command prompt, shell history file name, handling of results and errors
Dynamic enablement of commands based on domain specific criteria
Integration with the bean validation API
Already built-in commands, such as clear screen, gorgeous help, exit
ASCII art Tables, with formatting, alignment, fancy borders, etc.
For Spring users, we should mention also https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/SimpleCommandLinePropertySource.html and his twin brother https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/JOptCommandLinePropertySource.html (JOpt implementation of the same functionality).
The advantage in Spring is that you can directly bind the command line arguments to attributes, there is an example here https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/env/CommandLinePropertySource.html