I have a running java program which converts a json file into another file format. Everything works great.
For the implementation I decided to use the MVC pattern.
Now I want to implement the whole conversion routine so that I can use a command prompt but I never worked with that and don't know how to achieve this at all.
My thoughts were:
Open cmd and navigate to the main.java-file.
Print out the whole possibilities (the user should be able to enter the dir of the source file and the target dir, the user should be able to choose the target format).
If everything has been entered by the user, the conversion routine should be started by pushing ENTER.
Help would be really nice. For the moment I just know how to compile (javac helloWorld.java) and print "Hello World!" by exeuting a program with java helloWorld...
The apache commons cli project provides utilities for parsing command line arguments and providing help menu. This makes it pretty simple to handle the args provided to your main method.
You will also need to provide scripts to assemble your class path. You can look at the maven app assembler plugin for ways of doing this.
The interaction between a shell/command prompt and the started Java program is very similar to the way it works in C programs*. The main() method receives arguments as strings from the command line (or from any other parent process which executes the java runtime).
In Java you get an array of strings. You need to decide yourself which string has what meaning.
public static void main(String[] arg) { // traditional or String ... args
System.out.println("You have " + arg.length + " arguments);
if (arg.length >= 1) System.out.println("First: " + arg[0]);
}
When starting a Java runtime with arguments, it is important to note, that arguments start after the class name (or the JAR name):
java -cp . package.Main arg0 arg1 ...
java -jar package.jar arg0 arg1 ...
The Java runtime also has an mechanism to specify system properties on the command line. This is done with the -D option.
java -Dverbose=yes -jar package.jar arg0 arg1 ...
java -jar package.jar -Dverbose=yes arg1 ... //not a system property but arg[0]
It is important, that this option is specified before the class/jar-name, otherwise it will not be processed by the runtime, but you will see another argument.
String verbose = System.getProperty("verbose", "false");
The reason why system properties are useful: you can use them for optional control, so you do not have to worry about recognizing arguments (there are a number of libraries out there which can do that but for small tools I think it is overkill).
BTW: there are some interactions between shells/prompts and started programs when using wildcards (* and ?) and whitespace/quoting - those are OS specific.
* in C the first argument args[0] is the program name, in java arg[0] is the first argument after the class name.
Related
My issue here is that I can't seem to pass arguments through my program. I'm not sure how to explain it clearly but here it goes:
I want to be able to run a script file through a custom interpreter with arguments.
For example:
AtomScript.exe main.atom -> Program runs
When I want to run it through a batch file:
main.atom -> Program runs
Now when I want to pass arguments through the program using the AtomScript command in a batch file:
AtomScript.exe main.atom arg1 arg2 -> Program runs with arguments
The arguments are passed. But when I want to use the simple main.atom command to run it with arguments it doesn't work:
main.atom arg1 arg2 -> Program runs without arguments
I'm not sure what to do at this point. Any suggestions?
main.atom is not an executable, so it can't take any parameters
Windows knows, which program has to be started and does so (ignoring any parameters)
Only if you start the executable directly, you can define parameters (the first one being main.atom)
for example:
C:\>assoc .txt
.txt=txtfile
C:\>ftype txtfile
txtfile=%SystemRoot%\system32\NOTEPAD.EXE %1
assoc defines, what filetype that extension is ("txtfile")
ftype defines, what has to be done for this filetype (start notepad)
You can see, there is just one parameter %1 (the filename (main.atom)).
Of course you could expand it with more parameters (needs to be run as administrator):
ftype txtfile=%SystemRoot%\system32\NOTEPAD.EXE %*
(which makes not much sense with this example), but I don't recommend it (it's just done on your computer). Better use the "official way": in the batchfile do exactly the same as on the commandline: start the executable with the desired parameters:
AtomScript.exe main.atom arg1 arg2
Let's assume I would like to execute a Java application:
java -cp j1:j2...:j9999 Main arg1 arg2
In this case, the java executable gets a plethora of arguments which, on certain OSes, can cause problems due to the length limitation of the command line string (see Maximum Length of Command Line String).
As a remedy, javac offers the #argfile (see here) which allows specifying the arguments within a file. The above example would look like this, if java supported it as well:
java #FileContainingArguments.txt
and the content of FileContainingArguments.txt is:
-cp j1:j2...:j9999
Main
arg1
arg2
So the question is, why java doesn't support it, while javac and javadoc do?
I don't know why it is not supported yet, but it seems Open JDK 9 will support it, once it is released:
https://bugs.openjdk.java.net/browse/JDK-8027634. I am not sure about Oracle.
I have a caching app in Java and I need to put objects of different size in cache. The problem is that I didn't really know how to count the size of a custom object and I've found the solution - to use the library: http://mvnrepository.com/artifact/com.googlecode.sizeofag/sizeofag/1.0.0.
To run the program using the library I need to specify command-line argument -javaagent. So, how can I do it if I'm using maven???
The program is simple:
protected static Boolean b;
public static void main( String[] args )
{
System.out.println(SizeOfAgent.sizeOf(b));
}
This is the output:
0
Can not access instrumentation environment.
Please check if jar file containing SizeOfAgent class is
specified in the java's "-javaagent" command line argument.
P.S. I know, that such kind of question already exists, but it has no proper answer.
On a Linux/Unix machine the "mvn" command will use a shell variable "MAVEN_OPTS" to pass in options. This is useful if you want to give Maven more memory. In your .profile or .bash_profile put a line like this in:
export MAVEN_OPTS=-javaagent
On windows:
in shell (cmd.exe) type "set MAVEN_OPTS=..."
or
add MAVEN_OPTS to your environment
On NetBeans:
In ~/.netbeans/6.5/, create etc/netbeans.conf. Add your environment variables there, e.g.:
export MAVEN_OPTS="-Xmx512m -XX:MaxPermSize=128m"
Curious little issue I am running into here:
I would like a client to be able to do something like:
(1) java -jar myJar.jar inputFile outputFile
or
(2) java -jar myJar.jar text outputFile
outputFile is an optional argument.
Essentially (1) will read input from a file for them, while (2) they provide the input my program will use directly. There is no way to determine whether or not the argument is the input or whether it is the location of the file though that I can think of. For normal command line stuff you would specify a flag like -i inputfile to show you want it to read from a file. What are my options here that maintain ease of use for the client?
Is my only option to create a syntax the client must use for the first argument? i.e.
"-t text" or "-i inputFile"?
I have seen libraries such as commons cli which would enable this, but I would prefer a solution that does not involve using a library.
If I understood the problem correctly, can't you just check the number of arguments instead of explicitly specifying direct input? Like, if one arg is passed the first arg is output, and if 2 args are passed then the first arg is input and the second arg is output?
With that being said - Using a 'option' syntax of the hyphen- kind is probably easiest on most people used to a cli.
I would suggest to read from standard input (System.in) and print to standard out (System.out)
This way, no parameters are required. It's very intuitive for people who work with CLI tools. And you can leave the details of where the input comes from to the OS.
So in a unix OS, you would use your jar something like this:
echo "some test" | java -jar myjar.jar > outfile
or
cat somefile | java -jar myjar.jar > outfile
You can use
input=text or file=inputfile
(with output=outputFile as optional).
In this case, you can treat all your parameters in the same way and split them with the delimiter '=', check the left side of '=' to determine which parameter it is.
When my Java file-processing program is opened by an Open With... command, or is set as a file's default program, how do I handle the file that opened it.
Is it passed as a command line argument?
In what format?
And how about programs, wrapped in an .exe wrapper, or compiled with an AOT compiler?
Launch the app. with Java Web Start and declare an interest in the file-type within the launch file (JNLP).
The path to the File will be passed as a String as the 2nd argument to the main. The 1st argument will be either -edit/open (I forget) or -print.
And how about programs, wrapped in an .exe wrapper, or compiled with an AOT compiler?
How about asking that on a separate question? If deploying with JWS, we would use Jar(s).
Create an executable of your Java File processing program. Please read this-creating executable file if you want to know, how to create executable?
In command line, you may say: executable FileName.ext
FileName.ext will be available in your main program's args[0] attribute.
i.e.
public static void main(String[] args){
String fileName = args[0];
}
You should receive the file's path as an argument in main().
See Using command-line argument for passing files to a program (maybe duplicated?)