First, I know the Title is a bit ambiguous. Actually I don't know how to write it better!
Second, I will describe the problem.
Situation:
I am practicing on an online judge (OJ), so in case of wrong output, the OJ shows me the test case which makes my code to fail. Normally, I can copy my code and paste it into Eclipse, then call my function with that test case and debug my code.
But the problem when the test case is a multiple calls for my function (Like testing an enhanced version of a priority queue), let's assume there were n calls till the fail of the code. So to debug the code, I will have to call the function say n times! Which is not logical!
Function the OJ will call:
public void enqueue (int value)
{
// implementation
}
public int dequeue ()
{
// implementation
}
Test case makes the code to fail:
Last executed input: enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16),... dequeue(),...
Action:
I need a way to call the function with an array of test cases in order to be able to debug the code.
OR
By some way call the function with its parameter directly from the string. Something like invoke("enqueue(5, 3)");
After some investigation, I found a way to do the Action I need by using Java Reflection Also a helpful thread What is reflection and why is it useful?
I managed to develop a tool, here you are the steps:
Copy the test case in a String
Split the string on each function call
Remove the function name from each call, and store them in array of String in order.
Split the parameter
Now I have 2 arrays of integers for param1 and param2, and an array of String for invokations
I used Reflection in order to be able to call the methods from a string of calls, inside a for loop.
Then we have this
public class Test
{
public static void main(String[] args)
{
String testCase = "enqueue(5, 3), enqueue(51, 60), enqueue(0, 14), enqueue(364, 16), dequeue()";
// Prepare parameters and invocations
int[] param1; // assuming it is ready
int[] param2; // assuming it is ready
String[] calls; // assuming it is ready
try
{
Class calledClass = Class.forName("OJ.Prob3");
Method calledMethod1 = calledClass.getDeclaredMethod("enqueue", String.class, int.class);
Method calledMethod2 = calledClass.getDeclaredMethod("dequeue", null);
for (int i = 0 ; i < calls.length ; i++)
{
if (calls[i].equalsIgnoreCase("enqueue"))
calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]);
else if (calls[i].equalsIgnoreCase("dequeue"))
calledMethod2.invoke(calledClass.newInstance())
}
} catch (ClassNotFoundException e)
{
e.printStackTrace();
} catch (NoSuchMethodException e)
{
e.printStackTrace();
} catch (SecurityException e)
{
e.printStackTrace();
} catch (IllegalAccessException e)
{
e.printStackTrace();
} catch (IllegalArgumentException e)
{
e.printStackTrace();
} catch (InvocationTargetException e)
{
e.printStackTrace();
}
}
}
I already tested this solution and it works really very smooth, but please if anyone has a better solution, you will be more than welcome.
I will finalize the code and make it something like a tool, and I will post it soon, in order to make everybody's life easier debugging the online judges test cases.
Update:
You can do the same for the static methods, just remove .newInstance() from calledMethod1.invoke(calledClass.newInstance(), param[i], param2[i]); to something like calledMethod1.invoke(calledClass, param[i], param2[i]);
Related
After catching an exception, how do I continue the execution of a Java program?
So I made a program to insert or delete nodes from specific positions in Doubly Linked List. Those 2 methods throw exception.
In main method, I have started to insert some int values to positions. If I entered wrong pos value insert method throws an error and catch block handle.
If I have entered 30 nodes and insert them to the correct positions except 1 Node.
-After false entry (i.e in the middle of the insertions) how can I continue to insert the rest?
public static void main(String[] args) {
LinkedList myList = new LinkedList();
try {
myList.Insert(1, 0);
myList.Insert(5, 54); // this is the false entry
myList.Insert(1, 0);
myList.Insert(1, 0);
} catch (Exception ex) {
System.out.println(ex.toString());
}
myList.Out();
myList.ReverseOutput();
}
}
So after execution, the output is 1. How can I make it [1 , 1 , 1]?
You can wrap myList.insert in a method which ignores the Exception, and use that instead:
static void insertAndIgnoreException(LinkedList list, int position, int value) {
try {
list.Insert(position, value);
} catch (LinkedListInsertionException e) {
System.out.println(e.getMessage());
}
}
So your main becomes:
public static void main(String[] args) {
LinkedList myList = new LinkedList();
insertAndIgnoreException(1, 0);
insertAndIgnoreException(5, 54); // this is the false entry
insertAndIgnoreException(1, 0);
insertAndIgnoreException(1, 0);
myList.Out();
myList.ReverseOutput();
}
Some notes:
I've used a specific exception type LinkedListInsertionException. Never catch and ignore Exception, as you'll end up missing all sort of other problems, e.g. NullPointerExceptions.
Stick to Java naming conventions in your code. i.e. insert not Insert.
Don't reuse JDK class names, i.e. use MyLinkedList not LinkedList.
In this example, you can solve this by using a loop.
Something like:
int[] numsToInsert = new int[] {1, 0, 5, 54, 1, 0, 1, 0};
for(int i = 0; i < 8; i += 2){
try {
myList.Insert(numsToInsert[i], numsToInsert[i + 1]);
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
This will catch the exception separately for each insertion by performing the insertions iteratively.
The short answer is: you don't.
... but that doesn't mean there is nothing you can do.
The purpose to a try/catch is stop all processing once an error is detected. Its purpose is to skip the rest of the code (through to the catch). It's doing exactly what it is supposed to do, it is the same as saying "skip me".
So your question "how do I run the rest of the code" can only be acheived by removing the code from "skip me" instruction.
try {
myList.Insert(1, 0);
myList.Insert(5, 54); // this is the false entry
} catch (Exception ex) {
System.out.println(ex.toString());
}
myList.Insert(1, 0);
myList.Insert(1, 0);
myList.Out();
myList.ReverseOutput();
This will give you the output you expect.
... but it doesn't feel quite right
If we are removing code from the try it almost seems like the try isn't worth having. The thing is, that try block was put there there for some reason. Try blocks are supposed to catch errors and it successfully did so, so obviously its doing something useful, and taking the code out of it feels like the wrong solution.
What we want is for each one of the lines of code to be tried, and if it fails, try the next one. Notice I said try more than once, and also "each one"
try {
myList.Insert(1, 0);
} catch (Exception ex) {
System.out.println(ex.toString());
}
try {
myList.Insert(5, 54); // this is the false entry
} catch (Exception ex) {
System.out.println(ex.toString());
}
try {
myList.Insert(1, 0);
} catch (Exception ex) {
System.out.println(ex.toString());
}
try {
myList.Insert(1, 0);
} catch (Exception ex) {
System.out.println(ex.toString());
}
This will also give you the output you want, and also handles any of those inserts kicking out an error.
... but it doesn't feel quite right
That's a lot of repetitive text, just to do the same insert over and over. If only we had a way to repeat things?
int values[4][2] = {
{1,0},
{5,54},
{1,0},
{1,0}
};
for(int v[2] : values){
try {
myList.Insert(v[0], v[1]);
} catch (Exception ex) {
System.out.println(ex.toString());
}
}
This will give you the output you want, handles any of the inserts kicking out an error, and avoids the constant repetition.
... but it doesn't feel quite right
There was no loop being used for that original code. I assume that was for a reason: possibly it was a test stub that will eventually be receiving values from somewhere else.
This indicates that having each item tested independantly is the actual purpose of this code. If so, there is a way that we could have the single line of code handle its own error:
function TryInsert(list,pos,val){
try {
list.Insert(pos, val);
return true;
} catch (Exception ex) {
System.out.println(ex.toString());
return false;
}
}
...
TryInsert(mylist, 1, 0);
TryInsert(mylist, 5, 54); // this is the false entry
TryInsert(mylist, 1, 0);
TryInsert(mylist, 1, 0);
This will give you the output you want, handles any of the inserts kicking out an error, and is more true to the original intent.
... but it doesn't feel quite right
Given you are passing in the myList object to every function call, it seems like that object is the thing to be acted upon. This would indicate that this is the true desired behaviour of your Insert function.
Perhaps you would like to alter your class, either to add this function to it, or modify the Insert to act on its own best judgement when the error occurs (either directly or through inheritance).
myList.TryInsert(1, 0);
myList.TryInsert(5, 54); // this is the false entry
myList.TryInsert(1, 0);
myList.TryInsert(1, 0);
Given I don't have access to your class ... I leave it as an exercise to the reader.
refactoring is fun
My function looks like:
public static double isOverturn(final String reference, final String hypothesis, FieldType fieldType) {
double overturnScore = 1.0;
if (StringUtils.isEmpty(reference) || StringUtils.isEmpty(hypothesis))
return overturnScore;
Method comparisonMethod = null;
try {
comparisonMethod = comparison(fieldType.getName());
overturnScore = (double) comparisonMethod.invoke(null, reference, hypothesis);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return overturnScore;
}
I want to have log.info in place of e.printStackTrace. But it is giving me error. How to use log.info in static method?
Just make your log field static. This is industry standard anyway.
That is deplorable error handling. If something goes wrong with your reflective invocation, this method returns 1.0. That seems like very silly behaviour. Generally you should just throw exceptions on if there's nothing you can do to handle it properly (and 'log it and return some throwaway default value' is rarely a valid 'handling it' strategy!), because what you do results in a long chain of exceptions, or code that straight up does the wrong thing, because as they say, garbage in, garbage out, and returning 1.0 in the face of problems with definitions sure sounds like that 1.0 is just garbage, no?
You can just catch Exception if your intent is to completely ignore what it all means, shunt it off to a log, and return a default value.
I'm beginning with Java 8 and I was wondering if I can convert a loop with a try-catch clause, into a lambda function?
Below is the method code I would like to convert into:
for (File f: files) {
JSONOject obj;
try (FileWriter fw= new FileWriter("path.csv")) {
obj= (JSONObject) parser.parse(new FileWriter(f));
readOBJ(valueType,results,obj);
results.put(day, new JobClass(day,work, time,description));
Date d= results.keySet();
Calendar c= Calendar.getinstance();
c.setTime(d);
Map<Date, JobClass> daysList= new HashMap<>();
j.insertDaysList(results,c,fw,daysList);
results.putAll(daysList);
j.resSort(results,resDayList);
} catch (IOException ex) {
e.printStacktrace();
}
}
return resDaysList;
Assuming it's the files iteration you want to convert to a Stream, that can easily be done. At the moment, your loop contents don't even throw uncaught exceptions, so there's no difficulty here (though I would suggest refactoring it into its own method first).
As lambda expressions in Java are just a means to conveniently provide implementations of single-abstract-method (SAM) interfaces as anonymous objects and the standard Stream interface offers the forEach() method for internal iteration, you can encapsulate pretty much everything you want to within your expression.
forEach(Consumer<? super T> action) expects you to provide it with an object of the Consumer interface, which need only have one method implementation consuming an object of any kind and returning no value.
So you simply put the code within your loop into the expression (or, as already proposed, transfer it into it's own method first) and you're done. The only thing you'll need to think about is how to treat your return statement, as it's not possible to return values from within the forEach() method (due to it being a so called "terminal" method of return type void). But you'll be able to pass your list into the lambda expression, modify your values in any way you see fit and keep working with it after the lambda is done, without any problem.
The try-catch-block does not affect the lambda expression itself. After all, the following two segments of code are equivalent:
List<String> someList = Arrays.asList("example", "of", "lambda", "code");
// lambda style
someList.stream().forEach( item -> {
try {
System.out.println(item.toString());
} catch (Exception e) {
e.printStackTrace();
}
});
// anonymous object style
someList.stream().forEach(new Consumer<String>() {
#Override
public void accept(String s) {
try {
System.out.println(item.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
I try to remove all PMD warnings in my project and have some difficulties. I have a method that returns a Container object. This was my original method (simplified):
try {
return setResult();
} catch (Exception ex) {
}
return null;
PMD warned that there are 2 return statements. So I tried this:
Container result = null;
try {
result = setResult();
} catch (Exception ex) {
}
return result;
=> PMD warned about initializing with null. So I tried this:
Container result;
try {
result = setResult();
} catch (Exception ex) {
}
return result;
=> Eclipse did not compile this, suggesting to use the "= null" variation.
What am I missing here? How do I have to write this method without PMD warnings?
I'd use the second approach you show:
Container result = null;
try {
result = setResult();
} catch (Exception ex) {
}
return result;
Because, as PMD points out, it is important to avoid unnecessary return statements for the purpose of reducing complexity.
The PMD documentation classifies the NullAssignment rule as "controversial". It's usefulness very much depends on the context. Here is the sample code they provide:
public void bar() {
Object x = null; // this is OK
x = new Object();
// big, complex piece of code here
x = null; // this is not required
// big, complex piece of code here
}
So, unless you can assign the Container variable with a meaningful value beforehand - you should probably ignore this rule for this code fragment.
If you want to completely avoid the null assignment, you could use Guava's Optional. In this case it has the following advantages:
It forces you to think about the absence of a value
It makes the code more understandable
It makes PMD happy
I'm very new to java and the idea of try catch blocks to handle exceptions.
This roughly what I'm ending up with, and there simply has to be a better way:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
There are more try catch blocks embedded in the same way, so that at the end, there is just a lump of catch blocks. How else should exceptions be handled, Eclipse keeps asking my to either surround with a try catch block or "Add throws declaration".
Sometimes I want to catch certain exceptions, for example if it can't find an entity, I want to print something like "Entity not found", and if the JSON string can't be parsed into an object, I want to print something like "Can't parse JSON".
(I'm used to objective-c where the are delegate methods for failure, or the method returns null and you have passed a pointer to [a pointer to] an NSError object, which will have been "filled", Is there somewhere to learn about try-catch?)
If all you're doing is catching them and printing the stack trace regardless of the exception type, you can just wrap the code in one large try/catch block. To save many "catches", you can catch java.lang.Throwable which is the interface that all exceptions implement. If not, you can have a catch for every type of checked exception the code you're calling throws, and handle them specifically.
Eclipse keeps asking you to do so because Java code will not compile if the checked exceptions are not caught, or declared to be thrown by the caller.
+Adding this comment to the answer (Thanks, Paul Tomblin):
In production quality apps you'd be logging the trace, adding some logic where you're handling the exception in a right way, taking an alternate flow, and/or re-wrapping it in another exception and throwing it, etc. It all depends on the particular problem you're trying to solve.
The idea of exception handling is that you can handle errors at points in your program flow where you can deal with them meaningfully. Rather than checking every function's return value like in C, where most of the time you can't do anything sensible other than passing the error further up, you install a try/catch block at sensible points in your program:
Basically, whenever there is a point where you can react meaningfully to an error, then catch that error, and pass everything else on. That way, error handling is only invoked when there is a plausible recovery from the error.
For example, worst case if any error stops your program from executing meaningfully, then you might almost not catch anything at all and just let the OS handle the situation (well, perhaps one single try/catch to produce a friendly error message).
Example (in C++, sorry, I'm can't type Java blind):
int main()
{
try {
while (masterloop()) { }
catch (...) {
LOG("Fatal program error, terminating!"); // nothing else we can do!
}
}
/* lots of program logic */
void process_image()
{
try {
Image im = load_image_from_disk();
/* ... */
}
catch (const OutOfMemoryExc & e) {
LOG("Not enough memory to process the image.");
return;
}
catch (const DataErrorExc & e) {
LOG("Could not read the image data.");
return;
}
catch (...) {
throw; // pass everything else along
}
}
In this example, we may try to process an image and fail for some anticipable reasons (out of memory, or failure to read the image). In that case we just return without doing work and let the program continue gracefully. All other errors are propagated up to a higher point. Most importantly, we do not need to litter the actual image processing function with error checks and responses all the time, it suffices for any code there to throw one of our two good exceptions and not worry any further.
Moral: If you have try/catch blocks absolutely everywhere, you're doing it wrong.
I know there's a lot of answers here, and they do a good job of covering how to structure the try/catch blocks. However, I'm thinking one of the things bothering you is the significant... indentation and code growth (... because I know it's not the indentation or amount of code, but the implied complexity by wrapping it and shifting it over and growing longer and longer between the opening try and enclosing catch, and I can't put a word to that apprehension).
The way to get around this is to refactor into functions the distinct bits in the code. I know it's a simplistic answer, but it's a good way to isolate individual tasks and keep the error handling fairly local to the code that requires it without padding things out vertically and horizontally with nested try/catch blocks.
You can make these methods private as they are intended for internal use only, presumably.
private Integer getDatastoreACount() {
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
return (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
// expects an Integer return, so need to deal with this
// but for simplicity I'm just simply recycling 'e'
throw e;
}
}
public void parseJSON(String jsonString) {
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
Integer dsACount = getDatastoreACount();
//etc etc
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
}
You can catch multiple exceptions in the same try e.g.
try{
xyz;
}catch(NullPointerException npx){
npx.getMessage();
}catch(ArrayOutOfBoundsException ax){
ax.getMessage();
}
Also, by declaring the Exception as throws in your method signatures you can pass the Exception up the stack.
If you're just doing something like this:
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
} catch (Exception2 e2) {reaction to e2}
You can do everything in one try-block:
try {
do smth
do smth more
...
}
catch (Exception1 e1) {reaction to e1}
catch (Exception2 e2) {reaction to e2}
You can also break this down to one catch block if you're just printing the exception:
try {
do smth
do smth more
...
}
catch (Exception e) {e.printStackTrace();}
But this doesn't if you want to do somthing more, even if e1 is thrown, like:
try {
do smth
try {
do smth more
...
} catch (Exception1 e1) {reaction to e1}
do smth even if e1 was thrown
} catch (Exception2 e2) {reaction to e2}
The last example can't be written shorter.
If you have a block of code in which more than one type of exception may be thrown, you can declare two separate catch blocks:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
//..etc.. as many catch blocks as needed
Alternatively, if you don't care about the exact type of the exception, you can have onyl one catch block which catches Exception (or maybe Throwable; I can't remember exactly what the superclass of exceptions is in Java).
Another point I will make now is that you might not have the most modular code. Remember, code that does one thing well makes for good, modular code. If you find that you have many nested black (whether try/catch blocks, if/else blocks, etc.) you may want to check if some of the code can be extracted into its own method. This may also make your code look better when many exceptions must be handled.
First, from a design perspective, catching and printing exceptions is not a good thing. Something went wrong, and your code just keeps going in the same way as if it went right. That is not usually correct. So: perhaps your method needs to throw these exceptions instead of catching them. Perhaps only the caller is in a position to decide what happens if something fails like this.
But otherwise, the only advice I can offer to clean up how the code looks, syntactically, is to tell you that you can write:
try {
...
} catch (...) {
...
} catch (...) {
...
}
You can also catch for a broader exception class like Exception and just write one catch block but this is bad design. In Java 7, you will be able to catch for several exception types in one block.
You should use try/catch blocks if you have a way to recover from the exception, for example if you want to check if a string is a valid integer, you can write a method (this is a lame method, but just to show the idea):
public boolean isInteger(String str) {
try {
new Integer(str);
}
catch(NumberFormatException e) {
return false;
}
return true;
}
If you don't have a way to recover from the exception and all you do is to print the stack trace, it is suggested to add throws declaration (as eclipse suggest) to the method, and let the caller handle the exception (or throw it to its caller).
If you want to handle some exceptions and throw some other, you can do it as well.
I like to box up the call behind a static method, just to keep it tidier. For example, here's my reduced Set Json Value call.
private static boolean setJsonValue(JSONObject j,String key,Object value)
{
try
{
if(value instanceof Integer)
{
// numbers are special. We want them unquoted.
int valueI = (Integer)value;
j.put(key,valueI);
}
else
j.put(key,value);
return true;
}
catch (JSONException e)
{
// do nothing, it turns out
return false;
}
}
...and then I ignore the return values, because I am bad.
Somewhere or other I have a similar Get method, that returns null if it fails. You get the idea.
You have two basic code-style choices here (that don't involve changing method signatures)
Method1: Put everything in the one try catch and have multiple catch blocks, like this:
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
//..etc.. more try catch blocks needed
} catch (EntityNotFoundException e) {
e.printStackTrace();
} catch (com.google.appengine.repackaged.org.json.JSONException e) {
e.printStackTrace();
}
Method 2: Break up your code into sections that each have one catch, like this:
String qURL = null;
try {
JSONObject jsonObject = new JSONObject(jsonString);
int aCount = jsonObject.getInt("acount");
String devTok = jsonObject.getString("dt");
String qURL = jsonObject.getString("qu");
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
try {
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
Key qKey = KeyFactory.createKey("qu", qURL);
int dsACount = (Integer) datastore.get(qKey).getProperty(kLastKnownANumber);
} catch (EntityNotFoundException e) {
e.printStackTrace();
}
Method 2 is the recommended one, as it makes it obvious which lines are throwing which exceptions and generally segments the code into natural processing blocks.
Create another exception and put it below or above of the other exception. Depends on the context of your application.