Question

Do you know any way to and log all exceptions that are ever thrown (whether catched and handled or not) in java?

Here is my issue: There is an application, that I cannot change, and sometimes it has issues creating a lockfile (relevant code below). When it calls the tryLock() method , freezes for 30 seconds (despite the fact that tryLock is nonblocking), and returns with failure (CANT_CREATE_LOCK). As you see, all the catch tiers mask away the real problem, without even logging it.

final File lockFile = new File(fooHomeDir, ".foo-home.lock");
try
{
    FileOutputStream stream = new FileOutputStream(lockFile);
    try
    {
        if (stream.getChannel().tryLock() == null)
        {
            return LockResult.HELD_BY_OTHERS;
        }
        this.fileOutputStream = stream;
        this.lockFile = lockFile;
        return LockResult.OK;
    }
    catch (OverlappingFileLockException overlappingFileLockException)
    {
        return LockResult.HELD_BY_OTHERS;
    }
    catch (IOException ie)
    {
        return LockResult.CANT_CREATE_LOCK;
    }
}
catch (FileNotFoundException fnfe)
{
    return LockResult.CANT_CREATE_LOCK;
}

What I wish: Able to see what was the details of the exceptions.

Other info:

  • The environment is Linux, Java 1.7, Tomcat 7.
  • The fooHomeDir points to an NFS-backed mount point.
  • The fooHomeDir's permissions did not change.
  • The fooHomeDir's owner did not change.
  • The fooHomeDir's filesystem is not full.
  • There is no SELinux, or other thing that may interfere.

Basically, it worked before, and stopped "suddenly" and "without cause". So right now I'm investigating.

I'm commencing a remote debug of the application, but until then, suggestions are welcome :-)

Thanks, joe

UPDATE

For the record, the root cause of the issue was that the rpc.statd daemon died. Hence, the native locking mechanism failed over NFS. The symptom was an IOException with the message: "No locks available".

Kudos to Hans Maes

Was it helpful?

Solution

You could create your own implementation of Exception, which will log every error created. And then add it to the classpath with the -Xbootclasspath:bootclasspath flag. I wouldn't recommend it as a 'best practice' but at least you can find the source of your problem.

A very quick example (with room for improvement)

package java.lang;

public class Exception extends Throwable {

public Exception() {
    super();
    String exception = "Exception";
    logWithStack(exception);

}

public Exception(String message) {
    super(message);
    logWithStack(message);
}

public Exception(String message, Throwable cause) {
    super(message, cause);
    logWithStack(message);
}

public Exception(Throwable cause) {
    super(cause);
    logWithStack(cause.getMessage());
}

protected Exception(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
    super(message, cause, enableSuppression, writableStackTrace);
    logWithStack(message);
}

private void logWithStack(String exception) {
    System.out.println(exception);
    for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
        System.out.println(ste);
    }
}

}

Compile to a class file and then add -Xbootclasspath:/directoryWhereClassFileIsLocated/ to the tomcat options.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top