I want to check preconditions on a base class so that I know subtypes will always use constructor arguments that are valid.
Let's take as an example a constructor that:
takes 2 or more parameters
takes parameters of different types
for one parameter, it performs multiple checks (e.g. String is not null and not empty)
How would one best use the Guava preconditions approach in that case?
In a mock example like this: (this is contrived!)
protected AbstractException(String errorMessage, Throwable errorCause) {
super(errorMessage, errorCause);
checkNotNull(errorMessage,
ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK, "errorMessage");
checkArgument(!errorMessage.isEmpty(),
ErrorMessage.MethodArgument.CANNOT_BE_EMPTY_STRING_CHECK,
"errorMessage");
checkNotNull(errorCause, ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK,
"errorCause");
}
I end up calling super before checking the arguments because a call to super needs to be the first line of the method and, although I could do super(checkNoNull(errorMessage)), I cannot do the same wrapping using checkArgument because that returns void. So the dilemma is:
Where do I put the checks on all arguments? I don't want to create a Builder just for that
How do I "group" checks as in a fictitious checkStringNotNullAndNotEmpty()
Should I rather think about integration with matchers frameworks? (hamcrest, fest assertions...)
I use the odd-looking ErrorMessage.MethodArgument.CANNOT_BE_NULL_CHECK because the default throw does not include an error message so from the testing side I cannot recognise this as an argument validation failure rather than a "any" NPE?
Am I doing it all wrong?
This should have been a comment, but it's too long.
Calling super before the test is harmless provided that the super ctor doesn't do things which it shouldn't do anyway.
It could be prevented via a static builder method, you need no Builder. But it's not worth it.
I doubt that grouping tests is generally useful; if it was, then there would be a such method already. But if you need one such a concrete thing more than twice, then write your own; if it comes often, report it to the Guava team as an RFE.
I'm pretty sure, matchers are an overkill here as you're just creating an exception, i.e., something used only rarely (I hope). As your test is runtime only, it can't really help to catch errors. It would be nice, if you could statically ensure a "properly" constructed exception, but it's impossible in pure java.
More important: The exceptions you're throwing are probably inferior to the ones you'd get without all the checks. Imagine the user provides a cause and no message. That's bad, you think, but you replace it with an NPE lacking any cause. That's worse.
Look at Guava's Preconditions.format (package private). They could check the correct number of arguments first, but they do not. You can provide too few or too many, which is an error, but ignoring it is the best way to handle it.
Related
I want to check arguments in a method. I've found the Objects.requireNonNull method which makes the code easily readable.
Is it some similar build in solution for boolean checking?
I want a similar syntax to this:
SomeJavaObject.requiredFalse(myArgument < 0, "myArgument can not be negative!");
(I can write my own method, but I prefer using the built in java functions.)
Since we have the Apache Commons libraries in our project anyways, I tend to use the checks in the Validate class from time to time: https://commons.apache.org/proper/commons-lang/javadocs/api-3.5/org/apache/commons/lang3/Validate.html
There is similar stuff in Guava's Preconditions class, but I prefer Validate.
We decided to avoid the assert keyword because code running on a customer's machine would then have different execution paths than during local development, making it harder to debug issues.
You can use the assert keyword.
int a = -1;
assert a >= 0 : "Parameter passed to foo() can't be negative";
The code above will throw an AssertionError if you launch it with -enableassertions or -ea for short.
Caused by: java.lang.AssertionError: Parameter passed to foo() can't be negative
Keep in mind that assert by no means should be used to validate arguments passed to public methods, or even worse - user input, because they are disabled by default. Yes, they can be disabled, and this is not a pitfall of assert, but a conscious and deliberate design choice. Why you can't use that in some cases is clearly written in the official Oracle guideline:
Argument checking is typically part of the published specifications (or contract) of a method, and these specifications must be obeyed whether assertions are enabled or disabled. Another problem with using assertions for argument checking is that erroneous arguments should result in an appropriate runtime exception (such as IllegalArgumentException, IndexOutOfBoundsException, or NullPointerException). An assertion failure will not throw an appropriate exception.
That does not mean that using assert should be avoided and is considered a bad practice. Assertion is not equal to error handling. The key is to use the right tool for the right job. Assertions are useful at catching programmers' mistakes - to make sure that something regarded as impossible indeed does never happen - for example:
Checking if a variable in a private method does not have an unexpected value, as stated in the guideline:
You can, however, use an assertion to test a nonpublic method's precondition that you believe will be true no matter what a client does with the class.
Marking a block of code that should never be reached with assert false.
There is no such method in the standard API and there are some reasons, not to add it. While Objects.requireNonNull will throw a dedicated exception, NullPointerException, there is no such obvious exception type for a method that tests an arbitrary predicate. If the predicate is testing a parameter value, an IllegalArgumentException might be appropriate, otherwise, an IllegalStateException or something completely different would fit better. You might consider an API with a Supplier for the exception, but this leads to the second issue.
If you want to support a supplier for the exception, you need a capturing lambda expression if you want to provide a message that includes the illegal value. And the overhead might be simply too much for parameter checking. The same would apply to a String parameter as it has to be constructed before invoking the utility method. This differs from the requireNonNull test where the illegal value invariably is null.
While HotSpot might be good at eliminating such overhead, the API is the standard for all JREs, including those not having such an optimization potential.
Besides that, it would make more sense to have a naming like
require(myArgument >= 0, "myArgument can not be negative!");
instead of forcing the reader to decipher a negation.
Since it’s more common to have multiple methods with similar constraints in one class, the established pattern is to have a more tailored method, e.g.
checkPositive("myArgument", myArgument);
…
private void checkPositive(String name, int arg) {
if(arg<0) throw new IllegalArgumentException(name+" is negative");
}
See for example rangeCheck in ArrayList or checkIndex in NIO Buffer
Afaik there's no such method. What I usually do is this:
if(myArgument < 0)
throw new IllegalArgumentException("myArgument must be greater or equal to 0");
(and repeat for each parameter check)
You can also use assertions, altho those aren't always welcome in production code.
Background
Java interfaces specify the contract between the caller and callee sides of development. For example:
public interface SomeContainer<T> {
public boolean add(T value) throws SomeException;
}
The above method must return either a boolean or throw the given exception, and nothing else.
Problem Description
How can I do the same for a Play Promise-based method? A promise does not "throw" an exception; rather, a promises executes Promise.failure(ExceptionHere). Hence, my interface doesn't "throw" anything:
public interface SomeContainer<T> {
public Promise<boolean> add(T value);
}
However, the above definition does not prevent the implementating class from executing Promise.failure()--not a very good interface definition.
One possibility is to return a "Result" object which can contain the boolean or one of several allowed exceptions. However, this seems hackish, and still does not prevent the implementing code from calling Promise.failure() anyway.
Question
How does one write an effective Play Promise-based interface, where all return values and all acceptable exceptions are specified and nothing else is allowed?
What you're describing is a fundamental limitation of exceptions - their specification only works when they are thrown directly from a method. The problem is not specific to promises, it manifests itself all over the place, anytime you package execution of something up into a generic interface, which is especially pertinent when using lambdas. Consider doing a List.forEach, that doesn't throw an exception, but typically you will pass a lambda to it (which will implement java.util.function.Function), what if that lambda throws an exception? The answer is, it can't, unless it's an unchecked exception, and then there's no way to know statically that that exception will be thrown through to the caller of forEach.
The only real answer is don't use exceptions. If you talk to a functional programming purist, they will say never, ever use exceptions, instead of exceptions you should use a disjoint type. Play's Java API actually provides such a type, it's play.libs.F.Either. Convention is that the left should be the error, and the right the value. That said, Play's either type is quite limited, and doesn't compose very well with itself or other things. The either type provided by the Functional Java library is much more complete, and composes well. If you value being as strict as possible about type safety, in particular with exceptions, then this is probably the library for you, even without using promises, encoding errors into return types offers better type safety than exceptions, and makes it very straight forward to compose and reuse error handling. And if that sounds like a good option to you, then you should also consider using a language with stronger typing than Java, eg Scala.
If you're like me though and are little more pragmatic about things, then you'll use a hybrid approach. In some cases, it's really important for the caller to explicitly handle errors, in which case, they should be encoded in the types, an example of this is form validation, you don't just want to throw an error, you want to handle it by rendering a page with multiple meaningful error messages in it - this is a perfect example of where strongly typed error handling really shines, you can return a list of errors, one for each field that had a problem in a form, but you can't throw a list of exceptions. In other cases, errors really are exceptional things that don't usually have a specific handling strategy, instead they should be left to a general catch all high up in the stack to handle generically. For example, if the database is down, that's not something that you can usually recover from. In these cases, you lose nothing by throwing unchecked exceptions and letting the generic error handling do its thing.
I am starting to add tests to a large java code base. I often see the following in the session beans I am testing:
public OrderDTO getOrderDTO(Long id) {
Order o = (Order)entityManager.find(Order.class, id);
OrderDTO dto = new OrderDTO(o.getId(), o.getCurrency());
return dto;
}
Its quit easy to write a unit test to break this code (send in a null or a non existing id). When I did that half the developers of the team said:
We are not error checking everything. If you parameter is rubbish you will know fast!
The other half said:
We must add ifs to the id and then to the o and if any of them are null the null is what we return.
Isn't the point of unit testing to find exactly thees kind of issues?
(Yes, I am asking for an opinion!)
Yes, switching from Long to long will remove one if.
While this is somewhat opinion based, few people would say it's correct to return null if given null as a parameter. If I were to add anything, it would be at most a IllegalArgumentException (or even NPE) when null is passed in.
A test could be created to check that the method fails in a consistent fashion, but it would really be testing the behaviour of the JPA provider and not your code.
Returning nulls should be avoided, they are the source of all evil.
You could use the Null Object Pattern.
Or throw an exception, illegalargument or entitynotexsits spring to mind.
If you must return null, at least wrap it in an optional or use guava.
As always, it depends :)
If you are writing library code (code that is shared and used elsewhere or even by others), then you should really aim for handling all thinkable input values in a consistent way. Using well documented exceptions instead of returning null is certainly preferable for library code.
On the other hand there is local code.
I can see the method is public, but that does not eliminate the possibility that it's only used in one isolated portion of the code base.
In that case, you don't work with assumptions about parameters and what the caller expects in return. You work with defined calls. You control what is sent in and how the caller handles the return value. So it's OK not to null-check, if you know the caller never sends null. And it can be OK to return null as well if that simplifies your overall program structure.
ps: what bothers me most in that method is the unhandled NPE if entityManager.find(..) fails :)
I'm tempted to add a suffix like "Ex" to differentiate methods (with similar signatures) that throw Exceptions from those that don't.
Is there such a convention?
Yes, you name them the same as methods that don't.
Isn't the exception specification enough?
Edit: If you have similar methods that throw/not throw, I recommend the Parse/TryParse pattern (Parse being replaced by the operation). .NET Framework uses it frequently (Dictionary<T,K>.TryGetValue, Monitor.TryEnter, int.TryParse, etc. etc.).
Edit: Coding Horror: TryParse and the Exception Tax
Don't do that.
This is like asking "is there a naming convention for methods that take two Strings as parameters".
Java has checked exceptions, which means that you need to declare them anyway.
So you can easily see if an exception will be thrown, and what type of exception.
You cannot even compile code that calls the method without adding exception handling code.
Update: It seems your intention is to have methods that check if a certain condition is true, but you do not want to return just false, but throw an Exception if the condition is not met, so that you can also convey an explanation message (in the Exception). I think a prefix of "assert" or "ensure" makes sense:
// instead of
if (! isAuthenticated())
throw new NotAuthenticatedException("not sure why at this point...");
// you do
assertAuthentication();
// which will throw NotAuthenticatedException("proper explanation") inside
Why would you do such a thing in Java? It already has exception specifiers built into the language. The compiler will prevent you from calling a method which explicitly throws an exception without some action being taken on your part to handle or allow the exception to propagate?
If you need these methods differentiated, I'm sure you can do it in the naming without using a suffix or anything, which is (as others have pointed out) pretty ghastly.
Why have:
boolean authenticate(String username, String password);
and (say)
void authenticateEx(String username, String password) throws WhateverException;
when you could actually make it a meaningful part of the name by conveying the actual intent:
void ensureCanAuthenticate(String username, String password);
// or
void assertValidCredentials(...);
// or
void authenticateOrDie(...);
... or any number of other (probably better) names which actually convey the intent rather than relying on a confusing suffix.
Exceptions are part of the method signature in Java, therefore such a naming convention would be redundant.
Hungarian notation for methods that throw exceptions? Quel horror!
Do you mean checked or unchecked exceptions? Why on earth would you want to do that?
When you think about it, you'd have to add your convention to every method, because there's always the potential of an error or NPE or some other thing that could go wrong.
The "throws" clause is enough when you have checked exceptions, and there's no good purpose on God's green earth for unchecked exceptions.
Don't do it. Please.
Generally don't add it to method names.
Add throws instead.
int parseInt(String s, int radix) throws NumberFormatException
But personally i like for getter e.g.
getFieldsOrThrow(java.lang.String key)
getFieldsOrDefault(java.lang.String key, Value defaultValue)
https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/Struct
There is no convention and adding an ex will make the name harder to read and ugly looking for the average java programmer.
But at sometimes I could imagine that it would make your code faster understandable to add a try to methods that are likely to throw an exception. Especially if they are unchecked.
It doesn't have to be something ugly like it could be found in many c/c++ programs where you use _name or mName for members or iValue for integers.
But in java there are some conventions too.
If a method will return an integer it is prefixed with is... set, get and test are the most used examples for this. All of this things are documented in the method header, through return type annotations etc... But adding one word to the function name makes it easier and faster to read and understand.
Why not use try to give programmers reading your code a subconscious hint that this method is likely to throw an exception. Like tryCopyFile instead of tryWriteFile.
There is none that I'm aware of.
In my opinion, the only time something like that makes sense is in unit test cases (e.g., testFooExpectingException()). But that's not really what you're talking about.
There is no such convention because every method can throw exceptions, regardless of whether you declare them or not. It's also somewhat redundant in this day and age of IDE tooltips (unless you're not using an IDE of course).
I'm curious to know why you are tempted to use such a naming convention though.
Every once in a while you'll run into a case where it might make sense to have a method name like getSafely() (returns a default value in the case where the actual value is invalid, for code that doesn't care too much about real values vs placeholders) or its converse getOrBlowUp() (for fail-fast code where a missing value is technically possible but indicates a bug in the code that's supposed to set the value).
But the point here isn't "method 2 throws an exception, method 1 doesn't" -- because, as mentioned above, any code could throw a RuntimeException. The point is that the two methods have different error-handling semantics, specific to different use cases, and that's what the method names try to capture.
Even then, the code would usually be cleaner if you could just get away with one behavior or the other, and call the method get().
A useful parallel here might be the distinction between Systems Hungarian and Apps Hungarian in Hungarian Notation. (See also this piece on coding conventions from Joel on Software.)
Systems Hungarian just tells you the type of the variable, so integer count becomes iCount. This is the most common form of Hungarian notation and IMHO it's (1) pretty pointless with a modern IDE and (2) potentially deceptive, if someone changes the type declaration without renaming the variable.
Apps Hungarian tells you the purpose of the variable, so integer (or short, or ordinal ID object, or whatever, who cares?) index representing a data row becomes drIndex, and index representing an annotation column becomes acIndex. This is much more useful and much less likely to cause trouble.
Calling your method getEx() is Systems Hungarian.
After posting this question and reading that one I realized that it is very important to know if a method is supposed to return null, or if this is considered an error condition and an exceptions should be thrown. There also is a nice discussion when to return ‘null’ or throw exception .
I'm writing a method and I already know if I want to return null or throw an exception, what is the best way to express my decision, in other words, to document my contract?
Some ways I can think of:
Write it down in the specs / the documentation (will anyone read it?)
Make it part of the method name (as I suggested here)
assume that every method that throws an exception will not return null, and every one that does 'not' throw might return null.
I'm mainly talking about java, but it might apply to other languages, too: Why is there a formal way to express if exceptions will be thrown (the throws keywords) but no formal way to express if null might be returned?
Why isn't there something like that:
public notnull Object methodWhichCannotReturnNull(int i) throws Exception
{
return null; // this would lead to a compiler error!
}
Summary and Conclusion
There are many ways to express the contract:
If your IDE supports it (as IntelliJ), it's best to use an annotation like #NotNull because it is visible to the programmer and can be used for automated compile time checking. There's a plugin for Eclipse to add support for these, but it didn't work for me.
If these are not an option, use custom Types like Option<T> or NotNull<T>, which add clarity and at least runtime checking.
In any way, documenting the contract in the JavaDoc never hurts and sometimes even helps.
Using method names to document the nullability of the return value was not proposed by anyone but me, and though it might be very verbose und not always useful, I still believe sometimes it has its advantages, too.
A very good follow up question. I consider null a truly special value, and if a method may return null it must clearly document in the Javadoc when it does (#return some value ..., or null if ...). When coding I'm defensive, and assume a method may return null unless I'm convinced it can't (e.g., because the Javadoc said so.)
People realized that this is an issue, and a proposed solution is to use annotations to state the intention in a way it can be checked automatically. See JSR 305: Annotations for Software Defect Detection, JSR 308: Annotations on Java Types and JetBrain's Nullable How-To.
Your example might look like this, and refused by the IDE, the compiler or other code analysis tools.
#NotNull
public Object methodWhichCannotReturnNull(int i) throws Exception
{
return null; // this would lead to a compiler error!
}
You can use the Option type, which is very much like a list that has zero or one element. A return type of Option<Object> indicates that the method may return an Object, or it may return a special value of type None. This type is a replacement for the use of null with better type checks.
Example:
public Option<Integer> parseInt(String s) {
try {
return Option.some(Integer.parseInt(s));
}
catch (Exception e) {
return Option.none();
}
}
If you use this consistently, you can turn on IDE null-warnings, or just use grep for null which should not appear in your code at all if you use Option.none() everywhere you would normaly use a null literal.
Option comes standard with Scala, and it is called Maybe in Haskell. The link above is to a library called Functional Java that includes it. That version implements the Iterable interface, and has monadic methods that let you compose things nicely. For example, to provide a default value of 0 in case of None:
int x = optionalInt.orSome(0);
And you can replace this...
if (myString != null && !"".equals(myString))
...with this, if you have an Option<String>...
for (String s : myOptionString)
There's some support for a #Nullable and #NotNull annotation in IntelliJ IDEA. There's also some talk about adding those annotations (or a similar feature) to Java 7. Unfortunately I don't know how far that got or if it's still on track at all.
Indeed: in our framework we have a 'non-null' pointer type, which may be returned to indicate that the method will always return a value.
I see three options:
wait for language support to express it (e.g. the C# ?! thing)
use Aspect Orientation to build your own language extensions to express it
use a custom type to express it
(but builds on developer cooperation) use a naming scheme to indicate it
For Java, one can use the Javadoc description of a method to document the meaning of the returned value, including whether it can be null. As has been mentioned, annotations may also provide assistance here.
On the other hand, I admit that I don't see null as something to be feared. There are situations in which "nobody's home" is a meaningful condition (although the Null Object technique also has real value here).
It is certainly true that attempting a method invocation on a null value will cause an exception. But so will attempting to divide by zero. That doesn't mean that we need to go on a campaign to eliminate zeroes! It just means that we need to understand the contract on a method and do the right thing with the values that it returns.
Have you had a look at Spec#?
You could write your own annotation (Java) or attribute (C#) to indicate that the return value might be null. Nothing will automatically check it (although .NET 4.0 will have code contracts for this sort of thing) but it would at least act as documentation.
Maybe you could define a generic class named "NotNull", so that your method might be like:
public NotNull<Object> methodWhichCannotReturnNull(int i) throws Exception
{
// the following would lead to a run-time error thown by the
// NotNull constructor, if it's constructed with a null value
return new NotNull<Object>(null);
}
This is still a run-time (not a compile-time) check, but:
It's thrown in the implementation of the method (it's not a fault in the calling code)
It's self-documenting (the caller knows he's geting NotNull<T> as a return type)
At all costs, avoid relying on the JavaDocs. People only read them if the signature doesn't appear trivial and self-explanatory (Which is bad to begin with), and these who actually bother to read them are less likely to make a mistake with the nulls since they are currently being more careful.
If you're using Java 5+, you can use a custom Annotation, e.g. #MayReturnNull
UPDATE
All coding philosophy aside (returning null, using exceptions, assertions, yada yada), I hope the above answers your question. Apart from primitives having default values, complex types may or may not be null, and your code needs to deal with it.
Generally speaking, I would assume that a null return value is against the contract of the API by default. It is almost always possible to design your code such that a null value is never returned from your APIs during "normal" flow of execution. (For example, check foo.contains(obj) rather then calling foo.get(obj) and having a separate branch for null. Or, use the Null object pattern.
If you cannot design your API in such a way, I would clearly document when and why a null could be thrown--at least in the Javadoc, and possibly also using a custom #annotation such as several of the other answers have suggested.