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(){ ... }
}
Related
I am trying to create a loading sequence of 3 dots that repeats itself until input from the user breaks the loading sequence specifically the enter key. i connot for the life of me get the infinite while loop to end with input
public class loop {
public static void AnyKey() {
try {
System.in.read();
loading(false);
} catch (Exception e){}
}
public static void pause(long duration) {
try{
Thread.sleep(duration);
} catch (InterruptedException e){}
}
public static void loading(boolean status){
if (status == true) {
while (status) {
pause(500);
int i;
for (i = 0; i <3; i++){
System.out.print(".");
pause(500);
}
System.out.print("\b\b\b");
}
}
}
public static void main(String[] args) {
loading(true);
AnyKey();
}
}
In your current code, the main method calls loading and never leaves the function. If you go through loading(true) step by step, you find that since while(status) is always true you are stuck there and AnyKey() is never called.
Also, System.in.read(); is a blocking call. This means that you will wait for user input but will be unable to print the '...'. Instead I recommend your read the documentation for input stream, there you will find the .read() function but also the .available() function which will let you know if any characters have been entered in the input buffer.
Those should be all the tools you need to figure this one out (I think).
Hope this helps!
I figured it out i needed to learn about and use Threads and global variables check out my code below im fairly pleased with myself i was working on this for 3 days now lol
import java.util.Scanner;
class AnyKey extends Thread {
public void run() {
Scanner scanner = new Scanner(System.in);
scanner.nextLine();
loadingDots.loadingStatus = false;
}
}
public class loadingDots {
public static boolean loadingStatus;
public static void pause(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {}
}
public static void loading(){
loadingStatus = true;
while (loadingStatus) {
pause(500);
int i;
for (i = 0; i < 3; i++) {
if (!loadingStatus){
break;
}
System.out.print(".");
pause(500);
}
System.out.print("\b\b\b");
}
}
public static void main(String[] args) {
AnyKey anykey = new AnyKey();
anykey.start();
loading();
}
}
I was working on one of the problems on codechef.com https://www.codechef.com/problems/ENTEXAM
Here is my solution for the problem-
import java.io.*;
class Entrance_Final
{
static BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
static int test_case=0;//Test cases
static int students=0;
static int qualifiers=0;
static long result=0;
static int exams=0;
static long max_marks=0;
static long[]sigma_res;
static long sergey_score=0;
public static void main(String[]args)throws IOException
{
try
{
//System.out.println("Enter number of test cases.");
test_case=Integer.parseInt(in.readLine());
for(int lv=1;lv<=test_case;lv++)
comp_min_marks();
}
catch(Exception e)
{
System.err.println(e);
}
}
public static void comp_min_marks()throws IOException
{
try
{
//System.out.println("Enter students,enrollees,exams and maximum marks.");
String a=in.readLine();
a=a.trim();
int flag=0;
int times=1;
for(int lv=0;lv<a.length();lv++)
{
if(a.charAt(lv)==' '&&(times==1))
{
students=Integer.parseInt(a.substring(0,lv));
flag=lv+1;
times++;
}
else if(a.charAt(lv)==' '&&(times==2))
{
qualifiers=Integer.parseInt(a.substring(flag,lv));
flag=lv+1;
times++;
}
else if(a.charAt(lv)==' '&&(times==3))
{
exams=Integer.parseInt(a.substring(flag,lv));
flag=lv+1;
times++;
max_marks=Long.parseLong(a.substring(flag));
break;
}
}
sigma_res=new long[students-1];
//System.out.println("Enter the marks of all the students during their exams,each ones in one line");
for(int lv=0;lv<students-1;lv++)
{
String b=in.readLine();
sigma_res[lv]=int_sum(b);
}
//System.out.println("Now enter Sergey's scores");
if(exams==1)
{
//String b=in.readLine();
sergey_score=0;
}
else
{
String b=in.readLine();
sergey_score=int_sum(b);
}
sigma_res=doQuickSort(0,students-2);
result=sigma_res[students-qualifiers-1]-sergey_score+1;
if(result<0)
System.out.println("0");
else if(result<=max_marks)
System.out.println(result);
else
System.out.println("Impossible");
}
catch(Exception e)
{
System.err.println(e);
}
}
public static long int_sum(String b)throws IOException
{
try
{
b=b.trim();
long res=0;
int flag=0;
for(int lv=0;lv<b.length();lv++)
{
if(b.charAt(lv)==' ')
{
res+=Long.parseLong(b.substring(flag,lv));
flag=lv+1;
}
}
res+=Long.parseLong(b.substring(flag));
return res;
}
catch(Exception e)
{
System.err.println(e);
return -1;
}
}
private static long[] doQuickSort(int low,int high)throws IOException
{
try
{
if(high-low<1)
return sigma_res;
int wall=low;
int pivot_pos=(int)(Math.random()*(high-low))+low;
long pivot=sigma_res[pivot_pos];
long temp=sigma_res[high];
sigma_res[high]=pivot;
sigma_res[pivot_pos]=temp;
pivot_pos=high;
for(int lv=low;lv<=high-1;lv++)
{
if(pivot>sigma_res[lv])
{
temp=sigma_res[lv];
sigma_res[lv]=sigma_res[wall];
sigma_res[wall]=temp;
wall++;
}
}
temp=sigma_res[wall];
sigma_res[wall]=pivot;
sigma_res[pivot_pos]=temp;
pivot_pos=wall;
doQuickSort(low,wall-1);
doQuickSort(wall+1,high);
return sigma_res;
}
catch(Exception e)
{
System.err.println(e);
return sigma_res;
}
}
}
As you have probably noticed, I have enclosed all the code within my program in rather redundant try-catch blocks returning arbitrary exceptions. This is because I am always getting an NZEC-Error for my code (when I submit it online) and despite using these blocks, the error is persisting. I have repeatedly had a look at the constraints of the problem but had no luck figuring out what the issue is.
P.S I do not have access to the test cases of this problem.
Since there is no response here and I was able to figure out the issue, I suppose I might as well as answer my question. So first of all there was no exception at all, instead I was getting a VirtualMachineError in the line
sigma_res=new long[students-1];
(No idea why this was happening,all I know is the value of 'students' exceeded its constraint-defined limits).
After looking at a few solutions, I figured the issue was caused by taking the println statements out of the main() method and placing them in another one.
The moment I put the println statement back into main(), the solution was accepted.
P.S I still don't know why the program wouldn't terminate when the println statements where in another method.
public class abc{
public static void main(){
try{
int a =10;
if(a=10){
throw new Exception();
}
l1:System.out.println(a);
}catch(Exception e){
continue l1;
}
}
}
Actually what I am trying to do is when an exception occurs I wish to continue the next statement after that as well.
Is there any way I can achieve it with Java?
You would just want to put System.out.println(a); in the catch block.
Putting it in a finally block would mean that it is executed even when an exception does not occur. The program only goes to the catch block when an exception occurs.
I think this is what you want?
public static void main(String[] args) {
int a = 9;
try {
if (a == 10) {
throw new Exception();
}
} catch (Exception e) {
e.printStackTrace(); // only if there is any exception
} finally {
System.out.println(a); // always print this message
}
}
Or if a is 10
public static void main(String[] args) {
int a = 10;
try {
if (a == 10) {
throw new Exception();
}
} catch (Exception e) {
e.printStackTrace(); // only if there is any exception
} finally {
System.out.println(a); // always print this message
}
}
try some thing like
int a =0;
try{
a =10;
if(a=10){
throw new Exception();
}
} catch(Exception ex){
//do nothing
} finally {
l1:System.out.println(a);
}
Anyway in java avoid jumping
I have such code in my program
for(int i = 0; i < 100000; i++) {
func(i);
}
For most values of i, func lasts less than 1 sec, but for some values it may last several minutes, so I need to interrupt it if it lasts too long.
How can I do that?
FutureTask is perfect for executing code with timeout.
FutureTask task = new FutureTask(new Callable() {
#Override
public Object call() throws Exception {
/* Do here what you need */
return null; /* Or any instance */
}
}) {
};
try {
Object result = task.get(1, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
Logger.getLogger(Example1.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(Example1.class.getName()).log(Level.SEVERE, null, ex);
} catch (TimeoutException ex) {
Logger.getLogger(Example1.class.getName()).log(Level.SEVERE, null, ex);
}
}
One way to interrupt a function that may take too long is by running it in a separate thread. You can then send a message to that thread after a second to tell it to stop. Without using threads, you could handle it by replacing func with the code below:
function process(int i, long maxMiliseconds) {
long start = System.currentTimeMillis();
while(System.currentTimeMillis() - start < maxMiliseconds) {
//do your processing one step at a time
// return an answer if you have one.
}
//make some record of the fact that the process timed out for i.
return;
}
You can start func() in a separate thread and then do method join(long millis) on your thread to wait for 1 second for it's ending. But still the thread will run until it finish (stop() method is deprecated). The means of this is to get control in your current thread and react appropriately
This is the way I see it. I am sure there are ways to do it in less lines of code, but this one is straightforward solution
If you would want to run your func(i); in Thread then it would be another story.
public class MainClass {
private static boolean riding, updated = false;
private static int timeout = 10000;
public static void main(String[] args) {
while (true) {
if (!riding){
long endTimeMillis = System.currentTimeMillis() + timeout;
func(endTimeMillis);
}
}
}
private static void func(long endTimeMillis) {
for (int i = 0; i < 9999; i++) {
if ((!riding && System.currentTimeMillis() < endTimeMillis) || updated) {
updated = false;
System.out.println("run method main function");
riding = true;
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(System.currentTimeMillis() + " > "
+ endTimeMillis);
if (System.currentTimeMillis() > endTimeMillis) {
updated = true;
System.out.println("overdue");
riding = false;
break;
}
}
}
riding = false;
}
}
You can inject your exception handling into func if you dont want another thread.
public static void main(String[] args)
{
try
{
func(1);
}
catch (timeR e)
{
System.out.println("enough!")
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static void func(int a) throws timeR //your func needs to throw something when time-is-up
{
long time1,time2; //reference time and current time
time1=System.nanoTime(); //having reference
time2=System.nanoTime(); //init of current
while(true) //You did not put your func, so I used inf-while
{
//here whatever your func does,
//.....
//.....
//below line checks if time is up
time2=System.nanoTime();
if((time2-time1)>1000000000) //1000000000 is 1 second or 1Billion nanoseconds
{ throw new timeR("time is up!");}
//this is throwing(an alternative exit from this function)
}
}
static class timeR extends Exception
{
//Parameterless Constructor
public timeR()
{
}
//Constructor that accepts a message
public timeR(String message)
{
super(message);
}
}
Output: 1 second after func() called:
enough!
proje.lineerCebir$timeR: time is up!
at proje.lineerCebir.func(lineerCebir.java:198)
at proje.lineerCebir.main(lineerCebir.java:179)
Maybe you dont want to see red messages, then just comment out the e.printStackTrace().
Have fun.
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");
}
}