I am currently implementing a system in which I am using aspectJ to check whether a user is allowed to call a method or not. My methods look something like this:
#Constrained(
mayUsers = {Constrained.Types.ADMIN,
Constrained.Types.SELLER, Constrained.Types.ORGANIZER}
)
public boolean save() {
/* code */
}
I am able to use AspectJ to intercept the message call and do the check, but if the call is not allowed I want to throw an exception. If I just throw the Exception the user of the method is not informed about the Exception which might be thrown.
Now my question is:
Is it possible to enforce that the every method that has the #Constrained Annotation throws a specific Exception?
Is it possible to enforce that the every method that has the
#Constrained Annotation throws a specific Exception?
No it is not possible to do that right now. But what you can do is that at runtime you can check that all the methods that have this annotation must throw exception. If any of method does not declare throws clause, you can throw some Illegal*Exception to tell the developer that each method must declare throws clause.
You have two solutions:
Compile time annotation checking using APT (Annotation Processing Tool)
Runtime checks (pre-conditions)
Related
I have the following code:
public User getUserById(Long id) {
checkUserExists(id);
return repo.findOne(id);
}
private void checkUserExists(Long id) {
if (id == null || !repo.exists(id)) {
throw new NoUserFoundException("No User exists with id: " +id);
}
}
According to Oracle:
"Unchecked exceptions do not need to be declared in a method or constructor's throws clause if they can be thrown by the execution of the method or constructor and propagate outside the method or constructor boundary."
Do I have to describe the exception anyway in the JavaDoc (Without the #throws clause, but only describe?) What is the best way to describe such an unchecked exception in JavaDoc?
You are writing Javadoc for the user of your method. If it's useful for that user to know that it may throw an exception, document it!
In your case, it seems that it is indeed useful for the user to know that a NoUserFoundException is thrown if the user is not found.
In other cases it's less useful. For example, in many cases the fact that a NullPointerException is thrown if a parameter is null is not documented in the Javadoc because it's often somehow implied that a parameter cannot be null.
By the way, Oracle is talking about the throws class appearing after the method declaration, not about the Javadoc. If you decide to document a non-checked exception, it makes sense to use the #throws clause.
I have inherited some code from another team which uses
#Test (expectedExceptions = {Exception.class})
everywhere when the code might be throwing a more specific exception.
My understanding is that this is wrong because we are not expecting the right type of exception. But the current owners are saying that they have seen no issue because of this.
Is my understanding correct?
This is poor design, since it could be masking errors other than the one being tested for. As an example, suppose your code should throw a SecurityException on some operation but instead is throwing a NullPointerException because of a naive dereference. Your test would pass when it should fail.
You should always make your matchers as specific as possible, and in this case, that means the most specific exception class that applies.
Exception is Parent class of all types of exception in java, so basically your test will pass if code throws any checked or unchecked exception. But its better to write unit test that will expect a particular type of exception which your code can throw. For e.g. let say your have a method to validateParam
public void validateParam(String param) throws SomeCustomValidationException {
//suppose param is null , now this code will throw NullPointerException
if (param.length() > 2) {throw new SomeCustomValidationException();}
}
and you call it like this
public void businessLogic(String param) {
try {validateParam(param);}
catch(SomeCustomValidationException e){//show error dialog to the user}
}
So although your unit test will pass but your business logic will not work as you expected
Say I have a system property MY_PROP:
java -DMY_PROP="My value"
This property is necessary for my system to work.
What is the right exception to throw if this property is not set?
#PostConstruct
private void init() {
myProp = System.getProperty("MY_PROP");
if (myProp == null) {
throw new ????
}
// ...
}
Somehow IllegalArgumentException does not feel right. Maybe IllegalStateException, MissingResourceException, TypeNotPresentException? What is the standard practice for this scenario?
There is none. I would throw the IllegalStateException, because you are missing the parameter. This mean that configuration validator has failed and your application is in invalid state. In other words you should never be able to call the init() at all.
In case the value of parameter would be invalid, then i would throw an IllegalArgumentException.
If you are writing a validator, you should decide between using RuntimeException or checked one. When using for example javax.naming.ConfigurationException`, or created own one configuration exception. You API will be able to handle such exception and react properly in term of legacy.
Definitions:
IllegalStateException - Signals that a method has been invoked at an illegal or inappropriate time. In other words, the Java environment or Java application is not in an appropriate state for the requested operation.
IllegalArgumentException - Thrown to indicate that a method has been passed an illegal or inappropriate argument.
I only add to Vash's answer for the Spring Framework. If your using the Spring Framework and you want to be consistent with how most of the components in Spring do it then I would say you should use IllegalStateException (or your own derivation).
In Spring most components that do a #PostConstruct or #Override void afterPropertiesSet() throw IllegalStateException using the util org.springframework.util.Assert.state(..).
You can see this done in Spring AMQP as one example.
That being said I have actually filed bugs against Spring MVC where they used IllegalArgumentException instead of a custom and more explicit derived class. With static inline classes its very easy to create a custom exception with out creating another Java file.
Because a system property is not always defined, the standard pratice is to use a default value when you can't find the property.
I just checked some standard code in java 7 (apache tomcat, java.lang, java.awt, ...), they always use a default "fallback" when the property is null.
So maybe your problem is somewhere else ?
Why don't you take this parameters as a required argument of your jar ? Then you can use IllegalArgumentException.
I was playing around with some of my code and came across something I didn't fully understand. I have a class called SentimentClassifier, the constructor of which looks like this:
public SentimentClassifier(final int nGramToBeUsed) {
try {
classifier = (DynamicLMClassifier<?>) AbstractExternalizable.readObject(new File(etc));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
I have another class which creates this one, like so:
public TwitterManager(final int nGramToBeUsed) {
sentimentClassifier = new SentimentClassifier(nGramToBeUsed);
}
If I run the code like this, everything works fine. But if I change the first class from using try/catch to throw the exception, like so:
public SentimentClassifier(final int nGramToBeUsed) throws ClassNotFoundException, IOException {
classifier = (DynamicLMClassifier<?>) AbstractExternalizable.readObject(new File(etc));
}
Suddenly the second class complains that the IOException isn't being handled. Why is this thrown only for the thrown exception and not for the try/catch?
When you call a method M1 from another method M2:
If some code in M1 raises some Checked Exception, and the method M1 itself handles it, rather than throwing it, you don't have to worry about the exception while calling it.
Now, if the exception raised in M1, is not being handled in M1 itself, rather it is propagated up the stack trace, then M1 must declare that exception in the throws clause. This is just for the convenience of the calling method to know that it should be ready to handle those exception in case they are thrown. This is only the case with Checked Exception.
But if the calling method M2, doesn't handle that exception, it has the option to re-declare that exception to be thrown in it's own throws clause, in which case the exception will be propagated further up the stack trace.
If method M2 does neither of the previous two task, you will get a compiler error. Because you haven't given any proper path or way to handle the exception that can be thrown.
Note all the above arguments are true for Checked Exception only. For Unchecked exception, you don't need to handle it yourself, neither you need to declare it in throws clause.
Suggested Read:
Java: checked vs unchecked exception explanation
Unchecked Exception controversies
JLS - The Kinds and Causes of Exceptions
In Java, if a method declares that throws an Exception (other than RuntimeException), callers must handle the exception. They can do this one of two ways: catch it, or declare that they themselves throw it.
You moved the handling of these two exceptions from the SentimentClassifier constructor to its callers.
If the constructor declares any exceptions, the calling code must handle them or declare them. After all, the constructor could throw/propagate these exceptions, and any code that calls it must handle them.
When you catch an exception, it means that you will deal with it on the catch block, and its consequences, so the external code can continue to progress without being warned about the internal exception.
If your exception is thrown, you are forcing by contract to any creator/invoker class to deal with any declared exception that could be produced during the initialization/execution process, as it can be critical for the business logic.
In this case, if the exceptions that can be generated during init are critical, and could stop the class from working properly, they should be thrown, as the creator class TwitterManager could have a disfuncional or partially initialized instance of the SentinelClassifier object, leading to unexpected errors.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Throws or try-catch
I'm writing an API and I wish to write code such that I can raise an exception in a particular scenario. I've created an exception class as follows :-
public class InvalidSeverityException extends Exception {
private static final long serialVersionUID = 1L;
public InvalidSeverityException() {
// TODO Auto-generated constructor stub
}
}
In the codebase im having the following to call the code :-
throw new InvalidSeverityException();
However Eclipse suggests that I either use throws or enclose it within a try ... catch block. I feel that I shouldn't be catching this error and that the developers who use my API should enclose the code within try...catch.
Does that make sense? Am I doing something wrong?
When handling with exceptions in Java you must understand the concept of checked exceptions and unchecked exceptions.
In your case currently you are defining a checked exception, maybe you want an unchecked one.
Here's a brief description about each one of the types:
Checked Exceptions
This exceptions must be part of the method's signature that raises them (or that invokes one method that does) or you must catch them with a try catch block and deal with the problem. Usually checked exceptions are used when there is something that can be done about the error and also when you want the developer to be aware that such error may occur and that has to be handled.
In java java.lang.Exception is a checked exception and all its subclasses will also be checked.
Unchecked Exceptions
This exceptions on the other hand don't need to make part of the method signature, nor you have to wrap methods that throw new in a try catch block. It's just expected that somewhere in the call stack there will be a try catch to handle it, otherwise if it reaches the JVM it will nicely dump you a stacktrace.
In java java.lang.RuntimeException is an unchecked exception and so are all its subclasses.
My opinion
If you are defining an API my suggestion is to use checked exceptions, this is mostly because you explicitly inform the developers using your API that such an exception might occur (so they can handle it anyway they want).
You are correct, you should not catch it. As suggested by eclipse, you should use throws so that the developers will know that your method potentially throws that exception and can then catch it.
.... method() throws YourException{
The method where you have throw new InvalidSeverityException(); should define throws InvalidSeverityException
Example:
void yourMethod() throws InvalidSeverityException
{
........//Some code
throw new InvalidSeverityException();
}
Well then surely you follow the first suggestion by Eclipse and set your method to throw the exception.
public void myMethod() throws InvalidSeverityException {
//throw it somewhere in here so that other
//developer can catch it while calling your method
}