Uncatchable ChuckNorrisException

JavaExceptionException HandlingAop

Java Problem Overview


Is it possible to construct a snippet of code in Java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?

Thoughts that came to mind are using for example interceptors or aspect-oriented programming.

Java Solutions


Solution 1 - Java

I haven't tried this, so I don't know if the JVM would restrict something like this, but maybe you could compile code which throws ChuckNorrisException, but at runtime provide a class definition of ChuckNorrisException which does not extend Throwable.

UPDATE:

It doesn't work. It generates a verifier error:

Exception in thread "main" java.lang.VerifyError: (class: TestThrow, method: ma\
in signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestThrow.  Program will exit.

UPDATE 2:

Actually, you can get this to work if you disable the byte code verifier! (-Xverify:none)

UPDATE 3:

For those following from home, here is the full script:

Create the following classes:

public class ChuckNorrisException
    extends RuntimeException // <- Comment out this line on second compilation
{
    public ChuckNorrisException() { }
}

public class TestVillain {
    public static void main(String[] args) {
        try {
            throw new ChuckNorrisException();
        }
        catch(Throwable t) {
            System.out.println("Gotcha!");
        }
        finally {
            System.out.println("The end.");
        }
    }
}

Compile classes:

javac -cp . TestVillain.java ChuckNorrisException.java

Run:

java -cp . TestVillain
Gotcha!
The end.

Comment out "extends RuntimeException" and recompile ChuckNorrisException.java only :

javac -cp . ChuckNorrisException.java

Run:

java -cp . TestVillain
Exception in thread "main" java.lang.VerifyError: (class: TestVillain, method: main signature: ([Ljava/lang/String;)V) Can only throw Throwable objects
Could not find the main class: TestVillain.  Program will exit.

Run without verification:

java -Xverify:none -cp . TestVillain
The end.
Exception in thread "main"

Solution 2 - Java

After having pondered this, I have successfully created an uncatchable exception. I chose to name it JulesWinnfield, however, rather than Chuck, because it is one mushroom-cloud-laying-mother-exception. Furthermore, it might not be exactly what you had in mind, but it certainly can't be caught. Observe:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield()
    {
        System.err.println("Say 'What' again! I dare you! I double dare you!");
        System.exit(25-17); // And you shall know I am the LORD
    }
}
    
    
public static void main(String[] args)
{       
    try
    {
        throw new JulesWinnfield();
    } 
    catch(JulesWinnfield jw)
    {
        System.out.println("There's a word for that Jules - a bum");
    }
}

Et voila! Uncaught exception.

Output:

> run: > > Say 'What' again! I dare you! I double dare you! > >Java Result: 8 > > BUILD SUCCESSFUL (total time: 0 seconds)

When I have a little more time, I'll see if I can't come up with something else, as well.

Also, check this out:

public static class JulesWinnfield extends Exception
{
    JulesWinnfield() throws JulesWinnfield, VincentVega
    {
        throw new VincentVega();
    }
}

public static class VincentVega extends Exception
{
    VincentVega() throws JulesWinnfield, VincentVega
    {
        throw new JulesWinnfield();
    }
}


public static void main(String[] args) throws VincentVega
{
    
    try
    {
        throw new JulesWinnfield();
    }
    catch(JulesWinnfield jw)
    {
        
    }
    catch(VincentVega vv)
    {
        
    }
}

Causes a stack overflow - again, exceptions remain uncaught.

Solution 3 - Java

With such an exception it would obviously be mandatory to use a System.exit(Integer.MIN_VALUE); from the constructor because this is what would happen if you threw such an exception ;)

Solution 4 - Java

Any code can catch Throwable. So no, whatever exception you create is going to be a subclass of Throwable and will be subject to being caught.

Solution 5 - Java

public class ChuckNorrisException extends Exception {
    public ChuckNorrisException() {
        System.exit(1);
    }
}

(Granted, technically this exception is never actually thrown, but a proper ChuckNorrisException can't be thrown -- it throws you first.)

Solution 6 - Java

Any exception you throw has to extend Throwable, so it can be always caught. So answer is no.

If you want to make it difficult to handle, you can override methods getCause(), getMessage(), getStackTrace(), toString() to throw another java.lang.ChuckNorrisException.

Solution 7 - Java

My answer is based on @jtahlborn's idea, but it's a fully working Java program, that can be packaged into a JAR file and even deployed to your favorite application server as a part of a web application.

First of all, let's define ChuckNorrisException class so that it doesn't crash JVM from the beginning (Chuck really loves crashing JVMs BTW :)

package chuck;

import java.io.PrintStream;
import java.io.PrintWriter;

public class ChuckNorrisException extends Exception {

    public ChuckNorrisException() {
    }

    @Override
    public Throwable getCause() {
        return null;
    }

    @Override
    public String getMessage() {
        return toString();
    }

    @Override
    public void printStackTrace(PrintWriter s) {
        super.printStackTrace(s);
    }

    @Override
    public void printStackTrace(PrintStream s) {
        super.printStackTrace(s);
    }
}

Now goes Expendables class to construct it:

package chuck;

import javassist.*;

public class Expendables {

    private static Class clz;

    public static ChuckNorrisException getChuck() {
        try {
            if (clz == null) {
                ClassPool pool = ClassPool.getDefault();
                CtClass cc = pool.get("chuck.ChuckNorrisException");
                cc.setSuperclass(pool.get("java.lang.Object"));
                clz = cc.toClass();
            }
            return (ChuckNorrisException)clz.newInstance();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}

And finally the Main class to kick some butt:

package chuck;

public class Main {

    public void roundhouseKick() throws Exception {
        throw Expendables.getChuck();
    }

    public void foo() {
        try {
            roundhouseKick();
        } catch (Throwable ex) {
            System.out.println("Caught " + ex.toString());
        }
    }

    public static void main(String[] args) {
        try {
            System.out.println("before");
            new Main().foo();
            System.out.println("after");
        } finally {
            System.out.println("finally");
        }
    }
}

Compile and run it with following command:

java -Xverify:none -cp .:<path_to_javassist-3.9.0.GA.jar> chuck.Main

You will get following output:

before
finally

No surprise - it's a roundhouse kick after all :)

Solution 8 - Java

In the constructor you could start a thread which repeatedly calls originalThread.stop (ChuckNorisException.this)

The thread could catch the exception repeatedly but would keep throwing it until it dies.

Solution 9 - Java

No. All exceptions in Java must subclass java.lang.Throwable, and although it may not be good practice, you can catch every type of exception like so:

try {
    //Stuff
} catch ( Throwable T ){
    //Doesn't matter what it was, I caught it.
}

See the [java.lang.Throwable][1] documentation for more information.

If you're trying to avoid [checked exceptions][2] (ones that must be explicitly handled) then you will want to subclass Error, or RuntimeException.

[1]: http://docs.oracle.com/javase/7/docs/api/java/lang/Throwable.html "Throwable" [2]: http://en.wikipedia.org/wiki/Exception_handling#Checked_exceptions

Solution 10 - Java

Actually the accepted answer is not so nice because Java needs to be run without verification, i.e. the code would not work under normal circumstances.

AspectJ to the rescue for the real solution!

Exception class:

package de.scrum_master.app;

public class ChuckNorrisException extends RuntimeException {
	public ChuckNorrisException(String message) {
		super(message);
	}
}

Aspect:

package de.scrum_master.aspect;

import de.scrum_master.app.ChuckNorrisException;

public aspect ChuckNorrisAspect {
	before(ChuckNorrisException chuck) : handler(*) && args(chuck) {
		System.out.println("Somebody is trying to catch Chuck Norris - LOL!");
		throw chuck;
	}
}

Sample application:

package de.scrum_master.app;

public class Application {
	public static void main(String[] args) {
		catchAllMethod();
	}

	private static void catchAllMethod() {
		try {
			exceptionThrowingMethod();
		}
		catch (Throwable t) {
			System.out.println("Gotcha, " + t.getClass().getSimpleName() + "!");
		}
	}

	private static void exceptionThrowingMethod() {
		throw new ChuckNorrisException("Catch me if you can!");
	}
}

Output:

Somebody is trying to catch Chuck Norris - LOL!
Exception in thread "main" de.scrum_master.app.ChuckNorrisException: Catch me if you can!
    at de.scrum_master.app.Application.exceptionThrowingMethod(Application.java:18)
    at de.scrum_master.app.Application.catchAllMethod(Application.java:10)
    at de.scrum_master.app.Application.main(Application.java:5)

Solution 11 - Java

A variant on the theme is the surprising fact that you can throw undeclared checked exceptions from Java code. Since it is not declared in the methods signature, the compiler won't let you catch the exception itself, though you can catch it as java.lang.Exception.

Here's a helper class that lets you throw anything, declared or not:

public class SneakyThrow {
  public static RuntimeException sneak(Throwable t) {
    throw SneakyThrow.<RuntimeException> throwGivenThrowable(t);
  }
 
  private static <T extends Throwable> RuntimeException throwGivenThrowable(Throwable t) throws T {
    throw (T) t;
  }
}

Now throw SneakyThrow.sneak(new ChuckNorrisException()); does throw a ChuckNorrisException, but the compiler complains in

try {
  throw SneakyThrow.sneak(new ChuckNorrisException());
} catch (ChuckNorrisException e) {
}

about catching an exception that is not thrown if ChuckNorrisException is a checked exception.

Solution 12 - Java

The only ChuckNorrisExceptions in Java should be OutOfMemoryError and StackOverflowError.

You can actually "catch" them in the means that a catch(OutOfMemoryError ex) will execute in case the exception is thrown, but that block will automatically rethrow the exception to the caller.

I don't think that public class ChuckNorrisError extends Error does the trick but you could give it a try. I found no documentation about extending Error

Solution 13 - Java

Is it possible to construct a snippet of code in java that would make a hypothetical java.lang.ChuckNorrisException uncatchable?

Yes, and here's the answer: Design your java.lang.ChuckNorrisException such that it is not an instance of java.lang.Throwable. Why? An unthrowable object is uncatchable by definition because you can never catch something that can never be thrown.

Solution 14 - Java

You can keep ChuckNorris internal or private and encapsulate him or swollow him...

try { doChuckAction(); } catch(ChuckNorrisException cne) { /*do something else*/ }

Solution 15 - Java

Two fundamental problems with exception handling in Java are that it uses the type of an exception to indicate whether action should be taken based upon it, and that anything which takes action based upon an exception (i.e. "catch"es it) is presumed to resolve the underlying condition. It would be useful to have a means by which an exception object could decide which handlers should execute, and whether the handlers that have executed so far have cleaned things up enough for the present method to satisfy its exit conditions. While this could be used to make "uncatchable" exceptions, two bigger uses would be to (1) make exceptions which will only be considered handled when they're caught by code that actually knows how to deal with them, and (2) allow for sensible handling of exceptions which occur in a finally block (if a FooException during a finally block during the unwinding of a BarException, both exceptions should propagate up the call stack; both should be catchable, but unwinding should continue until both have been caught). Unfortunately, I don't think there would be any way to make existing exception-handling code work that way without breaking things.

Solution 16 - Java

It is easily possible to simulate a uncaught exception on the current thread. This will trigger the regular behavior of an uncaught exception, and thus gets the job done semantically. It will, however, not necessarily stop the current thread's execution, as no exception is actually thrown.

Throwable exception = /* ... */;
Thread currentThread = Thread.currentThread();
Thread.UncaughtExceptionHandler uncaughtExceptionHandler =
    currentThread.getUncaughtExceptionHandler();
uncaughtExceptionHandler.uncaughtException(currentThread, exception);
// May be reachable, depending on the uncaught exception handler.

This is actually useful in (very rare) situations, for example when proper Error handling is required, but the method is invoked from a framework catching (and discarding) any Throwable.

Solution 17 - Java

Call System.exit(1) in the finalize, and just throw a copy of the exception from all the other methods, so that the program will exit.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMax CharasView Question on Stackoverflow
Solution 1 - JavajtahlbornView Answer on Stackoverflow
Solution 2 - JavaMike GView Answer on Stackoverflow
Solution 3 - JavaKorgenView Answer on Stackoverflow
Solution 4 - Javaпутин некультурная свиньяView Answer on Stackoverflow
Solution 5 - JavafluffyView Answer on Stackoverflow
Solution 6 - JavamirelonView Answer on Stackoverflow
Solution 7 - JavaWildfireView Answer on Stackoverflow
Solution 8 - JavaPeter LawreyView Answer on Stackoverflow
Solution 9 - JavaVolatileDreamView Answer on Stackoverflow
Solution 10 - JavakriegaexView Answer on Stackoverflow
Solution 11 - JavaHans-Peter StörrView Answer on Stackoverflow
Solution 12 - Javausr-local-ΕΨΗΕΛΩΝView Answer on Stackoverflow
Solution 13 - JavaThomas EdingView Answer on Stackoverflow
Solution 14 - JavaJayView Answer on Stackoverflow
Solution 15 - JavasupercatView Answer on Stackoverflow
Solution 16 - JavadstView Answer on Stackoverflow
Solution 17 - JavaDemiView Answer on Stackoverflow