Im' trying to write a class BrokenObjectException class derivated from Exception.
But in Eclipse I get this error:
The serializable class BrokenObjectException does not declare a static final serialVersionUID field of type long
public class BrokenObjectException extends Exception
{
BrokenObject(String message)
{
;
}
}
I have not understood why it asks me to declare a field.
Shouldn't interface just force to declare some methods?
Anyway I want to have this class because I want to catch it n a different way from how I catch all exceptions, from I example I have a block:
try
{
if(...)
throw new Exception("wrong");
if(...)
throw new BrokenObjectException("wrong");
}
catch(BrokenObjectException e)
{
// do something (action1)
throw e;
}
catch(Exception e)
{
// so something (action2)
throw e;
}
So in the first catch block I have written "do something".
This because depending on the type of exception thrown I want to do different actions.
So since BrokenObjectException is derivated from Exception it shall be catched two times.
But if a BrokenObjectException is thrown, I want to do action1 and action2, if just a normal Exception is thrown I want just to do action2.Is that possible?
And how to fix the error I'm getting?
That's not an error but rather just a warning. Simply use the #SuppressWarnings("serial") annotation just above the class declaration:
#SuppressWarnings("serial")
public class BrokenObjectException extends Exception
{
BrokenObject(String message)
{
;
}
}
What is happening is you are extending a class that implements the Serializable interface and so the compiler will warn you if you do not fully comply with its contract. To get around this (since I doubt that you'll want to serialize objects of this class), simply use the annotation above.
I believe that you can just highlight over the error text that eclipse gives you and then tell it to generate the serial version UUID. After that, it should work just how you want it to.
Also you can use the
#SuppressWarnings("serial")
if you want to just ignore it. However, I would recommend going ahead and generating it. For more info on why check out this stack overflow post.
What is a serialVersionUID and why should I use it?
Are you aware why is that serialVersionUID field needed? Is that what you are asking for? if so please look at the following link
Related
I am writing a program that consumes some data from a RabbitMQ API, via the java.function.Consumer functional interface. In my subclass that implements this interface, I have 3 potential exceptions:
public interface MyMessageHandler extends Consumer<MyMessage> {}
public class SpecificMessageHandler implements MyMessageHandler {
#Override
public void accept(IncomingMessage incomingMessage) {
if(incomingMessage.getTime() < 1000) {
throw new InvalidTimeException("message"); //Custom exception extends RuntimeException
}
if(incomingMessageAlreadyExists) {
throw new DuplicateMessageException("message"); //Custom exception extends RuntimeException
}
try {
ObjectMapper.reader.readValue(incomingMessage.getJson()) // Throws IOEXception
} catch(IOException e) {
throw new CustomIOException("message"); //Custom exceptin extends RuntimeException
}
// If all is well, carry on with rest of function
}
}
I am having to take this route because you can't seem to throw regular exceptions in a functional interface, it has to be a runtime exception.
I am throwing the exceptions at this level of the stack, as I want to implement the actual handling behaviour higher up the stack, due to the fact I will have many message handlers that will be handled in the same way, therefore it's easier to implement that handling behaviour once higher up, rather than in every single handler class.
This functionally works, however feels like bad design. Is there a more elegant way to implement this? Note, I can't switch from a functional interface to something else, as i'm working with legacy code (not ideal, but that's how the world is some times!)
I am having to take this route because you can't seem to throw regular
exceptions in a functional interface, it has to be a runtime
exception.
This is incorrect. You can't throw checked exceptions in a java.function.Consumer specifically, because its signature
void accept(T t);
doesn't declare any.
The following functional interface is perfectly acceptable, and can throw certain checked exceptions.
public interface MyMessageHandler {
void accept(IncomingMessage incomingMessage) throws IOException;
}
MyMessageHandler handler = (msg) -> {
throw new IOException(); // Valid
};
If you wanted something more generic, you could declare something like
public interface ThrowableConsumer<T> {
void accept(T t) throws Exception;
}
interface MyMessageHandler extends ThrowableConsumer<MyMessage> {}
I am throwing the exceptions at this level of the stack, as I want to
implement the actual handling behaviour higher up the stack
You could use Lombok's #SneakyThrows to effectively convert a checked exception into an unchecked one. A hack, but it works.
class SpecificMessageHandler implements MyMessageHandler {
#Override
#SneakyThrows
public void accept(IncomingMessage incomingMessage) {
// Doesn't matter that it's checked and j.f.Consumer doesn't declare it
throw new IOException();
}
}
However I highly doubt that your employer will allow you to do hacks like this if you're not permitted to change an interface.
This functionally works, however feels like bad design
Why? There's a huge class of people who believe that checked exceptions were a mistake to begin with. There's nothing wrong with runtime exceptions.
Note, I can't switch from a functional interface to something else, as
i'm working with legacy code
People throw this word around a lot. Java 8 came out 8 years ago. Your code can't be that old. Usually when people say "I can't change X", what they mean is that they don't feel comfortable changing it, for whatever reason. If you're living in fear of your software, find a way to change that.
The following text is from "Effective Java", Item 2:
The traditional Abstract Factory implementation in Java has been the
Class object, with the newInstance method playing the part of the
build method. This usage is fraught with problems. The newInstance
method always attempts to invoke the class’s parameterless
constructor, which may not even exist. You don’t get a compile-time
error if the class has no accessible parameterless constructor.
Instead, the client code must cope with InstantiationException or
IllegalAccessException at runtime, which is ugly and inconvenient.
Also, the newInstance method propagates any exceptions thrown by the
parameterless constructor, even though newInstance lacks the
corresponding throws clauses. In other words, Class.newInstance breaks
compile-time exception checking. The Builder interface, shown above,
corrects these deficiencies.
Please go to this link for full text.
I've been able to follow everything before, "In other words..". Can someone please explain how does newInstance break compile-time exception checking and how does Builder pattern fixes it.
'newInstance' doesn't know ahead of time (at compile time) what exceptions could be thrown, as a normal class method would (because of the way code dependencies are built, and because a class has to make known which exceptions it throws).
The Builder pattern uses a class that takes a request (usually via a method) and creates a new object instance based on steps (most likely defined in that class).
Conceptually a non-abstract factory, and builder are very similar.
public class Main {
private int i;
public Main() throws IOException {
throw new IOException();
}
public static void main(String[] args) {
Class c = Main.class;
try {
c.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
In my opinion, if we use class.newInstance() method, we will never know the exactly exception will be thrown by the construction even though the exception is a checked exception and the checked exception isn't shown at the method signature. Just like the example above. If we use class.newInstance(), we will forget to handle the IOException and then get a "broken object". But the Builder pattern won't. Sorry for my pool english and hope you can understand.
This is a simplified class that describes my problem:
public class Main {
enum Test{
First(method()){ // Unhandled exception type Exception
// ...
};
Test(Object obj){
//...
}
}
static Object method() throws Exception{
// ...
if (someCondition){
throw new Exception();
}
}
}
Above someCondition depends on device and some situations and I can not decide in about it now, also as you can see, I do not want to catch Exception in method.
Yes. It is a compilation error.
No. There is no special syntax to deal with this.
I do not want to catch Exception in method.
Unfortunately if you throw a checked exception, it has to be caught further up the call stack. That is a fundamental design principal for the Java language, and one that the compiler enforces strictly.
In this, case there is no way to catch the checked exception. Hence, if you are going to call a method in enum constant parameter (as per your code), the method cannot throw a checked exception1.
Here is a possible workaround, though this is probably a bad idea:
public class Main {
enum Test{
First(methodCatchingException()){
// ...
};
Test(Object obj){
//...
}
}
static Object method() throws Exception{
// ...
if (someCondition){
throw new Exception();
}
}
static Object methodCatchingException() {
try {
return method();
} catch (Exception ex) {
throw new SomeRuntimeException("the sky is falling!", ex);
}
}
}
Another way to look at this problem is to ask yourself what should happen with the exception if the compiler let you write that ... and an exception was thrown? Where would it go?
You can't catch it ... because the enum initialization is like a static initialization.
If the Java runtime completely ignored the thrown exception, that would be really bad.
If the Java runtime crashed, then the model of checked exceptions is broken.
So, what this is saying to me is that the Java language design is right, the Java compiler is right ... and the real problem here is in your application design:
You should not be propagating a checked exception here. If an exception occurs in this context it is categorically NOT a recoverable error.
Maybe it is inadvisable to use an enum for this ... because of the potential for non-recoverable initialization errors.
(Note that if this method call terminates due to an unchecked exception, it will turn it into an ExceptionInInitializerError. In addition, the JVM will mark the enum class as uninitializable, and will throw an NoClassDefFoundError if your application attempts to use it; e.g. via Class.forName(...).)
I assume that Exception is used here for illustration purposes. It is a bad thing to declare methods as throws Exception or to throw new Exception(...)
1 - I had a look at the JLS for something to back this up. As far as I can tell, the spec does not mention this situation. I'd have expected to see it listed in JLS 11.2.3. However, it is clear that a compiler cannot allow a checked exception to propagate at that point as it would "break" the model of how checked exceptions work.
I don't think you want to be throwing a checked exception here (which is what Exception is). The reason: you're invoking the call of method inside of the constructor of Test. There's really not a clean way to deal with it.
While the obvious choice here is to switch to RuntimeException, I want you to reconsider throwing the exception in the first place. Since your enum will only ever have First declared in it, does it really make sense for it to throw an exception when it's being instantiated? Personally, I don't think it does; whatever dangerous operation it's doing should be deferred until you want to invoke it, and then would you want to throw your exception.
A method I am calling in run() in a class that implements Runnable) is designed to be throwing an exception.
But the Java compiler won't let me do that and suggests that I surround it with try/catch.
The problem is that by surrounding it with a try/catch I make that particular run() useless. I do want to throw that exception.
If I specify throws for run() itself, the compiler complains that Exception is not compatible with throws clause in Runnable.run().
Ordinarily I'm totally fine with not letting run() throw an exception. But I have unique situation in which I must have that functionality.
How to I work around this limitation?
You can use a Callable instead, submitting it to an ExecutorService and waiting for result with FutureTask.isDone() returned by the ExecutorService.submit().
When isDone() returns true you call FutureTask.get(). Now, if your Callable has thrown an Exception then FutureTask.get() wiill throw an Exception too and the original Exception you will be able to access using Exception.getCause().
If you want to pass a class that implements Runnable into the Thread framework, then you have to play by that framework's rules, see Ernest Friedman-Hill's answer why doing it otherwise is a bad idea.
I have a hunch, though, that you want to call run method directly in your code, so your calling code can process the exception.
The answer to this problem is easy. Do not use Runnable interface from Thread library, but instead create your own interface with the modified signature that allows checked exception to be thrown, e.g.
public interface MyRunnable
{
void myRun ( ) throws MyException;
}
You may even create an adapter that converts this interface to real Runnable ( by handling checked exception ) suitable for use in Thread framework.
If run() threw a checked exception, what would catch it? There's no way for you to enclose that run() call in a handler, since you don't write the code that invokes it.
You can catch your checked exception in the run() method, and throw an unchekced exception (i.e., RuntimeException) in its place. This will terminate the thread with a stack trace; perhaps that's what you're after.
If instead you want your run() method to report the error somewhere, then you can just provide a callback method for the run() method's catch block to call; that method could store the exception object somewhere, and then your interested thread could find the object in that location.
Yes, there is a way to throw a checked exception from the run() method, but it's so terrible I won't share it.
Here's what you can do instead; it uses the same mechanism that a runtime exception would exercise:
#Override
public void run() {
try {
/* Do your thing. */
...
} catch (Exception ex) {
Thread t = Thread.currentThread();
t.getUncaughtExceptionHandler().uncaughtException(t, ex);
}
}
As others have noted, if your run() method is really the target of a Thread, there's no point in throwing an exception because it is unobservable; throwing an exception has the same effect as not throwing an exception (none).
If it's not a Thread target, don't use Runnable. For example, perhaps Callable is a better fit.
#FunctionalInterface
public interface CheckedRunnable<E extends Exception> extends Runnable {
#Override
default void run() throws RuntimeException {
try {
runThrows();
}
catch (Exception ex) {
throw new RuntimeException(ex);
}
}
void runThrows() throws E;
}
Some people try to convince you that you have to play by the rules. Listen, but whether you obey, you should decide yourself depending on your situation. The reality is "you SHOULD play by the rules" (not "you MUST play by the rules"). Just be aware that if you do not play by the rules, there might be consequences.
The situation not only applies in the situation of Runnable, but with Java 8 also very frequently in the context of Streams and other places where functional interfaces have been introduced without the possibility to deal with checked exceptions. For example, Consumer, Supplier, Function, BiFunction and so on have all been declared without facilities to deal with checked exceptions.
So what are the situations and options?
In the below text, Runnable is representative of any functional interface that doesn't declare exceptions, or declares exceptions too limited for the use case at hand.
You've declared Runnable somewhere yourself, and could replace Runnable with something else.
Consider replacing Runnable with Callable<Void>. Basically the same thing, but allowed to throw exceptions; and has to return null in the end, which is a mild annoyance.
Consider replacing Runnable with your own custom #FunctionalInterface that can throw exactly those exceptions that you want.
You've used an API, and alternatives are available. For example, some Java APIs are overloaded so you could use Callable<Void> instead of Runnable.
You've used an API, and there are no alternatives. In that case, you're still not out of options.
You can wrap the exception in RuntimeException.
You can hack the exception into a RuntimeException by using an unchecked cast.
You can try the following. It's a bit of a hack, but sometimes a hack is what we need. Because, whether an exception should be checked or unchecked is defined by its type, but practically should actually be defined by the situation.
#FunctionalInterface
public interface ThrowingRunnable extends Runnable {
#Override
default void run() {
try {
tryRun();
} catch (final Throwable t) {
throwUnchecked(t);
}
}
private static <E extends RuntimeException> void throwUnchecked(Throwable t) {
throw (E) t;
}
void tryRun() throws Throwable;
}
I prefer this over new RuntimeException(t) because it has a shorter stack trace.
You can now do:
executorService.submit((ThrowingRunnable) () -> {throw new Exception()});
Disclaimer: The ability to perform unchecked casts in this way might actually be removed in future versions of Java, when generics type information is processed not only at compile time, but also at runtime.
Your requirement doesn't make any sense. If you want to notify the called of the thread about an exception that happened, you could do that through a call back mechanism. This can be through a Handler or a broadcast or whatever else you can think of.
I think a listener pattern might help you with this scenario. In case of an exception happening in your run() method, use a try-catch block and in the catch send a notification of an exception event. And then handle your notification event. I think this would be a cleaner approach. This SO link gives you a helpful pointer to that direction.
Yes, you can throw checked exceptions from the run() method. It can be done with generics by tricking the compiler. Look at this code:
public static void main(String[] args) {
new Main().throwException();
}
public void throwException() {
Runnable runnable = () -> throwAs(new Exception());
new Thread(runnable).start();
}
private <T extends Throwable> void throwAs(Throwable t) throws T {
throw ( T ) t;
}
This might be helpful if you want to throw checked exceptions from the run() method of Runnable
The easiest way is to define your own exception object which extend the RuntimeException class instead of the Exception class.
I am a c++ developer and I am pretty new with the checked and unchecked exception in java. The exception specifications in c++ are simply not good and that's why nobody is using it. I like the checked exception and I have a question, let's have this interface:
public interface Warehouse {
MyStuff fetch(int id);
}
The warehouse can be implemented in different way: file, database or in memory (mock object for test).
Now, if I want to implement using a file, I cannot try to open the file in the method otherwise my signature will change and my class will not implement the interface anymore. Also if I had another class with another checked exception all the other existing implementation will be affected.
I can see two solutions:
Catch the checked exception and throw another custom runtime exception. I don’t think this is a good solution, why the user should catch a runtime exception saying that a file is missing when there is already a standard and checked way to do that.
Do the entire job in the constructor of the implementation class and leave the fetch function unable to throw. I like this way, the object both exists and is valid or it doesn’t exist. The only drawback on this approach is that we cannot implement a lazy evaluation; we need to read and parse the file in the constructor even though nobody will use the object. This is not efficient.
Am I missing something? Is there a better way to avoid this problem?
Your first solution is the right one. Change your interface to :
public interface Warehouse {
MyStuff fetch(int id) throws FetchFailureException;
}
And make every subclass wrap its IO, JDBC or whatever exception inside a FetchFailureException. This FetchFailureException exception should be runtime if unrecoverable, and checked if recoverable.
Personally, I would have Warehouse list all the exceptions it can throw (including unchecked ones in the javadoc)
If you have an exception which is not listed, you need to handle it or wrap it. (Whether its checked or not)
You have to make your mind up whether you want Warehouse to throw an checked exception or not. You can't have it both ways. (Actually you can but its not a good idea as you can blindly throw a checked exception without the compiler knowing)
The Best practice is to specify the exceptions which the method will be throwing in the interface.
Suppose you have a custom Exception class :
class MyException extends Exception { public MyException
(String message) { super(message); } public
MyException (String message, Exception cause) { super(message,
cause); }
}
Handle all your exceptions in MyException class,
Now you can specify the exception which your method should throw in the interface
public Interface Warehouse
{
public MyStuff fetch() throws MyException;
}
I would suggest you to include in the Warehouse class all the exceptions and then working with subinterfaces in order to work with non checked exceptions, like this:
public interface Warehouse {
MyStuff fetch(int id) throws FileNotFoundException;;
}
public interface FileWarehouse extends Warehouse {
#Override
MyStuff fetch(int id) throws FileNotFoundException;
}
public interface OtherWarehouse extends Warehouse {
#Override
MyStuff fetch(int id);
}