I have an interesting issue. My code block is given below. The problem is : log file does not contains "Getting ready to sleep.." line but it contains "Backup thread was interrupted..." lines.
My question : Is it possible to catch exception without getting in its try block ?
long sleepTime = runtime.getTimeInMillis() - Calendar.getInstance().getTimeInMillis();
try {
log("Getting ready to sleep...(" + sleepTime + ")");
Thread.sleep(sleepTime);
Database db = new Database();
log(db.performDatabaseBackup());
// Set it to run the next day.
runtime.add(Calendar.DATE, 1);
} catch (InterruptedException ie) {
log("Backup thread was interrupted...");
}
Edit : Log method
private void log(String message) {
Logger.debug(this, message);
}
and Logger.debug
public static void debug(
Object obj,
String message ){
debug( obj.getClass(), message );
}
public static void debug(
String className,
String message )
{
try
{
Class inputClass = Class.forName( className );
debug( inputClass, message );
}
catch ( ClassNotFoundException e )
{
debug( ( Class )null, message );
}
}
No it is not possible to catch an Exception not thrown during execution of its try block. Possible situations:
InterruptedException is thrown before you log "Getting ready..." i.e. in your log(...) call. (unlikely)
Log method does not work as expected and does not log your line. (likely) Can you check if the sleep is performed by setting a high sleep time. That would imply this reason.
You have other pieces of code logging "Backup thread was interrupted..." that cause the log output and the presented code fragement is not executed at all.
My guess would be that the log method is not functioning properly? I don't believe that the catch block can be entered without entering the try block. Another alternative is that the log method throws InterruptedException?
Can you post your log method as well?
If you enter the catchblock an exception has been thrown inside the try block. Period.
To solve your problem: Print the stacktrace of the exception and look if log() also throws some exceptions.
Related
Here inside the for loop I'm trying to get the value from stringCompletableFutureEntry which throws the InterruptedException and with sonar enabled on this, I am supposed to interrupt the thread when an exception occurs but according to my expectation I should get data for all futures if it's not there than I can use Optional.empty() or skip this iteration and move further. How should I get rid of this sonar issue?
private void mapFutures(
Map<Obj1, CompletableFuture<DummyContainer>> futures, List<DummyStatus> dummyStatusList) {
for (Map.Entry<Obj1, CompletableFuture<DummyContainer>> stringCompletableFutureEntry :
futures.entrySet()) {
try {
Optional<DummyContainer> dummyContainer =
Optional.ofNullable(**stringCompletableFutureEntry.getValue().get()**);
List<Dummy> dummy = null;
dummy = dummyContainer.map(DummyContainer::getDummyData).orElseGet(() -> null);
if (!CollectionUtils.isEmpty(dummy)) {
dummyStatusList.add(new DummyStatus(stringCompletableFutureEntry.getKey(), dummy.get(0)));
} else {
dummyStatusList.add(new DummyStatus(stringCompletableFutureEntry.getKey()));
}
} catch (InterruptedException | ExecutionException e) {
Thread.currentThread().interrupt(); // sonar expectation
}
}
}
I tried using timeout while getting data e.g.
stringCompletableFutureEntry.getValue().get(Long.parseLong("3000"), TimeUnit.MILLISECONDS))
It'll throw a TimeoutException once the time threshold is reached.
I'm looking for other Solutions to get rid of InterruptedException inside the loop.
I have to write tests for a website that sometimes hangs indefinitely while loading a page. I'd like to write a method that times out 20 minutes after it starts running.
But when I try to write code like this -
#Test(timeOut=4000)
public void test() {
try { Thread.sleep(5000); } catch (InterruptedException e) {}
System.out.println("I don't want this to print.");
}
The test prints "I don't want this to print." and THEN fails with the intended exception - org.testng.internal.thread.ThreadTimeoutException: Method didn't finish within the time-out 4000
How can I get the test to fail as soon as the time limit is reached?
TLDR;
Do not catch InterruptedException just put in throws clause.
As TestNG works (in this case) the framework will create a new single-threaded executorService, submit a worker which will be waiting for termination. If the test running was not finished the worker will throw org.testng.internal.thread.ThreadTimeoutException.
Related source code is:
org.testng.internal.MethodInvocationHelper
private static void invokeWithTimeoutWithNewExecutor(
ITestNGMethod tm,
Object instance,
Object[] parameterValues,
ITestResult testResult,
IHookable hookable)
throws InterruptedException, ThreadExecutionException {
ExecutorService exec = ThreadUtil.createExecutor(1, tm.getMethodName());
InvokeMethodRunnable imr =
new InvokeMethodRunnable(tm, instance, parameterValues, hookable, testResult);
Future<Void> future = exec.submit(imr);
exec.shutdown();
long realTimeOut = MethodHelper.calculateTimeOut(tm);
boolean finished = exec.awaitTermination(realTimeOut, TimeUnit.MILLISECONDS);
if (!finished) {
exec.shutdownNow();
ThreadTimeoutException exception =
new ThreadTimeoutException(
"Method "
+ tm.getQualifiedName()
+ "() didn't finish within the time-out "
+ realTimeOut);
testResult.setThrowable(exception);
testResult.setStatus(ITestResult.FAILURE);
} else {
Utils.log(
"Invoker " + Thread.currentThread().hashCode(),
3,
"Method " + tm.getMethodName() + " completed within the time-out " + tm.getTimeOut());
// We don't need the result from the future but invoking get() on it
// will trigger the exception that was thrown, if any
try {
future.get();
} catch (ExecutionException e) {
throw new ThreadExecutionException(e.getCause());
}
testResult.setStatus(ITestResult.SUCCESS); // if no exception till here then SUCCESS.
}
}
The point is:
ExecutorService exec = ThreadUtil.createExecutor(1, tm.getMethodName());
// ... and
boolean finished = exec.awaitTermination(realTimeOut, TimeUnit.MILLISECONDS);
The java.util.concurrent.ExecutorService.awaitTermination(...) method throws InterruptedException which was handled in the test method. Because of this the test method won't be terminated but the finished flag will be false.
So it will help:
#Test(timeOut = 4000)
public void test() throws InterruptedException {
Thread.sleep(5000);
System.out.println("I don't want this to print");
}
I am calling a method from a third party jars whose class file is not accessible to me. So for some cases it throws exception logs and I want to extract string from the current log dynamically.
This is the java program method which throws exception
public String runLayoutTest(final String xmlFile){
try{
String gettingValue = "novalue";
boolean errorFlag = perform("runLayoutTest", new Reporter.Reportable() {
#Override
public boolean run() throws Exception {
String layoutXml = null;
//current directory
Path currentRelativePath = Paths.get("");
String currentProjectPath = currentRelativePath.toAbsolutePath().toString();
System.out.println("Current relative path is: " + currentProjectPath);
System.out.println("layoutXml "+xmlFile);
String x = client.runLayoutTest(currentProjectPath+"\\Excel\\"+xmlFile);
System.out.println("******* x ********"+x);
setX(x);
return true;
}
});
gettingValue = getX();
return gettingValue;
}catch(Exception e){
System.out.println("**Any one rule in Layout is failed**");
//System.out.println(e.getMessage());
return getX();
}
}
Here the client is a object of the third party jar file , And that is throwing me the exception on some odd cases .
The Exception logs are
com.experitest.client.InternalException: Exception caught while executing runLayoutTest: {"rule_1":{"Exists":true},"rule_2":{"Exists":true,"EqualHeight":false},"rule_3":{"AlignedLeft":false}}
at com.experitest.client.JavaClientInternals.executeInternally(JavaClientInternals.java:234)
at com.experitest.client.Client.execute(Client.java:237)
at com.experitest.client.Client.runLayoutTest(Client.java:1475)
at com.igate.framework.NativeDriver$79.run(NativeDriver.java:2753)
at com.igate.framework.Reporter.action(Reporter.java:81)........
From this exception I want to extract
runLayoutTest: {"rule_1":{"Exists":true},"rule_2":{"Exists":true,"EqualHeight":false},"rule_3":{"AlignedLeft":false}}
as a String.
Hence is there any method with which I can dynamically extract such String whenever it occurs.
And I still don't know the reason why my catch method is not getting called.
In your case you can just use Exception.getMessage() which will result in
Exception caught while executing runLayoutTest:
{"rule_1":{"Exists":true},"rule_2":{"Exists":true,"EqualHeight":false},"rule_3":{"AlignedLeft":false}}
Below can be used to get the json string. You can then parse the json to get desired data from it
String message = e.getMessage();
int colonIndex = message.indexOf(":");
String json = null;
if (colonIndex != -1) {
json = message.substring(colonIndex + 1);
}
Please note that this solution will not work in case of wrapped exception
I had to implement this code to attack directly to throwable detailMessage. I had to ignore all the hierarchy of classes that extended Exception because someone implemented a horrible getMessage method that was being overlapped with web components. In JUnit was no way to define unit test cases because framework's exceptions always tried to translate its error code into the 'session' (web) language...
public static Object getThrowableDetailMessage(Throwable throwable) {
try {
// Tiramos la puerta abajo y pedimos a Throwable que nos pase el código de error
Field f = Throwable.class.getDeclaredField("detailMessage");
f.setAccessible(true);
Object detailMessageFound = f.get(throwable);
return detailMessageFound;
} catch (SecurityException ex) {
//LOG
return null;
} catch (NoSuchFieldException e) {
//LOG
return null;
} catch (IllegalArgumentException e) {
//LOG
return null;
} catch (IllegalAccessException e) {
//LOG
return null;
}
}
You also can try to replace Throwable by InternalException and keep the reflection on this level of the hierachy. But like someone is already pointing. Make sure your code is being affected by the Exception you want to inspect.
I have implemented all the catches possible because I wanted to trace a different log for everyone of them. (For debugging and testing overall)
Note: My code has been implemented under JDK 1.6_18
How can I make my Java run again from the start (main) when it encounters an exception without closing and running it again manually?
My program basically writes on a file. When it cannot find the file I will throw the FileNotFoundException then write the file (say for example hello.txt). After it writes, the program closes (in NetBeans cause I am still developing it) and start showing this at the buttom:
Exception in thread "main" java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:542)
at java.lang.Integer.parseInt(Integer.java:615)
at app4pics1word.App4pics1word.cache(App4pics1word.java:127)
at app4pics1word.App4pics1word.<init>(App4pics1word.java:18)
at app4pics1word.App4pics1word.main(App4pics1word.java:146)
Java Result: 1
you can try this
public static void main(String[] args) {
try {
//something wrong happens here
}catch(Throwable e) {
e.printStackTrace();
main(args);
}
}
You should use exception handling instead of restarting the program. If you restart the program, the error will still be there and thus your program will keep on trying to run for eternity, always failing with the same exception.
You would like to catch your exception and make sure that the input is valid:
boolean okInput = false;
int x = -1;
String someData = "rr";
do {
try {
x = Integer.parseInt(someData); // try to parse
okInput = true;
} catch(NumberFormatException n) {
// Error, try again
okInput = false
someData = "2";
}
} while(!okInput); // Keep trying while input is not valid
// Here x is a valid number
This tutorial provides you good code in general of how exceptions work.
is this what you are looking for ?
public static void main(String [] args) {
boolean done = false;
do {
try {
writeSomeFile();
done = true;
}
catch (Exception ex)
{
System.out.println("Exception trapped "+ex)
}
} while (!done);
}
You can make it a loop that is broken only when the try block succeeds without an Exception:
public static void main(String[] args) {
while(true) {
try {
...
break; //at the end of try block
}
catch (SomeException e) {
//print error message here, or do whatever
}
}
//program continues here once try block gets through w/o exceptions
...
}
However, instead of having this in your main I recommend hiding this rather ugly structure inside a method.
I have used log4j for looging error log using FileAppender. The problem is its logging the same error two times in a log file when the below situation
Case1:
Class1 :
public void func(){
try{
new Class2.prop()
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop(){
try{
//error oocurs here
}catch(FileNotFoundException fe){
logger.log(2,fe);
}
}
Error :
Class2 .FileNotFoundException
at Class2.prop(Class2.java:3)
at Class1.func(Class1.java:4)
Log File :
FileNotFound exception
FileNotFound exception
But its logging the error one time for the below case.
Case2 :
Class1 :
public void func(){
try{
new Class2.prop()
//error oocurs here
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop(){
try{
}catch(FileNotFoundException fe){
logger.log(2,fe);
}
}
Error :
Class2 .IOException
at Class1.func(Class1.java:4)
Log File :
IOException exception
Help me what should i do to log the error only one time in a log file whereever it is.
But its logging the error one time for the below case.
That's because you're handling the exception:
Class1:
public void func() {
try{
new Class2.prop()
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop() throws IOException {
try{
//error oocurs here
}catch(FileNotFoundException fe){
logger.log(2,fe);
throw fe;
}
// Here!!!!!
}
In your catch block of the class2 ( after your //error oocurs here ) you log the exception, that's what you've got on your logs.
But since you are just logging the exception, you're telling the program that the exception has been controlled somehow, or handled ( which is more appropriate) and the program continues it's flow to the line where I added the comment // Here!!!!!
Later in class1, since the exception was handled, nothing happens in your try/catch block and your second exception is never logged ( as you expected ) because it never happened.
If you want to see two logs ( which I think it's unnecessary ) you should re-throw the exception as I did in your class2 and plus, modify the method signature to mark indicate it throws an IOException.
That way you will have two logs.
Better will be like this:
Class1:
public void func() {
try{
new Class2.prop()
}catch(IOException ioe){
logger.log(2,ioe);
}
}
Class2 :
public void prop() throws IOException {
//error oocurs here
}
In class 2 you don't handle the exception, you just let it go through the caller. In the stacktrace you'll have the information anyway.
I hope this helps.
In your log4j configuration, do you have the logger used in Class 2 being sent to your appender twice?