Question

I have the following API:

public interface MyApi {

   /**
    * Performs some stuff.
    * @throws MyException if condition C1
    */
   public void method() throws MyException;
}

I am now performing the following modification in my API implementation

public class MyApiImpl {

   public void method() throws MyException {
     if (C1) {
       throw new MyException("c1 message");
     }
     ...
   }
}

is replaced by :

public class MyApiImpl {

   public void method() throws MyException {
     if (C1) {
        throw new MyException("c1 message");
     } else if (c2) {
        throw new MyException("c2 message");
     }
     ...
   }
}

Do you consider this as an API breakage ?

Client's code will still compile but method contract defined by the API javadoc is no more respected since MyExcepiton is thrown by a "new" condition.

If only my API jar file is updated, clients application will still work but depending on the way clients catch the exception the application behavior can change a lot.

What's your point of view on that ?

Was it helpful?

Solution

Yes, you're breaking the contract of the interface by throwing an exception when C1 doesn't occur.

As a rule of thumb, the vaguer the interface contract, the easier it is not to break :) If the interface isn't defined in terms of an explicit C1, but in more general terms, that gives a lot more flexibility.

OTHER TIPS

My point of view is that you should not change the contract defined by the API in the documentation. If you need new behavior you should either a.) create a new method that can be called by the client reflecting this new behavior or b.) discuss with the client the need for the change and make them aware of it.

This really can go both ways, it is between you and your clients as to what your approach will be.

It largely depends on what c2 is. Is it within the logical bounds on the pre-existing contract? If so, you're satisfying the contract by throwing a MyException. If not then perhaps you need to throw a new type of exception.

I should point out that I'm not a huge fan of checked exceptions. Ultimately, forcing someone to deal with an exception doesn't necessarily make their code any better or safer (in fact it can have the opposite effect as they can sloppily swallow spurious exceptions).

I'd say "no", no API breakage, unless MyException is a RuntimeException. Then it is.

Anyway, I'd subclass MyException for condition C2

And both conditions C1 and C2 should be "exceptional" IMHO, I would not make an habit of throwing exceptions

It's a breakage. Whether the API is enforced by language constructs or simply documented is irrelevant.

Whether this breakage causes a problem for client code is a different question. It may be that you are fixing a defect and need to cover case C2 in this way to fix it. From that respect client code developers may be happy that you've made this change (assuming they are not currently working around the defect in such a way which would break in the face of the change!)

I think the problem here is that you made part of your interface, implementation specific conditions. If the "C1" condition were only part of your implementation, then you could have simply created a new implementation that throws an exception on "C1" or "C2" without breaking the interface.

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