java jar arguments for swing application [duplicate] - java
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
Related
How should I approach for creating a command-line parser in java? [duplicate]
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
How can I easily write a REPL app in Java?
I have a CMS server that provides a client library. I'd like to be able to drive the CMS interactively from the command line. The basic approach would be: Create a connection to the CMS Add the CMS connection object to the REPL context Connect the REPL to stdout/stderr/stdin Kick off a daemon thread for to keep the REPL running. I was hoping that I could perhaps leverage Groovy to do this but haven't managed to get it working. Is there a library that provides REPL support? Can you provide a simple example?
If you don't mind using Scala as your language, you can use the Scala REPL to explore java libraries. You can do this in a number of ways, either with $ scala -classpath yourjarfileshere.jar or if you're using maven: mvn scala:console If all you're doing is playing (not scripting or anything), then this is a possible way to go. If you wish to embed your repl, and you're still willing to use Scala, you can look at the answer to these questions: Drop into interpreter during arbitrary scala code location and Launch Scala REPL programatically? Groovy also has a repl, groovysh, which you can use to explore.
I got this working with Groovy. Example public static void main(final String[] args) { Binding binding = new Binding(); // Configure your bindings here. Groovysh shell = new Groovysh(binding, new IO()); shell.run(args); } Known Issues However, it won't work when the app is started from Eclipse (ie using the Eclipse 'console' view). To work around this you must update the Eclipse launch configuration to pass the following VM argument: -Djline.terminal=jline.UnsupportedTerminal. More information Documentation of the Groovy Shell.
Wikipedia page for REPL mentions BeanShell. Would that work?
Beanshell can be run as repl in your own thread/main within your application: public static void main(String[] args) throws Exception{ Reader inreader = new InputStreamReader(System.in); Interpreter i = new Interpreter(inreader, System.out, System.err, true); try { BufferedReader in = new BufferedReader(inreader); String str; while ((str = in.readLine()) != null) { i.eval(str); } in.close(); } catch (Exception e) { } } that example runs in eclipse fine, you type at it in the console window of eclipse then it will talk back to you fine.
Parse string as if it was a command with params and options
I have this Java enum: public enum Commands { RESIZE_WINDOW("size -size"), CREATE_CHARACTER("create-char -name"), NEW_SCENE("scene -image"), DIALOG("d -who -words"), PLAY_SOUND("sound -file --blocking=false"), FADE_TO("fade-to -file"), WAIT("w -length=auto"); } I want to be able to parse those strings and extract: command name (e.g. create-char) required parameters (e.g. -name) optional options, with default value (e.g. --blocking=false) I looked at org.apache.commons.cli, but that appears to fail on the first criteria (different command names) and is very verbose. Any library suggestions? (This is going to be used to parse a scripting "language", if that context helps.) Edit: An example input in the scripting language would be d John "Hello World" -- multi-word text goes in quotes.
It appears that you want to build numerous CLI commands based simply on their "help descriptors"; a DSL of sorts. Instead of doing this string parsing, consider building the commands programmatically, for which there are numerous libraries (CLI being but one) and advantages. Your example is already significantly complex enough that a second look at CLI (or one of the others) is warranted. You show required and optional args, each having either no-value or a default (though no means of indicating 'required' arg-values without a default, command descriptions, etc), and you still need to build a parser for the command line itself, verification, means of invoking handlers, etc... Below is a list of command parsers I've found. None will parse your specific DSL, but they will allow you to build your commands programmatically, parse it, often verify and provide meaningful warnings, help handling, etc. Some even use annotations on objects to define commands, theoretically making maintenance easier. Most are designed (and show examples) for parsing the arguments to your program, rather than numerous commands (natural-cli being an exception) but all should be able to do this - a simple class could wrap the parsing and options together: static class CommandLine { HashMap<String,Options> options = new HashMap<String,Options>(); public void register(String cmd, Options opts) { options.put(cmd, opts); } public void parse(String line) { // a better parser here would handle quoted strings String[] split = line.split("\\s"); String cmd = split[0]; String[] args = new String[split.length-1]; if (args.length > 0) System.arraycopy(split, 1, args, 0, args.length); Options opts = options.get(cmd); if (opts == null) ; // handle unknown command else { opts.parse(args); // handle results... opts.reset(); // required? } } } public static void main(String[] args) throws Exception { CommandLine cl = new CommandLine(); cl.register("size", new Options()); // This will vary based on library Some cl.register("create-char", new Options()); // require subclasses, others use builder //... pattern, or other means. BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while (true) { cl.parse(in.readLine()); } } Other Libraries CLI JewelCli: also uses annotations, and allows lists and enums for values. examples look promising natural-cli: allows cli with "human readable sentances". Seems geared towards your goal of multiple commands and their options, albiet with a different DSL and syntax. GNU Java Getopt: Used same way as above, though you initialize the Getopt object with the name of the command. JOpt Simple: Claims "simplicity over all others" JArgs args4j: uses annotations on separate classes created for each command JSAP CLAJR: uses reflection CmdLn ArgParser JCommando: uses XML config files. parse-cmd: uses Builder-pattern and method chaining to build parameters cli-parser: annotation based
Include Perl in Java
Is there any way to execute perl code without having to use Runtime.getRuntime.exec("..."); (parse in java app)?
I've been looking into this myself recently. The most promising thing I've found thus far is the Inline::Java module on CPAN. It allows calling Java from Perl but also (via some included Java classes) calling Perl from Java.
this looks like what you're asking for
Inline::Java provides an embedded Perl interpreter in a class. You can use this to call Perl code from your Java code. Graciliano M. Passos' PLJava also provides an embedded interpreter. Don't use JPL (Java Perl Lingo)--the project is dead and has been removed from modern perls.
Inline::Perl is the accepted way. But there's also Jerl which may be run from a JAR. Here's an example without using the VM wrapper (which is not so fun). Here's some examples using the jerlWrapper class to make it easier to code: import jerlWrapper.perlVM; public final class HelloWorld { /* keeping it simple */ private static String helloWorldPerl = "print 'Hello World '.$].\"\n\";"; public static void main(String[] args) { perlVM helloJavaPerl = new perlVM(helloWorldPerl); helloJavaPerl.run(); } } or import jerlWrapper.perlVM; public final class TimeTest { /* The (ugly) way to retrieve time within perl, with all the * extra addition to make it worth reading afterwards. */ private static String testProggie = new String( "my ($sec, $min, $hr, $day, $mon, $year) = localtime;"+ "printf(\"%02d/%02d/%04d %02d:%02d:%02d\n\", "+ " $mon, $day + 1, 1900 + $year, $hr, $min, $sec);" ); public static void main(String[] args) { perlVM helloJavaPerl = new perlVM(testProggie); boolean isSuccessful = helloJavaPerl.run(); if (isSuccessful) { System.out.print(helloJavaPerl.getOutput()); } } }
I could have sworn it was easy as pie using the Java Scripting API. But apparently it's not on the list of existing implementations... So, maybe this helps instead : java and perl edit: i said "maybe"
No, I don't believe this exists. While there have been several languages ported to the JVM (JRuby, Jython etc) Perl is not yet one of them.
In the future, the standard way to use any scripting language is through the java Scripting Support introduced in JSR 223. See the scripting project homepage for a list of scripting languages supported at the moment. Unfortunately, Perl isn't on there yet :-(
Calling a java program from another
How do i call a Java command from a stand alone java program. I understand that Runtime.getRuntime().exec("cmd c/ javac <>.java"); would work. However, this would be platform specific. Any other APIs available that could make it work in j2sdk1.4 ?
If you can run everything in the same JVM, you could do something like this: public class Launcher { ... public static void main(String[] args) throws Exception { launch(Class.forName(args[0]), programArgs(args, 1)); } protected static void launch(Class program, String[] args) throws Exception { Method main = program.getMethod("main", new Class[]{String[].class}); main.invoke(null, new Object[]{args}); } protected static String[] programArgs(String[] sourceArgs, int n) { String[] destArgs = new String[sourceArgs.length - n]; System.arraycopy(sourceArgs, n, destArgs, 0, destArgs.length); return destArgs; } And run it with a command line like this: java Launcher OtherClassWithMainMethod %CMD_LINE_ARGS%
Calling Runtime.getRuntime().exec() is not only platform specific, it is extremely inefficient. It will result in spawning a brand new shell and an entire jvm which could potentially be very expensive depending on the dependencies of this application (no pun intended). The best way to execute "external" Java code would be to place it in your CLASSPATH. If you must call an application's main method you can simply import and call the method directly. This could be done like so: import my.externals.SomeMain // call as if we are running from console SomeMain.main(new String[] {"some", "console", "arguments"}) Of course, the best case scenario would be to simply use this as an external library and access the code you need without having to call SomeMain.main(). Adhering to best practices and writing proper encapsulated modular objects allows for much greater portability and ease of use when being used by other applications.
When you leave the JVM and move to system commands, then you have to deal with the platform specific commands yourself. The JVM offers a good way for abstraction, so why move away? If you want to execute java specific binaries, check out the ant libraries of java. You can execute ant scripts from java which execute platform depending commands.
Java programming from quercus php on GAE: import com.newatlanta.commons.vfs.provider.gae.GaeVFS; import org.apache.commons.io.IOUtils; import java.lang.Long; import java.lang.Boolean; GaeVFS::setRootPath(quercus_servlet_request()->getSession(true)->getServletContext()->getRealPath('/')); define('VFSM', GaeVFS::getManager()); //VFSM->resolveFile('gae://gaevfs')->createFolder(); $file=VFSM->resolveFile('gae://gaevfs/tmp1'); //$file->createFile(); $text='pp'; $method=$file->getClass()->getDeclaredMethod('updateContentSize', array(Long::TYPE, Boolean::TYPE)); $method->setAccessible(true); $method->invoke($file, strlen($text), true); $out=$file->getContent()->getOutputStream(); IOUtils::write($text, $out, 'UTF8'); $out->close(); $in=$file->getContent()->getInputStream(); $method=$file->getClass()->getDeclaredMethod('doGetContentSize',array()); $method->setAccessible(true); $len=$method->invoke($file); $whole=IOUtils::toString($in, 'UTF8').':'.$len."<br>"; $in->close(); echo $whole; GaeVFS::clearFilesCache(); GaeVFS::close();