Quel est le bon moyen d’analyser les arguments de ligne de commande en Java?
Vérifiez ces:
Ou roulez les vôtres:
Par exemple, voici comment vous utilisez commons-cli
pour analyser 2 arguments de chaîne:
_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;
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);
}
}
_
utilisation en ligne de commande:
_$> 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
_
Jetez un coup d'œil au plus récent JCommander .
Je l'ai créé. Je suis heureux de recevoir des questions ou des demandes de fonctionnalités.
J'ai essayé de maintenir un liste des analyseurs syntaxiques Java de la CLI .
J'ai utilisé JOpt et je l'ai trouvé assez pratique: http://jopt-simple.sourceforge.net/
La page d'accueil fournit également une liste d'environ 8 bibliothèques alternatives, consultez-les et choisissez celle qui convient le mieux à vos besoins.
Quelqu'un m'a indiqué args4j dernièrement, qui est basé sur des annotations. J'aime vraiment ça!
Acheter ou construire?
De nombreuses petites applications ressemblant à des utilitaires lancent probablement leur propre analyse en ligne de commande pour éviter la dépendance externe supplémentaire.
picocli peut être intéressant. Il est conçu pour être inclus en tant que source en tant qu'alternative plus simple à l'ombrage de bocaux dans un uberjar.
Une autre fonctionnalité qui pourrait vous plaire est son aide à l’utilisation colorisée.
Caractéristiques de l'analyseur:
<command> -xvfInputFile
ainsi que <command> -x -v -f InputFile
)"1..*"
, "3..5"
Le message d'aide à l'utilisation est facile à personnaliser avec des annotations (sans programmation). Par exemple:
( source )
Je n'ai pas pu résister à l'ajout d'une capture d'écran supplémentaire pour montrer les messages d'aide d'utilisation possibles. L’aide à l’utilisation est le visage de votre application, alors soyez créatif et amusez-vous!
Disclaimer: j'ai créé picocli. Vos commentaires ou questions sont les bienvenus.
Il s'agit de la bibliothèque d'analyse en ligne de commande de Google en source ouverte faisant partie du projet Bazel. Personnellement, je pense que c'est la meilleure solution, et beaucoup plus facile que Apache CLI.
https://github.com/pcj/google-options
maven_jar(
name = "com_github_pcj_google_options",
artifact = "com.github.pcj:google-options:jar:1.0.0",
sha1 = "85d54fe6771e5ff0d54827b0a3315c3e12fdd0c7",
)
dependencies {
compile 'com.github.pcj:google-options:1.0.0'
}
<dependency>
<groupId>com.github.pcj</groupId>
<artifactId>google-options</artifactId>
<version>1.0.0</version>
</dependency>
Créez une classe qui étend OptionsBase
et définit votre @Option
.
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;
}
Analyser les arguments et les utiliser.
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));
}
}
Jetez un coup d'œil au projet Commons CLI , plein de bonnes choses là-dedans.
Yeap.
Je pense que vous cherchez quelque chose comme ceci: http://commons.Apache.org/cli
La bibliothèque Apache Commons CLI fournit une API pour le traitement des interfaces de ligne de commande.
Peut-être que ces
Suite d'analyse des options de ligne de commande JArgs pour Java - ce petit projet fournit une suite pratique, compacte, pré-packagée et documentée de manière exhaustive, permettant d'analyser les options de ligne de commande pour les programmeurs Java. Initialement, une analyse compatible avec "getopt" de style GNU est fournie.
ritopt, Analyseur d'options ultimes pour Java - Bien que plusieurs normes d'options de ligne de commande aient été préposées, ritopt respecte les conventions prescrites dans le paquet opt.
Vous pourriez trouver ce méta-article sur le malheur intéressant comme point de départ:
http://furiouspurpose.blogspot.com/2008/07/command-line-parsing-libraries-for-Java.html
J'ai écrit un autre: http://argparse4j.sourceforge.net/
Argparse4j est une bibliothèque d'analyse syntaxique d'arguments de ligne de commande pour Java, basée sur argparse de Python.
Si vous connaissez gnu getopt, il existe un port Java à: http://www.urbanophile.com/arenn/hacking/download.htm .
Il semble y avoir quelques classes qui font ceci:
airline @ Github a l'air bien. Il est basé sur des annotations et tente d'émuler les structures de ligne de commande Git.
Je sais que la plupart des gens ici vont trouver 10 millions de raisons pour lesquelles ils n'aiment pas mon chemin, mais tant pis. J'aime garder les choses simples, alors je sépare simplement la clé de la valeur en utilisant un '=' et les stocke dans un HashMap comme ceci:
Map<String, String> argsMap = new HashMap<>();
for (String arg: args) {
String[] parts = arg.split("=");
argsMap.put(parts[0], parts[1]);
}
Vous pouvez toujours conserver une liste des arguments que vous attendez, pour aider l'utilisateur s'il oublie un argument ou utilise un argument erroné ... Toutefois, si vous voulez trop de fonctionnalités, cette solution ne vous convient pas.
Argparse4j est le meilleur que j'ai trouvé. Il imite la bibliothèque argparse de Python, qui est très pratique et puissant.
Si vous voulez quelque chose de léger (taille de jar ~ 20 kb) et simple à utiliser, vous pouvez essayer argument-parser . Il peut être utilisé dans la plupart des cas d'utilisation, prend en charge la spécification de tableaux dans l'argument et ne dépend d'aucune autre bibliothèque. Cela fonctionne pour Java 1.5 ou supérieur. L'extrait ci-dessous montre un exemple d'utilisation:
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);
}
Plus d'exemples peuvent être trouvés ici
Je ne recommanderais pas d'utiliser la bibliothèque Apache Common CLI, car elle n'est pas threadsafe. Il utilise des classes avec état avec des variables statiques et des méthodes pour effectuer un travail interne (par exemple, OptionBuilder) et ne doit être utilisé que dans des situations à contrôle unique fortement threadées.
Si vous utilisez déjà Spring Boot, l'analyse des arguments est prête à l'emploi.
Si vous souhaitez exécuter quelque chose après le démarrage, implémentez l'interface ApplicationRunner
:
@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
}
}
Votre méthode run
sera invoquée une fois le contexte démarré avec succès.
Si vous avez besoin d'accéder aux arguments avant vous lancez le contexte de votre application, vous pouvez simplement analyser les arguments de l'application manuellement:
@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);
}
}
Et enfin, si vous avez besoin d'accéder à vos arguments dans un haricot, il suffit d'injecter la ApplicationArguments
:
@Component
public class MyBean {
@Autowired
private ApplicationArguments arguments;
// ...
}
Comme l’un des commentaires mentionnés plus tôt ( https://github.com/pcj/google-options ) serait un bon choix pour commencer.
Une chose que je veux ajouter est la suivante:
1) Si vous rencontrez une erreur de réflexion de l’analyseur, essayez d’utiliser une version plus récente de la goyave. dans mon cas:
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) Lors de l'exécution de la ligne de commande:
bazel run path/to/your:project -- --var1 something --var2 something -v something
3) Lorsque vous avez besoin d'aide pour l'utilisation, tapez simplement:
bazel run path/to/your:project -- --help