Throwing an exception from an abstract Runnable.run() in Java - java

I've made an abstract Thread that processes some streams in its run() method. I'd like to be able to have the subclasses handle these exceptions rather than the abstract parent class, but I don't know the most elegant way to do that. Right now, I'm doing something like this:
import org.apache.logging.log4j; // (I use log4j for logging)
public interface Loggable {
Logger getLogger();
}
public abstract class ParentThread extends Thread implements Loggable {
private final static Logger logger =
Logger.getLogger(ParentThread.class); // Logger with no Appenders
#Override
public void run() {
try {
// Do some stuff that throws exceptions
doAbstractStuff();
} catch (SomeSortOfException ex) {
getLogger().error("Oh noes!", ex);
} catch (SomeOtherException ex) {
getLogger().error("The sky is falling!", ex);
}
}
public Logger getLogger() { return logger; }
protected abstract void doAbstractStuff();
}
public class ChildThread extends ParentThread {
#Override
public Logger getLogger() { /* return a logger that I actually use */ }
#Override
public void doAbstractStuff() { /* Implementation */ }
}
I guess I should mention that the ChildThread is actually an inner class of my main form, and that its logger belongs to that form.
Another approach I thought of was to have an
abstract void handleException(Exception ex);
in ParentThread, but then I'm not able to handle individual exceptions from the ChildThread.

Your first solution seems conceptually wrong to me: mixing application-specific error-handling with generic logging.
Your second idea (the callback) seems a better solution and offers the possibility of abstracting away the implementation-specific exceptions for custom events, for example:
public abstract class Parent {
public void run() {
InputStream in = null;
try {
in = new URL("bladiebla").openConnection().getInputStream();
String text = // ...read text from InputStream
if (text == null || text.length() == 0) {
handleMyEvent(new NoInputEvent());
return;
}
doWork(text);
} catch (MalformedURLException e) {
handleMyEvent(new MyEvent(e));
} catch (IOException e) {
handleMyEvent(new MyEvent(e));
}
finally {
if (in != null) {
try {
in.close();
}
catch(IOException e) {
handleMyEvent(e);
}
}
}
}
abstract void doWork(String text);
abstract void handleMyEvent(MyEvent myEvent);
}
public class MyEvent {
private Exception exception;
public MyEvent() {}
public MyEvent(Exception exception) {//set it}
}
public class NoInputEvent extends MyEvent {
}

Well there's no difference between
} catch (SomeSortOfException ex) {
getLogger().error("Oh noes!", ex);
} catch (SomeOtherException ex) {
getLogger().error("The sky is falling!", ex);
}
and
if (ex instanceof SomeSortOfException) {
getLogger().error("Oh noes!", ex);
} else if (ex instanceof SomeOtherException) {
getLogger().error("The sky is falling!", ex);
}
although the latter may require some casting.
Your abstract handleException(Exception ex) idea is sound, I'd go with that. I'd be inclined to not make it abstract, though, and define a sensible default implementation in ParentThread, and allow ChildThread to override it if required.

Why is your base class logging exceptions ? Why not use what the platform provide Thread.setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) and let it do whatever instead of mixing logging w/ your do-stuff component.

Related

Throwing exception without " throws " for any type of exception

I want to throw an exception (any type) in Java, but the restriction is that i can't add " throws Exception " to my main method. So i tried this:
import java.io.IOException;
class Util
{
#SuppressWarnings("unchecked")
private static <T extends Throwable> void throwException(Throwable exception, Object dummy) throws T
{
throw (T) exception;
}
public static void throwException(Throwable exception)
{
Util.<RuntimeException>throwException(exception, null);
}
}
public class Test
{
public static void met() {
Util.throwException(new IOException("This is an exception!"));
}
public static void main(String[] args)
{
System.out.println("->main");
try {
Test.met();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
This code works, but when i am trying to catch an "IOException", for examle, in try-catch block, it doesnt compile. The compiler tells me that IOException is never thrown. It works only for exceptions that extend RuntimeException. Is there a way to solve this?
Added:
import java.io.IOException;
class Util
{
#SuppressWarnings("unchecked")
private static <T extends Throwable> void throwException(Throwable exception, Object dummy) throws T
{
throw (T) exception;
}
public static void throwException(Throwable exception)
{
Util.<RuntimeException>throwException(exception, null);
}
}
public class Test
{
public static void met() { // this method's signature can't be changed
Util.throwException(new IOException("This is an exception!"));
}
public static void main(String[] args)
{
System.out.println("->main");
try {
Test.met();
} catch (IOException e) { // can't be changed and it does not compile right now
System.out.println(e.getMessage());
}
}
}
The simple answer: you can't.
The more complex answer: you can't, and you really shouldn't look to do this. The main reason being, if your code can catch exceptions that it's not advertised to, then that leads to inconsistency and bugs.
Above all, that code block isn't meant to catch anything other than an IOException; that is, the code is only meant to recover on something going haywire with IO. If I were to try and catch anything else, then that would imply that the code knows how to recover from that scenario, which is very much not the case.
As an aside, any children of IOException will be caught by that block, so you don't have to worry about catching FileNotFoundExecption, since that will handle it.
This is awful coding, and I feel dirty just writing it...
Instead of catch-ing the IOException directly, you can check that the caught Exception is an IOException.
public class Test
{
public static void main(String[] args)
{
System.out.println("->main");
try {
Test.met();
} catch (Exception e) {
if (e instanceof IOException) {
System.out.println(e.getMessage());
}
}
}
}

Helper to call close() if implements AutoCloseable?

Is there any helper method in the JDK or common libraries that does this:
if (resource instanceof AutoCloseable) {
((AutoCloseable) resource).close();
}
Just a one-liner to call an object's close() if applicable.
I know about try-with-resources, that's not applicable to this situation. And I know that not all classes that have a close() method implement AutoCloseable. But, I seem to write the above over and over..
There's something Apache Commons offers:
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html#closeQuietly(java.io.Closeable)
Here is apache commons closeQuietly adapted for AutoCloseable:
static void closeQuietly(AutoCloseable closeable) {
try {
if (closeable != null) {
closeable.close();
}
}
catch (Exception swallowed) {
}
}
since google sent me here for that case :)
Edit:
Check this:
class CloserHelper
{
public static void close(Object object)
{
if (object instanceof AutoCloseable)
{
try
{
((AutoCloseable) object).close();
}
catch (Exception ignored) { }
}
}
}
I can think to something like this
class CloserHelper
{
public static void close(AutoCloseable obj) throws Exception
{
obj.close();
}
}
Then
CloserHelper.close(resource);
If the object is not a AutoCloseable you cannot just call it
If you want to ignore exceptions
class CloserHelper
{
public static void close(AutoCloseable obj)
{
try
{
obj.close();
}
catch (Exception e) { }
}
}

Java generic interfaces

I have generic class type, T as follow:
class MyClass<T>
Also I know that T is interface with only one method inside but I don't know what interface, I can't write this:
class MyClass< T extends TheInterface >
So is there a way to invoke this method?
public void callMe(T me, Object...params){
// How can I invoke T interface method?
}
I been trying this:
public void callMe(T me, Object... params) {
// methods.length is 244, just as in my activity class
Method[] methods = me.getClass().getMethods();
try {
methods[0].invoke(me, params);
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
} catch (InvocationTargetException e) {
e.printStackTrace();
return;
}
}
But it's not working
Edit: I posted new question that explain why I need this for
Yes, you have to write:
class MyClass< T extends TheInterface >
With this information, the compiler know that T have an operation named callMe
I'm not sure, are you looking for the Strategy pattern?
If you can not change declaration inside MyClass then you can just typecast it.
public void callMe(T me, Object... params) {
Someinterface instance = (Someinterface) me;
list.callMe(me, params);
}
But still declaring it like below should be the best solution
class MyClass<T extends Someinterface >
Below is the simple demonstration of how to do it using reflection
class MyClass<T> {
public void callMe(T me, Object... params) throws SecurityException,
NoSuchMethodException {
// How can I invoke T interface method?
Method size = me.getClass().getMethod("size", null);
Method add = me.getClass().getMethod("add", Object.class);
try {
add.invoke(me, 10);
System.out.println(size.invoke(me, params));
} catch (IllegalArgumentException e) {
e.printStackTrace();
return;
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
} catch (InvocationTargetException e) {
e.printStackTrace();
return;
}
}
}
MyClass<List> myclass = new MyClass<List>();
myclass.callMe(new ArrayList(), null);
Output :
1

Access Try-Catch block's code in another class

May be it could be silly,but I want to clear my the technical understanding of this code:
import netscape.*;//ldap jar
public class A {
public void method() {
...
try {
//code is written here.
LDAPSearchResults lsr = ldi.search(LDAPConnectionInfo.MY_SEARCHBASE,LDAPConnectionInfo.MY_SCOPE,LDAPConnectionInfo.MY_FILTER,null,false);
while(lsr.hasMoreElements()){
LDAPEntry findEntry = (LDAPEntry)lsr.nextElement();
} catch(...) {
}
}
}
Now I call another class
public class B {
A a = new A();
//here I want to use attributeName
}
How could I access A class's member(in try block) in B class.
Any way to handle try block code for reuse in another class.
How could I handle all those exception in another class.
Any modification should I need...
Calling method of Object type.
public class C{
private String attributeName;
public String getAttributeName() {
return attributeName;
}
public Object method(){
attributeName=lAttribute.getName();
}
}
How could print this Object type method into String(in a jsp page)... any inputs
You'll need a member in class A and a getter:
public class A {
private String attributeName;
public String getAttributeName() {
return attributeName;
}
public void method(){
...
try {
//code is written here.
attributeName = lAttribute.getName();
}
catch() {
}
}
}
Then:
public class B {
A a = new A();
// somewhere
String str = a.getAttributeName();
}
There's no way to access a method's private variables like you did in the original example, as they only exist on the stack during the method call.
Edit: I noticed another question:
How could I handle all those exception in another class.
I assume you want to call your method somewhere else and catch the exceptions there. In that case you can use the throws keyword to communicate that your method will pass exceptions to the caller:
public class A {
public void method() throws IOException {
//code is written here.
String attributeName = lAttribute.getName();
}
public void anotherMethod() {
try {
method();
} catch(IOException ex) {
...
}
}
}
then if some other piece of code calls method it will be forced to either handle or further propagate the exception.
How could I handle all those exception in another class.
In your calling class you can catch Throwable (which will catch all exceptions and errors)
try {
....
}
catch (Throwable t) {
//do something with the throwable.
}
if you do not want to catch Errors (Ive only done this when messing around with ImageIO and had memory problems) in Java then catch Exception instead
Any way to handle try block code for reuse in another class
here you could create a method in another class and then call it within your try /catch block
public class XYX {
public void methodForTry() throws Exception {
//do something
}
}
try {
new XYZ().methodForTry();
}
catch (Exception e){
}
You may or may not want to create new XYZ here. It depends what state this object may or may not hold.
As to the last questions I think Tudor's answer covers this
Your question may be about extracting the code template
try { ... do stuff ... }
catch (MyFirstException e) { ...handle ... }
catch (MySecondException e) { ...handle ... }
... more catch ...
Where you only want to change the ... do stuff ... part. In that case you'd need closures, which are coming with Java 8, and today you'd need something quite cumbersome, of this sort:
public static void tryCatch(RunnableExc r) {
try { r.run(); }
catch (MyFirstException e) { ...handle ... }
catch (MySecondException e) { ...handle ... }
... more catch ...
}
where RunnableExc would be an
interface RunnableExc { void run() throws Exception; }
and you'd use it this way:
tryCatch(new RunnableExc() { public void run() throws Exception {
... do stuff ...
}});
why not return it?
public String method() {
String attributeName
try {
//code is written here.
attributeName = lAttribute.getName();
} catch(...) {
}
return attributeName;
}
public class B {
A a = new A();
String attributeName = a.method();
}

In Java how can I validate a thrown exception with JUnit?

When writing unit tests for a Java API there may be circumstances where you want to perform more detailed validation of an exception. I.e. more than is offered by the #test annotation offered by JUnit.
For example, consider an class that should catch an exception from some other Interface, wrap that exception and throw the wrapped exception. You may want to verify:
The exact method call that throws the wrapped exception.
That the wrapper exception has the original exception as its cause.
The message of the wrapper exception.
The main point here is that you want to be perf additional validation of an exception in a unit test (not a debate about whether you should verify things like the exception message).
What's a good approach for this?
In JUnit 4 it can be easily done using ExpectedException rule.
Here is example from javadocs:
// These tests all pass.
public static class HasExpectedException {
#Rule
public ExpectedException thrown = ExpectedException.none();
#Test
public void throwsNothing() {
// no exception expected, none thrown: passes.
}
#Test
public void throwsNullPointerException() {
thrown.expect(NullPointerException.class);
throw new NullPointerException();
}
#Test
public void throwsNullPointerExceptionWithMessage() {
thrown.expect(NullPointerException.class);
thrown.expectMessage("happened?");
thrown.expectMessage(startsWith("What"));
throw new NullPointerException("What happened?");
}
}
As provided in your answer, it's a good approach. In addition to this:
You could wrap the function expectException into a new Annotation, called ExpectedException.
An annotated method would look like this:
#Test
#ExpectedException(class=WrapperException.class, message="Exception Message", causeException)
public void testAnExceptionWrappingFunction() {
//whatever you test
}
This way would be more readable, but it's exactly the same approach.
Another reason is: I like Annotations :)
Looking at the proposed answers, you can really feel the pain of not having closures in Java. IMHO, the most readable solution is ye good old try catch.
#Test
public void test() {
...
...
try {
...
fail("No exception caught :(");
}
catch (RuntimeException ex) {
assertEquals(Whatever.class, ex.getCause().getClass());
assertEquals("Message", ex.getMessage());
}
}
For JUNIT 3.x
public void test(){
boolean thrown = false;
try{
mightThrowEx();
} catch ( Surprise expected ){
thrown = true;
assertEquals( "message", expected.getMessage());
}
assertTrue(thrown );
}
Until this post I've done my exception validation by doing this:
try {
myObject.doThings();
fail("Should've thrown SomeException!");
} catch (SomeException e) {
assertEquals("something", e.getSomething());
}
I spent a few moments thinking about the issue though and came up with the following (Java5, JUnit 3.x):
// Functor interface for exception assertion.
public interface AssertionContainer<T extends Throwable> {
void invoke() throws T;
void validate(T throwable);
Class<T> getType();
}
// Actual assertion method.
public <T extends Throwable> void assertThrowsException(AssertionContainer<T> functor) {
try {
functor.invoke();
fail("Should've thrown "+functor.getType()+"!");
} catch (Throwable exc) {
assertSame("Thrown exception was of the wrong type! Expected "+functor.getClass()+", actual "+exc.getType(),
exc.getClass(), functor.getType());
functor.validate((T) exc);
}
}
// Example implementation for servlet I used to actually test this. It was an inner class, actually.
AssertionContainer<ServletException> functor = new AssertionContainer<ServletException>() {
public void invoke() throws ServletException {
servlet.getRequiredParameter(request, "some_param");
}
public void validate(ServletException e) {
assertEquals("Parameter \"some_param\" wasn't found!", e.getMessage());
}
public Class<ServletException> getType() {
return ServletException.class;
}
}
// And this is how it's used.
assertThrowsException(functor);
Looking at these two I can't decide which one I like more. I guess this is one of those issues where achieving a goal (in my case, the assertion method with functor parameter) isn't worth it in the long run since it's just a lot easier to do those 6+ of code to assert the try..catch block.
Then again, maybe my 10 minute result of problem solving at friday evening just isn't the most intelligent way to do this.
#akuhn:
Even without closures we can get a more readable solution (using catch-exception):
import static com.googlecode.catchexception.CatchException.*;
public void test() {
...
...
catchException(nastyBoy).doNastyStuff();
assertTrue(caughtException() instanceof WhateverException);
assertEquals("Message", caughtException().getMessage());
}
The following helper method (adapted from this blog post) does the trick:
/**
* Run a test body expecting an exception of the
* given class and with the given message.
*
* #param test To be executed and is expected to throw the exception.
* #param expectedException The type of the expected exception.
* #param expectedMessage If not null, should be the message of the expected exception.
* #param expectedCause If not null, should be the same as the cause of the received exception.
*/
public static void expectException(
Runnable test,
Class<? extends Throwable> expectedException,
String expectedMessage,
Throwable expectedCause) {
try {
test.run();
}
catch (Exception ex) {
assertSame(expectedException, ex.getClass());
if (expectedMessage != null) {
assertEquals(expectedMessage, ex.getMessage());
}
if (expectedCause != null) {
assertSame(expectedCause, ex.getCause());
}
return;
}
fail("Didn't find expected exception of type " + expectedException.getName());
}
The test code can then invoke this as follows:
TestHelper.expectException(
new Runnable() {
public void run() {
classInstanceBeingTested.methodThatThrows();
}
},
WrapperException.class,
"Exception Message",
causeException
);
i did something very simple
testBla(){
try {
someFailingMethod()
fail(); //method provided by junit
} catch(Exception e) {
//do nothing
}
}
For JUnit 5 it is much easier:
#Test
void testAppleIsSweetAndRed() throws Exception {
IllegalArgumentException ex = assertThrows(
IllegalArgumentException.class,
() -> testClass.appleIsSweetAndRed("orange", "red", "sweet"));
assertEquals("this is the exception message", ex.getMessage());
assertEquals(NullPointerException.class, ex.getCause().getClass());
}
By returning the exception object itself, assertThrows() allows you to test every aspect regarding your thrown exceptions.
I made a helper similar to the other posted ones:
public class ExpectExceptionsExecutor {
private ExpectExceptionsExecutor() {
}
public static void execute(ExpectExceptionsTemplate e) {
Class<? extends Throwable> aClass = e.getExpectedException();
try {
Method method = ExpectExceptionsTemplate.class.getMethod("doInttemplate");
method.invoke(e);
} catch (NoSuchMethodException e1) {
throw new RuntimeException();
} catch (InvocationTargetException e1) {
Throwable throwable = e1.getTargetException();
if (!aClass.isAssignableFrom(throwable.getClass())) {
// assert false
fail("Exception isn't the one expected");
} else {
assertTrue("Exception captured ", true);
return;
}
;
} catch (IllegalAccessException e1) {
throw new RuntimeException();
}
fail("No exception has been thrown");
}
}
And the template the client should implement
public interface ExpectExceptionsTemplate<T extends Throwable> {
/**
* Specify the type of exception that doInttemplate is expected to throw
* #return
*/
Class<T> getExpectedException();
/**
* Execute risky code inside this method
* TODO specify expected exception using an annotation
*/
public void doInttemplate();
}
And the client code would be something like this:
#Test
public void myTest() throws Exception {
ExpectExceptionsExecutor.execute(new ExpectExceptionsTemplate() {
#Override
public Class getExpectedException() {
return IllegalArgumentException.class;
}
#Override
public void doInttemplate() {
riskyMethod.doSomething(null);
}
});
}
It looks really verbose but if you use an IDE with good autocompletion you will only need to write the type of exception and the actual code under test. (the rest will be done by the IDE :D)

Categories