I am looking to do some error checking for my command line arguments
public static void main(String[] args)
{
if(args[0] == null)
{
System.out.println("Proper Usage is: java program filename");
System.exit(0);
}
}
However, this returns an array out of bounds exception, which makes sense. I am just looking for the proper usage.
The arguments can never be null. They just won't exist.
In other words, what you need to do is check the length of your arguments.
public static void main(String[] args) {
// Check how many arguments were passed in
if (args.length == 0) {
System.out.println("Proper Usage is: java program filename");
System.exit(0);
}
}
#jjnguy's answer is correct in most circumstances. You won't ever see a null String in the argument array (or a null array) if main is called by running the application is run from the command line in the normal way.
However, if some other part of the application calls a main method, it is conceivable that it might pass a null argument or null argument array.
However(2), this is clearly a highly unusual use-case, and it is an egregious violation of the implied contract for a main entry-point method. Therefore, I don't think you should bother checking for null argument values in main. In the unlikely event that they do occur, it is acceptable for the calling code to get a NullPointerException. After all, it is a bug in the caller to violate the contract.
To expand upon this point:
It is possible that the args variable itself will be null, but not via normal execution. Normal execution will use java.exe as the entry point from the command line. However, I have seen some programs that use compiled C++ code with JNI to use the jvm.dll, bypassing the java.exe entirely. In this case, it is possible to pass NULL to the main method, in which case args will be null.
I recommend always checking if ((args == null) || (args.length == 0)), or if ((args != null) && (args.length > 0)) depending on your need.
You should check for (args == null || args.length == 0). Although the null check isn't really needed, it is a good practice.
if i want to check if any speicfic position of command line arguement is passed or not then how to check?
like for example
in some scenarios 2 command line args will be passed and in some only one will be passed then how do it check wheather the specfic commnad line is passed or not?
public class check {
public static void main(String[] args) {
if(args[0].length()!=0)
{
System.out.println("entered first if");
}
if(args[0].length()!=0 && args[1].length()!=0)
{
System.out.println("entered second if");
}
}
}
So in the above code if args[1] is not passed then i get java.lang.ArrayIndexOutOfBoundsException:
so how do i tackle this where i can check if second arguement is passed or not and if passed then enter it.
need assistance asap.
If you don't pass any argument then even in that case args gets initialized but without any item/element.
Try the following one, you will get the same effect:
public static void main(String[] args) throws InterruptedException {
String [] dummy= new String [] {};
if(dummy[0] == null)
{
System.out.println("Proper Usage is: java program filename");
System.exit(0);
}
}
Related
I'm trying to test my main method (which should accept exactly one argument) for no arguments passed. Can't seem to understand what am I missing here to achieve that.The nature of my program is such that it reads input from a file, creates objects by passing parameters read from the file, and displays output.
Failure Message:
org.junit.ComparisonFailure: Expected :Please pass one argument
Actual :
Here's my Unit Test:
#Test
public void givenNoParameter_shouldAskForOne() throws IOException {
String[] args = {};
String output;
try (ByteArrayOutputStream bOutput = new ByteArrayOutputStream()) {
System.setOut(new PrintStream(bOutput));
Main.main(args);
bOutput.flush();
output = bOutput.toString();
}
String newLine = System.getProperty("line.separator");
String[] breakDownOutput = output.split(newLine);
assertEquals(1, breakDownOutput.length);
assertEquals("Please pass one argument", breakDownOutput[0]);
}
Main Method:
public static void main(String[] args) {
if(args.length == 1) {
DisplayOrder.setFilePath(args[0]);
DisplayOrder.display();
} else{
System.err.println("Please pass one argument");
}
}
I've realized I was using System.err.println() in my main. Changing that to System.out.println() fixed it.
Not showing your main method, my only guess is, that you do not write anything to "System.out" in your main, especially there is no System.out.println("Please pass one argument"); statement which is executed.
So, your unit test fails perfectly for a not expected value in "breakDownOutput[0]".
What you have to do is to make certain that the System.out.println("Please pass one argument"); is executed if no arguments were provided to your main.
Also check your class name Main.main(...) since there might be other Main classes imported which will never print out your expected values to System.out
Is it better to wait for a null pointer exception to happen?
public void doSomething(String str) {
Double val = Double.parseDouble(str); // Null pointer exception thrown here
// Other code
}
Or is it better to check every time for it, as early as possible?
public void doSomething(String str) {
if (str == null)
throw new NullPointerException(); // Null pointer exception thrown here
Double val = Double.parseDouble(str); // Other code
}
I would recommend using an assert clause. I think his response best answers your question
Avoiding != null statements
I would indicate in your method if str can be null or not with the #Nullable keyword. If you are disallowing the str variable to be null then do not do any null checking. You should instead check if str is null before calling doSomething. If str is allowed to be null then wrap it in a null check and do whatever you deem to be appropriate if the variable is null.
public void doSomething(#Nullable String str) {
if (str != null) {
Double val = Double.parseDouble(str);
// other code
}
else {
// return or do something else
}
}
Or..
public void doSomething(#Nullable String str) {
if (str == null) {
return;
}
Double val = Double.parseDouble(str);
// other code
}
I would not recommend throwing a null pointer error unless the application cannot continue without the str variable. You want to capture exceptions so your application doesn't crash not allow them to crash your application.
In that case it doesn't make much difference as parseDouble will throw a NPE. In a more general case, since Java 7, you can use:
Objects.requireNonNull(str); //throws NPE if str is null
//rest of the code
There no different code. You should throw some specific exception.
And sometimes null is legal value.
Sometimes it is usual to define something like a method contract.
I am doing this via Spring Asserts:
org.springframework.util.Assert;
Assertion utility class that assists in validating arguments. Useful
for identifying programmer errors early and clearly at runtime.
For example, if the contract of a public method states it does not
allow null arguments, Assert can be used to validate that contract.
Doing this clearly indicates a contract violation when it occurs and
protects the class's invariants.
Typically used to validate method arguments rather than configuration
properties, to check for cases that are usually programmer errors
rather than configuration errors. In contrast to config initialization
code, there is usally no point in falling back to defaults in such
methods.
This class is similar to JUnit's assertion library. If an argument
value is deemed invalid, an IllegalArgumentException is thrown
(typically).
In your case:
public void doSomething(String str) {
Assert.notNull(str);
Double val = Double.parseDouble(str); // Nullpointer not possible here if the contract was not injured.
// Other code
}
If a null value is passed by any developer the contract was not fullfilled and a IlligalArgumentException is thrown.
Easy testable via Junit:
/**
* Check case that passed string is null.
*/
#Test(expected = IllegalArgumentException.class)
public void testDoSomething_StringIsNull() {
mClassUnderTest.doSomething(null);
}
My java program takes input from the user on the command line. The user has a choice: he may either specify a plain-text file as input with the -inputfile option, or he may leave this option unspecified, in which case the program takes input from System.in. (I've observed this behavior in some programs that come pre-installed with my Ubuntu distro, so I infer that it is acceptable practice.)
So I make a BufferedReader (inBR)that reads from the file, if provided, and a Scanner (inScanner) that reads from System.in otherwise. Only one of these objects is actually instantiated, the other is left as null. Later on, when the program reads a line from input, I have the following code:
String line;
if (inBR != null) {
line = inBR.readLine(); (1)
} else {
line = inScanner.nextLine(); (2)
}
Which gives me the compile time errors variable inBR might not have been initialized and variable inScanner might not have been initialized at lines (1) and (2), respectively.
What is the acceptable solution here? I've considered, "initialize the variable that's supposed to be null as an Object to shut up the compiler." But this is just a hack; surely there's a better way.
Also, why isn't this a runtime exception, as a NullPointerException?
EDIT: inScanner.readLine() => inScanner.nextLine()
Declaring them this way would avoid the compilation error :
BufferedReader inBR = null;
Scanner inScanner = null;
Of course you still have to give them actual values before accessing them, or you'll get NullPointerException.
In java all variables that are used must be initialized at some point.
public void example(){
String name;
if(name == null) return null;
}
In the above example the variable name has not been initialized. There are several ways to solve this problem:
public void example1(){
String name = null;
if(name == null) return null;
}
This would solve the problem.
This would also solve the problem
public void exapmle2(){
String name = "";
if(name == null) return null;
}
Make the condition whether or not a file is provided. For example, if a file is provided, create the buffered reader and set line immediately. Otherwise, create a scanner and set the line.
ProcessBuilder pb = new ProcessBuilder(commandInformation);
Process process = pb.start();
Above code is returning error:
java.lang.IllegalArgumentException
at java.lang.ProcessImpl.<init>(ProcessImpl.java:69)
at java.lang.ProcessImpl.start(ProcessImpl.java:30)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:452)
at com.ConvertsImages.SystemCommandExecutor.executeCommand(SystemCommandExecutor.java:51)
at com.ConvertsImages.ImageConversion.runConvertCommand(ImageConversion.java:115)
at com.ConvertsImages.ImageConversion.runConvert(ImageConversion.java:80)
at com.ConvertsImages.ImageConversion.main(ImageConversion.java:26)
List commandInformation has only one entry as below:
["D:\Program Files\ImageMagick-6.8.6-Q16\convert.exe" "D:\ConvertFiles\ReImport_2507_1.jpg" -resize 40x40 "D:\ConvertFiles\proxy-40\ReImport_2507_1.jpg.jpg" ]
Please suggest.
Looking at the source code for ProcessBuilder, there is a method isQuoted that checks if a String argument is quoted and throws IllegalArgumentException if it is and a flag is checked.
private static boolean isQuoted(boolean noQuotesInside, String arg,
String errorMessage) {
int lastPos = arg.length() - 1;
if (lastPos >=1 && arg.charAt(0) == '"' && arg.charAt(lastPos) == '"') {
// The argument has already been quoted.
if (noQuotesInside) {
if (arg.indexOf('"', 1) != lastPos) {
// There is ["] inside.
throw new IllegalArgumentException(errorMessage);
}
}
return true;
}
if (noQuotesInside) {
if (arg.indexOf('"') >= 0) {
// There is ["] inside.
throw new IllegalArgumentException(errorMessage);
}
}
return false;
}
The above is called from getExecutablePath, note the true flag
boolean pathIsQuoted = isQuoted(true, path,
"Executable name has embedded quote, split the arguments");
which is called inside the ProcessImpl constructor
String executablePath = getExecutablePath(cmd[0]);
where cmd is the array created from your list. Index 0 matches the executable (in your case the whole String). In the String you showed us, your executable is quoted (or at least starts with one), so the method will throw an IllegalArgumentException.
This is confirmed by your stack trace
at java.lang.ProcessImpl.<init>(ProcessImpl.java:69)
That means inside your constructor.
Split each argument in your command list as a separate String element in the list. Don't put quotes around the executable.
I suspect you need a list of 'n' arguments.
It's currently interpreting your first list entry as the executable, and that's clearly not right since it incorporates your arguments too.
Please make sure, that the parameter passed in ProcessBuilder, commandInformation is a String array or a List<String>.
Parameters: command A string array containing the program and its
arguments
Parameters:
command The list containing the program and its arguments
Source
Oracle Docs. which states one of the reasons for IllegalArgumetnException.
Also I just noticed the file name that you have is included with .jpg.jpg .
Shouldn't it be fileName.jpg
Let me clarify the question I am asking. I have a java program I am working on that takes input from the keyboard via a readline library called JLine2. The library takes the entire line types as a command instead on breaking it up into space separated commands and arguments. What I am looking for is a safe way to break up the string that is passed as input.
I have tried using an array but since I am in the early stages of concept I don't yet know how many arguments my largest command will have so using a pre-initialized array I don't think will work. The problem I have ran into is when I check for null values in the array or when I check to see if a particular command or argument is present. Java keeps throwing an exception about the array index being out of scope or something. Because the array does not actually have a value for say array index 1 which is an argument to command in array index 0.
So what I am looking for is a way to take a string and safely split it into parts without having Java yelling at me when and array exception has occurred.
Here is the very slim code I can provide...
ConfigShell.class
package shell;
import java.io.IOException;
import configFS.ConfigFS;
import jline.console.ConsoleReader;
public class ConfigShell {
private ConfigFS config;
public ConfigShell() throws IOException {
config = new ConfigFS();
}
public void init() throws IOException {
ConsoleReader console = new ConsoleReader();
// When the program starts we want to be placed at / (root).
console.setPrompt(">> ");
// In this case an infinite loop is better than a loop based on whether line is equal to null.
// This allows line to be equal to null and still stay inside the shell.
while (true) {
String line = console.readLine();
if (line != null) {
// If pre-initialize the array I can check for null as a value for an array index.
// If I did this at time I needed the array and there were not enough index occupied the system would return an exception.
String[] cmdArgs = new String[4];
// We need to split up the incoming line because JLine2 does not do it for me.
// This allows me to evaluate the entire command piece by piece rather all at once.
cmdArgs = line.split("\\s+");
if (cmdArgs[0] != null && cmdArgs[0].equals("add")) {
if (cmdArgs[1] != null && cmdArgs[1].equals("server")) {
if (cmdArgs[2] != null) {
config.addServer(cmdArgs[2]);
System.out.println("Added server " + cmdArgs[2] + " to the configuration successfully.");
}
}
}
if (cmdArgs[0].equals("exit")) {
System.exit(0);
}
}
}
}
}
Note for testing: My Start.class main method makes a call to the init method in the above file.
You can do:
String cmdArgs = line.split("\\s+");
and then, before accessing any particular index, check the size of the array so that you do not get ArrayIndexOutOfBoundException
Something like this:
if(cmdArgs.length>=2){
//It means you have at least 2 elements
//Now its safe to access cmdArgs[0] and cmdArgs[1]
}
If all your problem is to have a storage for a variable number of strings you can use ArrayList<String> object.
You declare it like ArrayList<String> as = new ArrayList<String>();
Then when you split something from your command string you will simply use add method:
as.add(yourString);
If you need to retrieve a particular element of the ArrayList you can use its get method:
as.get(0);
You can process all elements with for each loop:
for(String str: as) {
println(str):
}
Have a look here for info and here for an example.
As I think you can use StringTokenizer class and its methods for your requirement.
see the sample code below:
if(line!=null)
{
StringTokenizer st=new StringTokenizer(line);// by default it takes space as delimiter....you can use as required as second argument in constructor...
while(st.hasMoreTokens())
{
String token1=st.nextToken();
// do your stuffs here..........
// I don't know exactly about your required logic here......
/* if(token1.equals("add"))
{
String token2=st.nextToken();
if(token2.equals("server"))
{
String token3=st.nextToken();
config.addServer(token3);
System.out.println("Added server " + token3 + " to the configuration successfully.");
}
}
*/
}// while closing...
}// outer if closing...
Or as PM 77-1 told you can use ArrayList. But as my opinion LinkedList should be a better option here.