Exception to throw when instance variables are null - java

I'm working on making a codebase complaint with a list of PMD rules. These include that you're not allowed to throw or catch NullPointerExceptions. I found this method which requires 2 instance variables to be non-null in order to run. It throws a NullPointerException otherwise:
public String build() {
if (apiKey == null || url == null) {
throw new NullPointerException(
"Cannot build: API key and URL must be set");
}
What should it be throwing instead? it seems to me that NullPointerException would be the bast call. The only other thing that comes to mind is IllegalArgumentException, but these aren't really arguments, so I don't think it really fits.

IllegalStateException seems entirely appropriate here:
Signals that a method has been invoked at an illegal or inappropriate time.
That describes the situation reasonably clearly, doesn't it?

IllegalStateException springs to mind.
One thing to consider here is whether this should be a checked or an unchecked exception. You could also consider making your own explicit Exception for this case if it can usefully be handled differently from the generic IllegalStateException.

Related

Need a better explanation for try/catch/throw/throws exception handing in Java

I am a little unsure about the difference between the try/catch, throw and throws in Java and every website seems to have an inhuman way of explaining it, I have tried the Oracle website but I just could not understand their explanation, is this correct?
Try/catch
With try catch, I want to try a piece of code and if something goes wrong do this.
Throw
With throw, I am throwing an error because I want to?
So if I wanted to validate a users age, say all people over 20 and the user does not meet the requirements, I would throw an error?
Throws
With Throws I am throwing an error but something else handles the exception? Would this be another method/class?
Try / Catch
try
{
// try to do some actions
}
catch(SomeExceptionType exception)
{
// if the above actions throw a SomeExceptionType, do these actions
}
Throw
Correct. We're explicitly throwing an exception. You may do this if, for example, the caller of a method has violated your method's contract. Perhaps an argument cannot be negative.
In this situation, the best way to deal with this is to throw an exception which stops what we're doing and allows callers further up the stack to deal with the problem:
/** Do a thing. myInt must be positive */
void someMethod(Integer myInt)
{
if (myInt < 0)
{
throw new IllegalArgumentException("Can't be negative");
}
// do something
}
void myCaller()
{
someMethod( 1); // won't throw
someMethod(-1); // will throw
}
Throws
throws is used as a keyword when dealing with checked exceptions. It's a way of letting callers know what checked exceptions they can expect they may have to deal with.
Those methods can decide to deal with the problem (i.e. a try-catch) or can themselves declare the same exception type to be thrown to propagate the exception up to their caller (and so on and so on)
You forget a important point : in Java all exceptions are not handled by the compiler in the same way.
The compiler ensures only that the checked exceptions be handled.
These exceptions don't inherit from RuntimeException but from Exception (directly or indirectly).
So whatever you throw in your code or a method of a third class declares throwing a checked exception, you have to explicitly handle it.
And there you have two ways :
catching the exception
letting the exception be propagated to the caller
try/catch addresses the first way while specifying the throws modifier in the method declaration addresses the second.
For no RunTimeExceptions, you don't have this constraint as the compiler doesn't force you to handle it. You may handle them if you want to.

Preconditions library to throw IllegalArgumentException for notNull check

Do you know some nice alternative to Apache Commons Validate or Guava Preconditions that would throw IllegalArgumentException instead of NullPointerException when checking if object is not null (except Spring Assert)?
I'm aware that Javadocs say:
Applications should throw instances of this class [NullPointerException] to indicate other
illegal uses of the null object.
Nevertheless, I just don't like it. For me NPE was always meaning I just forgot to secure null reference somewhere. My eyes are so trained, I could spot it browsing logs with a speed of few pages per second and if I do there is always bug alert in my head enabled. Therefore, it would be quite confusing for me to have it thrown where I expect an IllegalArgumentException.
Say I have a bean:
public class Person {
private String name;
private String phone;
//....
}
and a service method:
public void call(Person person) {
//assert person.getPhone() != null
//....
}
In some context it may be ok, that a person has no phone (my grandma doesn't own any). But if you'd like to call such person, for me it's calling the call method with an IllegalArgument passed. Look at the hierarchy - NullPointerException is not even a subclass of IllegalArgumentException. It basically tells you - Again you tried to call a getter on null reference.
Besides, there were discussions already and there is this nice answer I fully support. So my question is just - do I need to do ugly things like this:
Validate.isTrue(person.getPhone() != null, "Can't call a person that hasn't got a phone");
to have it my way, or is there a library that would just throw IllegalArgumentException for a notNull check?
Since the topic of this question evolved into "Correct usage of IllegalArgumentException and NullpointerException", I would like to point out the strait forward answer in Effective Java Item 60 (second edition):
Arguably, all erroneous method invocations boil down to an illegal argument
or illegal state, but other exceptions are standardly used for certain kinds of illegal
arguments and states. If a caller passes null in some parameter for which null values
are prohibited, convention dictates that NullPointerException be thrown
rather than IllegalArgumentException. Similarly, if a caller passes an out-ofrange
value in a parameter representing an index into a sequence, IndexOutOfBoundsException
should be thrown rather than IllegalArgumentException.
What about Preconditions's checkArgument?
public void call(Person person) {
Preconditions.checkArgument(person.getPhone() != null);
// cally things...
}
checkArgument throws IllegalArgumentException instead of NullPointerException.
You can use valid4j with hamcrest-matchers (found on Maven Central as org.valid4j:valid4j). The 'Validation' class has support for regular input validation (i.e. throwing recoverable exceptions):
import static org.valid4j.Validation.*;
validate(argument, isValid(), otherwiseThrowing(InvalidException.class));
Links:
http://www.valid4j.org/
https://github.com/valid4j/valid4j
On a side-note: This library also has support for pre- and post-conditions (like assertions really), and it's possible to register your own customized global policy, if needed:
import static org.valid4j.Assertive.*;
require(x, greaterThan(0)); // throws RequireViolation extends AssertionError
...
ensure(r, notNullValue()); // throws EnsureViolation extends AssertionError
Take a look at https://github.com/cowwoc/requirements.java/ (I'm the author). You can override the default exception type using withException() as follows:
new Verifiers().withException(IllegalArgumentException.class).requireThat(name, value).isNotNull();
Not that I'm aware of. I'd just roll your own to get the behavior you want with a concise invocation, mimicking Guava's implementation but tweaking the exception type.
class Preconditionz {
public static <T> T checkNotNull(T reference, Object errorMessage) {
if (reference == null) {
throw new IllegalArgumentException(String.valueOf(errorMessage));
}
return reference;
}
}
I like to go ahead and import static these really frequently used methods, too, so you can call them super concisely.
import static com.whatever.util.Preconditionz.checkNotNull;
// ...
public void call(Person person) {
checkNotNull(person, "person");
checkNotNull(person.getPhone(), "person.phone");
// ...
}
Depending on your environment, you might want to name it checkNotNull2 so it's easier to add the import via autocompletion in your IDE, or let you use it alongside the standard checkNotNull.
I guess I learned something again here on SO thanks to great comments by Olivier Grégoire, Louis Wasserman, CollinD and Captain Man.
The standards are ussually a strong and sufficient reason as they make the common language programmers will always understand correctly, but in this particular case I had this little doubt, that maybe this rule set around NPE isn't too ok. Java is an old language and some of its features came up to be a bit unlucky (I don't want to say wrong, that's maybe too strong judgment) - like checked exceptions, although you may also disagree. Now I think that this doubt is resolved and I should:
Throw an IllegalArgumentException when in the particular context I can tell why the null value is wrong rather from the business perspective. For instance in the service method public void call(Person person) I know what does it mean to the system that the phone number is null.
Throw a NullPointerException when I just know that the null value here is wrong and will sooner or later cause a NullPointerException, but in the particular context I'm unaware what does it mean from the business perspective. The example would be Guavas immutable collections. When you build such and try to add an element of a null value it throws you a NPE. It doesn't understand what this value mean for you, it's too generic, but it just knows it's wrong here, so it decides too tell you this immediately, with some more appropriate message, so that you can recognize the problem more effectively.
Having above in mind I would say the best option to make the assertion in the public void call(Person person) example is like Captain Man suggests:
Preconditions.checkArgument(person.getPhone() != null, "msg");
Check argument is a good name for this method - it's clear that I'm checking the business contract compliance against the person argument and it's clear that I'm expecting IllegalArgumentException if it fails. It's a better name than the Validate.isTrue of Apache Commons. Saying Validate.notNull or Preconditions.checkNotNull on the other hand suggest that I'm checking for a null reference and I'm actually expecting the NPE.
So the final answer would be - there is no such nice library and shouldn't be as this would be confusing. (And Spring Assert should be corrected).
You can easily do this:
if (person.getPhone() == null) {
throw new IllegalArgumentException("Can't call a person that hasn't got a phone");
}
It is clear to other programmers what you mean, and does exactly what you want.

When to throw exceptions for constructor

public Neocortex(Region rootRegion, ConnectionInterface functor) {
this.rootRegion = rootRegion;
this.currentRegion = this.rootRegion;
this.functor = functor;
}
Hey above I have the constructor for one of my classes. My question is should I add null pointer exceptions to the constructor or would this be unnecessary? Honestly, I just don't understand when I should add exceptions to my code. But in this case which constructor should i use?
public Neocortex(Region rootRegion, ConnectionInterface functor) {
if (rootRegion == null) {
throw new NullPointerException("rootRegion cannot be null");
} else if (functor == null) {
throw new NullPointerException("functor cannot be null");
}
this.rootRegion = rootRegion;
this.currentRegion = this.rootRegion;
this.functor = functor;
}
Well... It is a matter of taste.
If the preconconditions for the class is that rootRegion has to be provided, it makes sense to protect the class implementation from the need to make null checks all over the place.
So to answer the question "When should I throw exception in a constructor" : I would do it in all cases where the parameters, from the consumer, brings your implementation in a invalid state, delegate the problem (ie. throw the exception).
If you try to take the role as consumer for a while, and you choose not to make the null-checks he will have code like:
Neocortex n = new Neocortex(null,null);
n.doSomeething();
If he reach the 2nd line, and the implementation here throws a NullPointerException it will not be clear for him that it is due to the parameters he provided.
I would throw an IllegalArgumentException for those arguments to the constructor that, if accepted, would lead to something bad (including, but not limited to, a null argument). That is, it would lead to the completed construction of an object that doesn't make sense.
Don't throw a NullPointerException, because you haven't attempted to call a method on something null yet.
From the IllegalArgumentException javadocs:
Thrown to indicate that a method has been passed an illegal or inappropriate argument.
And if null is inappropriate, then throw an IllegalArgumentException.
Yes, if null is not an acceptable value for rootRegion, etc., then throw NullPointerException from the constructor. From the NullPointerException documentation, where it talks about when the JVM will throw this, but also says:
Applications should throw instances of this class to indicate other illegal uses of the null object.
You could use IllegalArgumentException for the more general case of arguments that aren't valid for the constructor, but NullPointerException is exactly right for the case of an argument being null that ought not be. IllegalArgumentException does have the advantage, though, of being pretty darned clear about what's wrong. :-)
In this specific case I'd throw an IllegalArgumentException, which means a lot more to the user of your class than a NullPointerException.
It is not a bad practice to have constructors throw exceptions. However, you should make sure that they are well documented (especially in the case of runtime exceptions), and meaningful to the caller.

Choosing between NullPointerException and IllegalArgumentException for signalling error at object construction

I have a question about best practices in Java. I'm writing a class, which relies on an object at construction pretty heavily. In fact, if the object passed in at construction is null, most of the functionality wouldn't make sense. I thought it best to throw an exception in the case where null is passed as an argument at object construction, but I don't know what the most appropriate exception would be in this case. Should I throw a NullPointer, IllegalArgument, Instatiation, or even an Initialization exception.
I've seen these all used throughout the Java source codebase, and I don't seem to be able to distinguish why a NullPointer was used in some cases and IllegalArgument used in others. I personally would have thought that if a bad argument is passed in at construction, some initialization error should occur.
Firstly, you should absolutely throw an exception. It's simply the Right Thing To Do.
As for whether you should throw IllegalArgumentException or NullPointerException - Josh Bloch talks about this in Effective Java, and generally concludes that NullPointerException is a reasonable choice. I'm not entirely sure I agree (I would probably have picked IllegalArgumentException), but ultimately it's unlikely to matter: you shouldn't be catching either of these exceptions directly, and the stack trace will show you where there's a problem anyway.
(It's a shame Java doesn't have the equivalent to .NET's ArgumentNullException, which means exactly what it sounds like.)
Personally I'm a big fan of Guava's Preconditions class:
public class Foo {
private final Bar bar;
public Foo(Bar bar) {
this.bar = Preconditions.checkNotNull(bar);
}
}
(Sometimes used with a static import of checkNotNull.)
IllegalArgument makes it clear, to the developer who's used the code, what the problem is and how to fix it I would say. It also makes it clear that the method CANNOT work without that object.
NullPointer means they have to think a little bit about what the problem is (not much) and may mean the code is cleaner, but like I said above. It's not immediately clear, from a documentation point-of-view whether your code can work with a null value or not.
If you think the platform exceptions do not give the client the right amount of information to understand and fix the issue, you can create your own exception that's more appropriate in that regard, say like .NET's ArgumentNullException; which will tell the client both what the problem is and how to fix it.
NullPointerException is used when you are expecting a valid object but get null instead. This is especially pertinent when trying to call methods on a null object. This is the most common use for it. However, your case may also warrant it.
IllegalArgumentException is used when you received an argument into a method that is not what you expect or of the wrong type/style/etc. This, in my view, would be more appropriate in your case. You expect a valid object, but you received null as an argument. This argument value is invalid - so I would throw IllegalArgumentException and in the message of the exception specify what's wrong, e.g.:
public MyClass(InputObject obj) {
if(obj == null) {
throw new IllegalArgumentException("null passed to MyClass constructor");
}
...
}

Is it good practice to make the constructor throw an exception? [duplicate]

This question already has answers here:
When to throw an exception?
(33 answers)
Closed 4 years ago.
Is it a good practice to make the constructor throw an exception?
For example I have a class Person and I have age as its only attribute. Now
I provide the class as
class Person{
int age;
Person(int age) throws Exception{
if (age<0)
throw new Exception("invalid age");
this.age = age;
}
public void setAge(int age) throws Exception{
if (age<0)
throw new Exception("invalid age");
this.age = age;
}
}
Throwing exceptions in a constructor is not bad practice. In fact, it is the only reasonable way for a constructor to indicate that there is a problem; e.g. that the parameters are invalid.
I also think that throwing checked exceptions can be OK1, assuming that the checked exception is 1) declared, 2) specific to the problem you are reporting, and 3) it is reasonable to expect the caller to deal with a checked exception for this2.
However explicitly declaring or throwing java.lang.Exception is almost always bad practice.
You should pick an exception class that matches the exceptional condition that has occurred. If you throw Exception it is difficult for the caller to separate this exception from any number of other possible declared and undeclared exceptions. This makes error recovery difficult, and if the caller chooses to propagate the Exception, the problem just spreads.
1 - Some people may disagree, but IMO there is no substantive difference between this case and the case of throwing exceptions in methods. The standard checked vs unchecked advice applies equally to both cases.
2 - For example, the existing FileInputStream constructors will throw FileNotFoundException if you try to open a file that does not exist. Assuming that it is reasonable for FileNotFoundException to be a checked exception3, then the constructor is the most appropriate place for that exception to be thrown. If we threw the FileNotFoundException the first time that (say) a read or write call was made, that is liable to make application logic more complicated.
3 - Given that this is one of the motivating examples for checked exceptions, if you don't accept this you are basically saying that all exceptions should be unchecked. That is not practical ... if you are going to use Java.
Someone suggested using assert for checking arguments. The problem with this is that checking of assert assertions can be turned on and off via a JVM command-line setting. Using assertions to check internal invariants is OK, but using them to implement argument checking that is specified in your javadoc is not a good idea ... because it means your method will only strictly implement the specification when assertion checking is enabled.
The second problem with assert is that if an assertion fails, then AssertionError will be thrown, and received wisdom is that it is a bad idea to attempt to catch Error and any of its subtypes.
I've always considered throwing checked exceptions in the constructor to be bad practice, or at least something that should be avoided.
The reason for this is that you cannot do this :
private SomeObject foo = new SomeObject();
Instead you must do this :
private SomeObject foo;
public MyObject() {
try {
foo = new SomeObject()
} Catch(PointlessCheckedException e) {
throw new RuntimeException("ahhg",e);
}
}
At the point when I'm constructing SomeObject I know what it's parameters are
so why should I be expected to wrap it in a try catch?
Ahh you say but if I'm constructing an object from dynamic parameters I don't know if they're valid or not.
Well, you could... validate the parameters before passing them to the constructor. That would be good practice.
And if all you're concerned about is whether the parameters are valid then you can use IllegalArgumentException.
So instead of throwing checked exceptions just do
public SomeObject(final String param) {
if (param==null) throw new NullPointerException("please stop");
if (param.length()==0) throw new IllegalArgumentException("no really, please stop");
}
Of course there are cases where it might just be reasonable to throw a checked exception
public SomeObject() {
if (todayIsWednesday) throw new YouKnowYouCannotDoThisOnAWednesday();
}
But how often is that likely?
As mentioned in another answer here, in Guideline 7-3 of the Java Secure Coding Guidelines, throwing an exception in the constructor of a non-final class opens a potential attack vector:
Guideline 7-3 / OBJECT-3: Defend against partially initialized
instances of non-final classes When a constructor in a non-final class
throws an exception, attackers can attempt to gain access to partially
initialized instances of that class. Ensure that a non-final class
remains totally unusable until its constructor completes successfully.
From JDK 6 on, construction of a subclassable class can be prevented
by throwing an exception before the Object constructor completes. To
do this, perform the checks in an expression that is evaluated in a
call to this() or super().
// non-final java.lang.ClassLoader
public abstract class ClassLoader {
protected ClassLoader() {
this(securityManagerCheck());
}
private ClassLoader(Void ignored) {
// ... continue initialization ...
}
private static Void securityManagerCheck() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
return null;
}
}
For compatibility with older releases, a potential solution involves
the use of an initialized flag. Set the flag as the last operation in
a constructor before returning successfully. All methods providing a
gateway to sensitive operations must first consult the flag before
proceeding:
public abstract class ClassLoader {
private volatile boolean initialized;
protected ClassLoader() {
// permission needed to create ClassLoader
securityManagerCheck();
init();
// Last action of constructor.
this.initialized = true;
}
protected final Class defineClass(...) {
checkInitialized();
// regular logic follows
...
}
private void checkInitialized() {
if (!initialized) {
throw new SecurityException(
"NonFinal not initialized"
);
}
}
}
Furthermore, any security-sensitive uses of such classes should check
the state of the initialization flag. In the case of ClassLoader
construction, it should check that its parent class loader is
initialized.
Partially initialized instances of a non-final class can be accessed
via a finalizer attack. The attacker overrides the protected finalize
method in a subclass and attempts to create a new instance of that
subclass. This attempt fails (in the above example, the
SecurityManager check in ClassLoader's constructor throws a security
exception), but the attacker simply ignores any exception and waits
for the virtual machine to perform finalization on the partially
initialized object. When that occurs the malicious finalize method
implementation is invoked, giving the attacker access to this, a
reference to the object being finalized. Although the object is only
partially initialized, the attacker can still invoke methods on it,
thereby circumventing the SecurityManager check. While the initialized
flag does not prevent access to the partially initialized object, it
does prevent methods on that object from doing anything useful for the
attacker.
Use of an initialized flag, while secure, can be cumbersome. Simply
ensuring that all fields in a public non-final class contain a safe
value (such as null) until object initialization completes
successfully can represent a reasonable alternative in classes that
are not security-sensitive.
A more robust, but also more verbose, approach is to use a "pointer to
implementation" (or "pimpl"). The core of the class is moved into a
non-public class with the interface class forwarding method calls. Any
attempts to use the class before it is fully initialized will result
in a NullPointerException. This approach is also good for dealing with
clone and deserialization attacks.
public abstract class ClassLoader {
private final ClassLoaderImpl impl;
protected ClassLoader() {
this.impl = new ClassLoaderImpl();
}
protected final Class defineClass(...) {
return impl.defineClass(...);
}
}
/* pp */ class ClassLoaderImpl {
/* pp */ ClassLoaderImpl() {
// permission needed to create ClassLoader
securityManagerCheck();
init();
}
/* pp */ Class defineClass(...) {
// regular logic follows
...
}
}
You do not need to throw a checked exception. This is a bug within the control of the program, so you want to throw an unchecked exception. Use one of the unchecked exceptions already provided by the Java language, such as IllegalArgumentException, IllegalStateException or NullPointerException.
You may also want to get rid of the setter. You've already provided a way to initiate age through the constructor. Does it need to be updated once instantiated? If not, skip the setter. A good rule, do not make things more public than necessary. Start with private or default, and secure your data with final. Now everyone knows that Person has been constructed properly, and is immutable. It can be used with confidence.
Most likely this is what you really need:
class Person {
private final int age;
Person(int age) {
if (age < 0)
throw new IllegalArgumentException("age less than zero: " + age);
this.age = age;
}
// setter removed
This is totally valid, I do it all the time. I usually use IllegalArguemntException if it is a result of parameter checking.
In this case I wouldn't suggest asserts because they are turned off in a deployment build and you always want to stop this from happening, but they are valid if your group does ALL it's testing with asserts turned on and you think the chance of missing a parameter problem at runtime is more acceptable than throwing an exception that is maybe more likely to cause a runtime crash.
Also, an assert would be more difficult for the caller to trap, this is easy.
You probably want to list it as a "throws" in your method's javadocs along with the reason so that callers aren't surprised.
I have never considered it to be a bad practice to throw an exception in the constructor. When the class is designed, you have a certain idea in mind of what the structure for that class should be. If someone else has a different idea and tries to execute that idea, then you should error accordingly, giving the user feedback on what the error is. In your case, you might consider something like
if (age < 0) throw new NegativeAgeException("The person you attempted " +
"to construct must be given a positive age.");
where NegativeAgeException is an exception class that you constructed yourself, possibly extending another exception like IndexOutOfBoundsException or something similar.
Assertions don't exactly seem to be the way to go, either, since you're not trying to discover bugs in your code. I would say terminating with an exception is absolutely the right thing to do here.
I am not for throwing Exceptions in the constructor since I am considering this as non-clean. There are several reasons for my opinion.
As Richard mentioned you cannot initialize an instance in an easy manner. Especially in tests it is really annoying to build a test-wide object only by surrounding it in a try-catch during initialization.
Constructors should be logic-free. There is no reason at all to encapsulate logic in a constructor, since you are always aiming for the Separation of Concerns and Single Responsibility Principle. Since the concern of the constructor is to "construct an object" it should not encapsulate any exception handling if following this approach.
It smells like bad design. Imho if I am forced to do exception handling in the constructor I am at first asking myself if I have any design frauds in my class. It is necessary sometimes, but then I outsource this to a builder or factory to keep the constructor as simple as possible.
So if it is necessary to do some exception handling in the constructor, why would you not outsource this logic to a Builder of Factory? It might be a few more lines of code but gives you the freedom to implement a far more robust and well suited exception handling since you can outsource the logic for the exception handling even more and are not sticked to the constructor, which will encapsulate too much logic. And the client does not need to know anything about your constructing logic if you delegate the exception handling properly.
It is bad practice to throw Exception, as that requires anyone who calls your constructor to catch Exception which is a bad practice.
It is a good idea to have a constructor (or any method) throw an exception, generally speaking IllegalArgumentException, which is unchecked, and thus the compiler doesn't force you to catch it.
You should throw checked exceptions (things that extend from Exception, but not RuntimeException) if you want the caller to catch it.

Categories