aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes What's all the fuss about java assertions? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "What Watch "What New topic
Author

What's all the fuss about java assertions?

Alexandru Dragoi
Ranch Hand

Joined: May 09, 2008
Posts: 30
I want to take the OCMJD exam and I am reading the book "SCJD Exam with J2SE 5" written by Andrew Monkhouse and Terry Camerlengo.

At page 49 it says:

Caution You should never use assertions to validate the inputs on public methods—these are methods that other programmers may use, and they may not honor your requirements. You should validate these inputs regardless of whether or not assertions are turned on at runtime.


And it even gives an example of correct use of assertions:



In my opinion this code has a big problem: if you withdraw something from your account and the balance becomes less than 0, then no exceptional event is signaled if assertions are turned off (for example in a production environment).
So from my point of view, I should validate these post-conditions and throw a checked exception instead of doing that assertion thing.

Let me know about your opinion regarding assertions...


Alex Dragoi, SCJP 1.4, OCPJP 6
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2594
    
    9

Looking at Andrew's assertion example, it has a problem. The assert statement is checked after it has deducted the withdrawal amount. Instead a better version may look something like



As for the OCMJD, you should not rely on assertion. In fact you should not even have an assert statement. Throwing (meaningful) exceptions when validation fails is acceptable.

And welcome to the Ranch.


K. Tsang JavaRanch SCJP5 SCJD/OCM-JD OCPJP7 OCPWCD5 OCPBCD5
Alexandru Dragoi
Ranch Hand

Joined: May 09, 2008
Posts: 30
Thanks for the feedback K. Tsang!
I just started to document myself and read books regarding OCMJD and I think that JavaRanch forum is a great resource to learn.
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2594
    
    9

Alexandru Dragoi wrote:Thanks for the feedback K. Tsang!
I just started to document myself and read books regarding OCMJD and I think that JavaRanch forum is a great resource to learn.


Yes this forum/site is great place to learn.

Good luck with the assignment. You may want to check out the SCJD FAQ and SCJD wall of fame for pointers and hints.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5536
    
  13

K. Tsang wrote:Looking at Andrew's assertion example, it has a problem. The assert statement is checked after it has deducted the withdrawal amount. Instead a better version may look something like

I don't want to be harsh, but you are completely wrong here! That's exactly what the caution (mentioned in the OP) is all about: don't use assertions to verify parameters (arguments) of a public method. So his example is spot on!

If you want to check parameters (arguments) from a public method use IllegalArgumentException instead, like:


With regard to the OCMJD assignment: I didn't use any assertions at all, but a gazillion IllegalArgumentException (and IllegalStateException) to guarantee correct use of the API as possible.

Good luck!


SCJA, SCJP (1.4 | 5.0 | 6.0), SCJD
http://www.javaroe.be/
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2594
    
    9

Roel I agree using assertions is bad. My example is just try to illustrate if assertion was used, the assert statement should check the current balance before withdrawal rather than after.
Sresh Rangi
Ranch Hand

Joined: Nov 28, 2012
Posts: 47
    
    2
Checking the balance after makes sense if it's not possible for the balance to be negative. For example, reduceBalance checks the balance itself and throws an exception if there are insufficient funds. This way the program doesn't rely on assertions for correct behavior. They are only used for documentation or testing.

Assertions aren't normally used on parameters because the method can not make any guarantees of what values they have.
Alexandru Dragoi
Ranch Hand

Joined: May 09, 2008
Posts: 30
Sresh Rangi wrote:Checking the balance after makes sense if it's not possible for the balance to be negative. For example, reduceBalance checks the balance itself and throws an exception if there are insufficient funds. This way the program doesn't rely on assertions for correct behavior. They are only used for documentation or testing.

Assertions aren't normally used on parameters because the method can not make any guarantees of what values they have.


That's more realistic!
I was confused because the implementation for reduceBalance was not revealed so I thought that the assertion was the only check to be done.
If the reduceBalance method checks and validates the withdrawalAmount against the current balance by throwing an exception, then I think that this is a good implementation.

However, I would prefer a checked exception (instead of a runtime IllegalArgumentException/IllegalStateException) to be thrown if the validation fails. That is because if the user tries to withdraw an invalid amount, this should be a recoverable condition and not a programming error.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5536
    
  13

Alexandru Dragoi wrote:However, I would prefer a checked exception (instead of a runtime IllegalArgumentException/IllegalStateException) to be thrown if the validation fails. That is because if the user tries to withdraw an invalid amount, this should be a recoverable condition and not a programming error.

Throwing a checked exception when this validation fails is of course even better. But you always have to be careful when using checked exceptions: when used thoughtless they can clutter your code in no time, certainly when you are designing/creating a framework/library/API. And as already mentioned in my previous post: I used IllegalArgumentException/IllegalStateException to guarantee correct use of the API as possible. So that's to prevent a developer of abusing the API, when it goes wrong it's not a recoverable condition, the developer just mad a mistake. The exception which is thrown when a room/contractor is already booked, is definitely a checked exception.
Alexandru Dragoi
Ranch Hand

Joined: May 09, 2008
Posts: 30
Roel De Nijs wrote:
Alexandru Dragoi wrote:However, I would prefer a checked exception (instead of a runtime IllegalArgumentException/IllegalStateException) to be thrown if the validation fails. That is because if the user tries to withdraw an invalid amount, this should be a recoverable condition and not a programming error.

Throwing a checked exception when this validation fails is of course even better. But you always have to be careful when using checked exceptions: when used thoughtless they can clutter your code in no time, certainly when you are designing/creating a framework/library/API. And as already mentioned in my previous post: I used IllegalArgumentException/IllegalStateException to guarantee correct use of the API as possible. So that's to prevent a developer of abusing the API, when it goes wrong it's not a recoverable condition, the developer just mad a mistake. The exception which is thrown when a room/contractor is already booked, is definitely a checked exception.


Let me see if I understand well...

So in my case for a reduceBalance(int withdrawalAmount) method, if I choose to do this:

I must specify in the javadoc that it is a violation to withdraw an something that is bigger than the current amount.
So it will be up to the client of the API who calls this method to perform the actual validation.

Because I specify this in the javadoc, if the client that implements the API fails to adhere to the contract, then this is a programming error and the runtime exception is suitable for my case.
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5536
    
  13

Alexandru Dragoi wrote:So it will be up to the client of the API who calls this method to perform the actual validation.

Exactly But this client could be some kind of service (it doesn't has to be a client like some user interface).

Imagine a BankAccount class whiich has an instance variable balance and a method withdraw. The amount to withdraw can never be bigger than the balance total. This domain class will only be used in service classes, not directly by any GUI. So to validate this rule (and to protect your API) you implement the method like this:

The BankAccountService has also a method to withdraw an amount of a certain balance. Because this service will be used by (several) GUI(s) you'll throw a checked exception here, because this is a recoverable situation (user must choose a lower amount to withdraw). An implementation could be:


And as an illustration of an API/library where wrong usage of checked exceptions can result in cluttered code, have a look at this JSONObject class. If you have a look at the several put-methods you'll see this method throws a checked JSONException when the key is null. That means I always have to catch (or handle) this exception even if I know for sure that the key can never be null, like in this example:

So it requires 3-4 lines of extra code for a situation which can never occur! Another drawback: you can never test the catch-clause because it will never occur. So if you use a quality management platform (e.g. SonarQube) to measure your source code quality (and test coverage) you can never get a 100% score for this class, because of this checked exception.

Checked exceptions are nice and a very powerful language structure, but they must be used with great care; otherwise it will be a burden instead of a blessing!
Alexandru Dragoi
Ranch Hand

Joined: May 09, 2008
Posts: 30
Thanks Roel, I think I get the idea!
Indeed, for the BankAccount which cannot be directly called by the API users (may well be package-private), the IllegalArgumentException seems more suitable than a checked exception.
On the other hand, the BankAccountService makes part of the public API and it is better to throw a checked exception here, because the API users must have a way to respond.

Now regarding JSONObject, it looks horrible! And they cannot even change the API without breaking their clients code.
JSONObject seems to be doomed forever!
Roel De Nijs
Bartender

Joined: Jul 19, 2004
Posts: 5536
    
  13

Alexandru Dragoi wrote:Now regarding JSONObject, it looks horrible! And they cannot even change the API without breaking their clients code.
JSONObject seems to be doomed forever!

It's not completely doomed: they can simply make JSONException a runtime exception instead of a checked one. That shouldn't break any client code.

In my current project I have to use this class. So I know what it means for your code if you have to use a badly designed API But I created a JSONUtils class with a few utility methods to gracefully handle this issue: e.g. the method put(JSONObject jsonObject, String key, Object value) checks if the key is null and if it's null a runtime exception is thrown (because it means 1 of the developers has made a mistake during development). So only in this utility class the JSONException can appear, but nowhere else. So this "workaround" decreases code cluttering and allows us to achieve 100% test coverage. That's how it should be designed in the 1st place.
Alexandru Dragoi
Ranch Hand

Joined: May 09, 2008
Posts: 30
Thanks for this discussion Roel!
That was more than enough for me to understand well what I needed to understand!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: What's all the fuss about java assertions?