Reputation: 2899
At the moment I'm wrangling with an existing Java project, my goal is to create a command line interface for passing arguments to it, to "run" it, so to speak.
I'm using the Apache commons cli library, like so:
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
public class CommandLineParameters {
public static void main(String[] args) {
CommandLineParser parser = new DefaultParser();
Options options = new Options();
options.addOption("a", "abc", true, "First Parameter");
options.addOption("x", "xyz", true, "Second Parameter");
options.addOption("h", "help", false, "Shows this Help");
try {
CommandLine commandLine = parser.parse(options, args);
System.out.println(commandLine.getOptionValue("a"));
System.out.println(commandLine.getOptionValue("x"));
if (commandLine.hasOption("h")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp("CommandLineParameters", options);
}
} catch (ParseException e) {
e.printStackTrace();
}
}
}
In Eclipse I can run this by modifying the Arguments
passed to the Run Configurations...
, however, what I would in fact like to do is, to be able to run this programme from a terminal shell, in an analogous way to "normal" terminal programmes such as grep
, or ipconfig
.
How can this be achieved using Java?
NOTE: I'm not trying to compile/build this programme from the command line, I'm trying to make an interface to the program in the command line.
Upvotes: 1
Views: 24896
Reputation: 192033
I think your better option is to rewrite the other main method of the existing program to accept CLI args, but if you want to do so, either way, you need to compile the program to a class or jar file
And you run it like any other Java program from the CLI, but give it arguments like -h
here. Note: you'll need to include a classpath for Apache Commons here.
java - cp <classpath> fully.qualified.CommandLineParameters -h
Or, if you have a JAR with a Main class attribute in its manifest and also includes Apache Commons (via an uber jar), there's no need to set the class name or classpath. Still, give the arguments, though
java -jar jarFile.jar -h
I want it to be an independent programme, accessed from the command line, such as
ls
Open your bashrc and put in an alias or function. The fact of the matter is, you must invoke java
, or you can use a different JVM scripting language like Groovy
$ cat my-ls
#!/usr/bin/env groovy
println "Run my other program"
$ chmod +x my-ls
$ ./my-ls
Run my other program
Upvotes: 1
Reputation: 11875
The provided answers describe how to build a jar that can be executed using java -jar
command. The following article explains how to take such an 'executable' jar and convert it to a 'program' file executable by sh
(so it can be invoked with ./program
and not with java -jar program.jar
): https://coderwall.com/p/ssuaxa/how-to-make-a-jar-file-linux-executable
The idea is that a zip
archive (and a jar
is basically a flavor of a zip
archive) may have an arbitrary prologue. The prologue is everything from the beginning of a file till zip
file signature (4 characters, first two of which are 'PK'). When java reads a jar
archive, it skips that prologue (everything before the signature).
So from the point of view of java
, such a jar will be a valid jar. But if that prologue is a shell script, such a jar will also be a file that you can execute using a shell interpreter.
That means that you can prepend usual jar content with a shell script that will just invoke that java -jar
with that same jar archive as an argument. And java
will happily execute that jar
ignoring the prologue.
The prologue in the article looks like this:
#!/bin/sh
MYSELF=`which "$0" 2>/dev/null`
[ $? -gt 0 -a -f "$0" ] && MYSELF="./$0"
java=java
if test -n "$JAVA_HOME"; then
java="$JAVA_HOME/bin/java"
fi
exec "$java" $java_args -jar $MYSELF "$@"
exit 1
It looks for java
and starts it with the needed parameters. This is just an example, you can tune the algorithm used to find java
command to make it suit your needs.
And the resulting file will consist of the concatenation of this launcher shell script and that jar file (containing main class and manifest) that should be run using java -jar
.
Upvotes: 6
Reputation: 338
you should create an executable jar from your java code:
Start your application from command line:
java -jar CommandLineParameters.jar --param1 -param2 ...
Upvotes: 0
Reputation: 29730
That sure is possible. After parsing the parameters you can read from System.in
and write to System.out
. Here a very simple sample to convert input to uppercase - incomplete (error handling and such), just to show how to start:
package sf;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Sample {
public static void main(String[] args) {
processArguments(args);
try {
processInput(System.in);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void processArguments(String[] args) {
// whatever
}
private static void processInput(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line.toUpperCase());
}
in.close();
}
}
and to execute it just use type like
java sf.Sample -a <input.txt >out.txt
the directory containing the sf
directory where the Sample.class
is located must be in the CLASSPATH or you must use the -cp
option to the java
command: How Classes are Found.
Upvotes: 0