I'm trying to create a method f1(x) that throws an exception when x equals 5. After that I will try to call that method from another method f2() to invoke that exception. Then I have to have f2() recover by calling f1(x+1). I tried coding something, but I'm stuck. Here is the code:
public class FiveException extends Exception {
public void f1(int x) throws FiveException {
if (x == 5) {
throw new FiveException();
}
}
public void f2() {
int x = 5;
try {
f1(x);
}catch (FiveException e) {
System.out.println("x is 5");
}
}
public static void main(String[] args) {
FiveException x5 = new FiveException();
x5.f2();
}
}
The print statement works, but I'm not sure how to call f(x+1). Any help on how to fix this and any techniques to write exceptions is appreciated.
Because f1 throws FiveException, wherever you call f1 you must either catch the exception or throw it to the method calling the method that raises the exception. For example:
public static void main(String[] args) throws FiveException {
FiveException x5 = new FiveException();
x5.f1(1);
}
Or:
public static void main(String[] args) {
FiveException x5 = new FiveException();
try {
x5.f1(1);
} catch (FiveException e) {
e.printStackTrace();
}
}
But your code is confusing... normally, it isn't the exception class that throws itself, you have other classes that throw the exception class.
If it's being invoked inside a catch statement, you must surround it with another try-catch, 'cause the code inside catch isn't protected, like this:
public void f2() {
int x = 5;
try {
f1(x);
}catch (FiveException e) {
System.out.println("x is 5");
try {
f1(x + 1);
} catch (FiveException e) {
e.printStackTrace();
}
}
}
But this code is ugly, you can write the following:
public void f2() {
int x = 5;
fProtected(x);
fProtected(x + 1);
}
private void fProtected(int x) {
try {
f1(x);
}catch (FiveException e) {
System.out.println("x is 5");
}
}
Related
public class Sample {
public static void main(String[] args) {
method();
}
public static void method()
{
try {
System.out.println("function");
throw new StaleElementReferenceException("thih sexception occured");
}
catch (StaleElementReferenceException e) {
method();
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
}
how to avoid Infinite Recursion in a non-return method with Try catch...For Example this code below...when the StaleElementException Occurs only once i want to execute "functions after Exception , if the Stale Element occurs the second time i want it to go to Exception catch and print Assert fail..how?
public class Sample {
public static void main(String[] args) {
method(false);
}
public static void method(boolean calledFromCatchBlock)
{
try {
System.out.println("function");
if(!calledFromCatchBlock) {
throw new StaleElementReferenceException("thih sexception occured");
} else {
throw new Exception();
}
} catch (StaleElementReferenceException e) {
method(true);
} catch (Exception e) {
System.out.println("AssertFail");
}
}
}
You should store somehow the state when you throw an exception (e.g. a boolean flag) outside method(), check this state and throw modified exception next time:
private static boolean alreadyThrown = false;
public static void method()
{
try {
System.out.println("function");
if (alreadyThrown) {
throw new RuntimeException("another exception occured");
} else {
alreadyThrown = true;
throw new StaleElementReferenceException("this exception occured");
}
}
catch (StaleElementReferenceException e) {
method();
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
Or you could provide some argument to the method(int arg) and check its value in a similar way:
public static void main(String[] args) {
method(1);
}
public static void method(int arg)
{
try {
System.out.println("function");
if (arg > 1) {
throw new RuntimeException("another exception occured");
} else {
throw new StaleElementReferenceException("this exception occured");
}
}
catch (StaleElementReferenceException e) {
method(arg + 1);
}
catch (Exception e) {
System.out.println("AssertFail");
}
}
If I have multiple resources, in a try catch, which one gets closed called on first?
public class TestRes {
public static void main(String[] args) {
TestRes tr = new TestRes();
tr.test();
}
public void test() {
try (MyResource1 r1 = new MyResource1(); MyResource2 r2 = new MyResource2(); ) {
System.out.print("T ");
} catch (IOException ioe) {
System.out.print("IOE ");
} finally {
System.out.print("F ");
}
}
class MyResource1 implements AutoCloseable {
public void close() throws IOException {
System.out.print("1 ");
}
}
class MyResource2 implements Closeable {
public void close() throws IOException {
throw new IOException();
}
}
}
This sample outputs:
T 1 IOE F
If I change the order so...
public class TestRes {
public static void main(String[] args) {
TestRes tr = new TestRes();
tr.test();
}
public void test() {
try (MyResource2 r2 = new MyResource2(); MyResource1 r1 = new MyResource1();) {
System.out.print("T ");
} catch (IOException ioe) {
System.out.print("IOE ");
} finally {
System.out.print("F ");
}
}
class MyResource1 implements AutoCloseable {
public void close() throws IOException {
System.out.print("1 ");
}
}
class MyResource2 implements Closeable {
public void close() throws IOException {
throw new IOException();
}
}
}
I get the same output - why?
It seems that you believe an exception from a close() method will prevent other close() methods from being called. That is wrong.
The Java Language Specification, section 14.20.3. try-with-resources, says:
Resources are closed in the reverse order from that in which they were initialized. A resource is closed only if it initialized to a non-null value. An exception from the closing of one resource does not prevent the closing of other resources. Such an exception is suppressed if an exception was thrown previously by an initializer, the try block, or the closing of a resource.
Which means that the close() method printing 1 will always be executed, and the first part answers your "Which close() runs first?" question.
I want to create a program that can relaunch itself if they detected any exception error during the execution.
Let say my program is trying reading a file. If the program failed to read a file, then it will have FileNotFound exception. After this exception occur, the program itself will restart and retry it again. This process will continue 3 times and if the program still cannot read that file, the program will then terminated and an exception message will be printed.
I created the read file part, but I have trouble to restart my program if it detect an error. Any help will be appreciated. I have included my pesudo code of what I am trying to do in the relaunch method.
fileReader.java
private static final int MAX_RETRIES = 3 ;
private static final int WAIT_BETWEEN_RETRIES_SEC = 30 ;
public static void main(String... args)
{
int retry = 1;
while (retry <= MAX_RETRIES) {
try {
//this method is okay, good. pass to next method.
readFile();
//error detected, retry only this method. Error fixed, pass to next method
method2();
//error detected, retry only this method. Error fixed, pass to next method
method3();
method4();
method5();
break;
} catch (IOException e) {
e.printStackTrace();
retry++;
try {
Thread.sleep(WAIT_BETWEEN_RETRIES_SEC * 1000);
} catch (InterruptedException e1) {}
}
}
if (retry == MAX_RETRIES) {
System.out.println("Failed!");
return;
}
// success
}
private static void readFile() throws IOException {
//read file code
}
instead of relaunching, you can (and should) handle this in main(). For example:
private static final int MAX_RETRIES = 3 ;
private static final int WAIT_BETWEEN_RETRIES_SEC = 30 ;
public static void main(String... args)
{
int retry = 1;
while (retry <= MAX_RETRIES) {
try {
readFile();
break;
} catch (IOException e) {
e.printStackTrace();
retry++;
try {
Thread.sleep(WAIT_BETWEEN_RETRIES_SEC * 1000);
} catch (InterruptedException e1) {}
}
}
if (retry == MAX_RETRIES) {
System.out.println("Failed!");
return;
}
// success
}
private static void readFile() throws IOException {
//read file code
}
Please try to use FutureTask under package java.util.concurrent. This support the feature the one you are looking for.
You don't have to restart the whole application after unsuccesfully reading a file - just re-run the problematic function (readFile() in this case).
Simply put readFile() in your reLaunch() function
private static void reLaunch(int relaunchAttempt){
readFile();
}
Or
private static void readFile(){
try{
//read file code
}catch(FileNotFoundException e){
//relaunch the application if error detected
readFile(count);
e.printStackTrace()
}
}
Maintain count in readFile() function
public class fileReader {
private static final MAX_RETRY = 3;
public static void main (String[] args){
int retry = 0;
while (retry++ < MAX_RETRY) {
try {
readFile();
break; // Break while loop
} catch (Exception e) {
if (retry == MAX_RETRY) {
// Failed 3 times
return;
}
}
}
// Success!
method1();
method2();
method3();
}
private static void readFile(){ ... }
private static method1(){ ... }
private static method2(){ ... }
private static method3(){ ... }
}
try-with-resources is nice and all that, but it seems to me that it is still not sufficient for effective resource management when creating classes that wrap multiple AutoCloseable objects. For example, consider
import java.io.*;
class AutocloseableWrapper implements AutoCloseable {
private FileReader r1;
private FileReader r2;
public AutocloseableWrapper(String path1, String path2) throws IOException {
r1 = new FileReader(path1);
r2 = new FileReader(path2);
}
#Override
public void close() throws IOException {
r1.close();
r2.close();
}
public static void main(String[] args) throws IOException {
try (AutocloseableWrapper w = new AutocloseableWrapper("good-path", "bad-path")) {
System.out.format("doing something\n");
throw new IOException("doing something in main");
}
}
}
There are at least two issues with this wrapper:
If "bad-path" is invalid and causes the assignment to r2 to throw, then r1 is not closed.
If wrapper construction succeeds but then r1.close throws, then r2 is not closed.
All those issues can be addressed, but then writing the wrapper becomes quite non-trivial and error-prone, even if wrapping only two resources:
import java.io.*;
class AutocloseableWrapper implements AutoCloseable {
private FileReader r1;
private FileReader r2;
public AutocloseableWrapper(String path1, String path2) throws IOException {
r1 = new FileReader(path1);
try {
r2 = new FileReader(path2);
}
catch (IOException e) {
try {
r1.close();
}
catch (IOException e2) {
e.addSuppressed(e2);
}
throw e;
}
}
#Override
public void close() throws IOException {
IOException e = null;
try {
r1.close();
}
catch (IOException e1) {
e = e1;
}
try {
r2.close();
}
catch (IOException e2) {
if (e == null)
throw e2;
else {
e.addSuppressed(e2);
throw e;
}
}
}
public static void main(String[] args) throws IOException {
try (AutocloseableWrapper w = new AutocloseableWrapper("good-path", "bad-path")) {
System.out.format("doing something\n");
throw new IOException("doing something in main");
}
}
}
Is there some helper class or any other way to make writing wrappers easier?
You should enable the syntactic code unwrapped by the compiler....You can find the Oracle article over here :-
http://www.oracle.com/technetwork/articles/java/trywithresources-401775.html
Coming to the question,if you have a wrapper you can do something like this
#Override
public void close() throws IOException {
Throwable t = null;
try {
r1.close();
} catch (Throwable t1) {
t = t1;
throw t1;
} finally {
if (t != null) {
try {
r2.close();
} catch (Throwable t2) {
t.addSuppressed(t2);
}
} else {
r2.close();
}
}
}
Note:This will work because of precise rethrow feature in Java 7
You could use a generic resource wrapper such as:
public class CloseableChain implements AutoCloseable {
private AutoCloseable r1;
private CloseableChain r2;
public void attach(AutoCloseable r) {
if (r1 == null) {
r1 = r;
} else {
if (r2 == null) {
r2 = new CloseableChain();
}
r2.attach(r);
}
}
public void close() throws Exception {
if (r1 == null) {
return;
}
Throwable t = null;
try {
r1.close();
} catch (Throwable t1) {
t = t1;
throw t1;
} finally {
if (r2 != null) {
if (t != null) {
try {
r2.close();
} catch (Throwable t2) {
t.addSuppressed(t2);
}
} else {
r2.close();
}
}}}}
Then you could refactor your code to:
import java.io.*;
class AutocloseableWrapper implements AutoCloseable {
private CloseableChain chain;
private FileReader r1;
private FileReader r2;
private FileReader r3;
public AutocloseableWrapper(String path1, String path2) throws IOException {
chain = new CloseableChain();
r1 = new FileReader(path1);
chain.attach(r1);
r2 = new FileReader(path2);
chain.attach(r2);
// and even more...
r3 = new FileReader("whatever");
chain.attach(r3);
}
#Override
public void close() throws IOException {
chain.close();
}
public static void main(String[] args) throws IOException {
try (AutocloseableWrapper w = new AutocloseableWrapper("good", "bad")) {
System.out.format("doing something\n");
throw new IOException("doing something in main");
}
}
}
i have an error in this code that's the thread set 2 value instead of one when the program start , the program mustn't set the next value before get the current
this is the main class
class DATA
{
private int value=0;
Lock lock;
Condition co;
Boolean IstReady=false;
public DATA()
{
IstReady=false;
lock = new ReentrantLock();
co=lock.newCondition();
}
public void set(int x) throws InterruptedException
{
lock.lock();// try
while(IstReady==true)
co.await();
value=x;
IstReady=true;
co.signal();
lock.unlock();
}
public int get()
{
int ret=0;
try{
lock.lock();
while(IstReady==false)
co.await();
ret=value;
co.signal();
//lock.unlock();
}
catch(Exception e)
{
System.out.println(e);
}
finally{
lock.unlock();
IstReady=false;
}
return ret;
}
}
}
}
and this the set() and get() class
class setter extends Thread
{
DATA D;
public setter(DATA X)
{
D=X;
}
#Override
public void run()
{
Random T=new Random();
while(true)
{
try {
int M=T.nextInt(1000);
System.out.println("setter set"+M);
D.set(M);
} catch (InterruptedException ex) {
Logger.getLogger(setter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
public class Newtest {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
DATA x=new DATA();
setter s=new setter(x);
getter g=new getter(x);
s.start();
g.start();
}
}
i think the error is in the set() and get() method in DATA class