Following the style used in Joshua Bloch's Effective Java and in agreement with the answers to this question, I've used AssertionErrors in the past in the Java SE environment for code paths that should never possibly be executed.
Looking at Java EE, the EJB 3.1 specification says
If the bean method encounters a system exception or error, it should simply propagate the error from the bean method to the container (i.e., the bean method does not have to catch the exception).
and a little further down, it says that the concerned EJB instance has to be discarded in the case of a non-ApplicationException. As far as I know, if another instance of that EJB is required in a subsequent request, the container takes one from the pool or creates a new one if necessary, so there should be no problems associated with that (except of course if it was a #Singleton EJB).
Is it appropriate/good style to use an AssertionError in a session bean method for indicating programming errors? Or is there a more fitting Throwable subtype for that?
I don't really see anything wrong in throwing an AssertionError. The container should be able to perform a rollback, just as it would for any unckecked exceptions.
Having said that, I never throw AssertionErrors myself. A couple of common examples where I would throw a subclass of RuntimeException, which is probably more appropriate than AssertionError, are:
Say we have an enum:
public enum TestEnum {
TEST1, TEST2;
}
I want to catch the default case, in this I throw an IllegalArgumentException:
public class TestClass {
public void doSomethingWithTestEnum(TestEnum testEnum) {
switch (testEnum) {
case TEST1:
// do something here
break;
case TEST2:
// do something here
break;
default:
throw new IllegalArgumentException("Unknown enum type: " + testEnum);
}
}
}
Another example would be parameter validation:
public class TestClass {
private String testString;
public TestClass(String testString) {
this.testString = Objects.requireNonNull(testString);
}
}
Here, a NullPointerException is thrown if testString is null.
There are probably cases where an assertion would be more suitable, but honestly I never encounter them.
Related
Let's say I have a class as below, as the class name suggests, this class doesn't allow auto commit.
So my question is that if it is better to leave it like below (empty body, maybe add some logging #WARN/ERROR level) or to throw UnsupportedOperationException?
public class NoAutoCommitConnection implements java.sql.Connection {
public void setAutoCommit(boolean autoCommit) throws SQLException {
}
}
I would actually go with if(autoCommit) { throw new UnsupportedOperationException(); }, since it clearly communicates that auto commiting is not supported, but won't fail setAutoCommit(false) calls.
Not implementing the method or rather it's intention breaks the contract of the interface.
I think the least you can do in such a situation is to throw an exception at runtime.
I have service, a simple class that need to take input and run some business logic. Before executing this service, the user must set all the data. In general, it look like this:
public class TestService extends InnerServiceBase {
/**
* Mandatory input
*/
private Object inputObj;
#Override
protected ErrorCode executeImpl() {
//Some business logic on inputObj
return null;
}
public void setInputObj(Object inputObj) {
this.inputObj = inputObj;
}
}
What is the best runtime exception to throw in case the inputObj is null ?
IllegalStateException seems like the best fit. The object is not in the correct state to have executeImpl() called on it. Whatever exception you use, make sure the error message is helpful.
Whether you should be using an unchecked exception at all is a whole other question...
Depends on the scenario.
If this is part of an API that another developer is using, throwing NullPointerException is reasonable since you don't want that input to be null. Adding a descriptive exception message would be helpful.
If you're not interested in throwing an NPE, or this is part of code that's not going into an API, then you could throw an IllegalArgumentException, as null could be considered an illegal argument.
If setInputObj is called with a null argument, and that's not valid, then throw NullPointerException. There's some debate over the "correct" exception here (IllegalArgumentException or NullPointerException for a null parameter?), but Guava, Apache Commons Lang and even the JDK itself (Objects.requireNonNull) have settled on NPE.
If executeImpl is called before inputObj has been set, throw IllegalStateException.
So I have a pretty big java application that I wrote a year ago and I'm trying to understand it again. I'm looking at a method in the code where there is an obvious risk of getting NoSuchElementException: I'm calling .next() on a scanner variable that has been constructed with an arbitrary string. The only thing the method is declared to throw are custom made subclasses of Exception. The risky command isn't written in a catch-block either. The code compiles and works fine and when I use my gui in such a fashion that it should throw a NoSuchElementException nothing happens :O
As a test I wrote a catch-block into the code, compiled it, ran the gui and made it throw NoSuchElementException again and the application successfully caught the exception and acted accordingly. How is it that I can compile the code without specifying the this exception may be thrown? If it's any use at all, here is the code without the catch-block:
public static Expression interpret(final Scanner scanner)
throws
InvalidPosition,
NoSuchSpreadsheet,
IllegalStartOfExpression,
InvalidExpression,
FalseSyntax,
InvalidRange {
String keyword = null;
try {
keyword = scanner.next();
} catch (NoSuchElementException e) {
throw new IllegalStartOfExpression();
}
switch(keyword) {
case "Get":
Position pos = PositionInterpreter.interpret(scanner.next());
Expression expression = Application.instance.get(pos);
if (expression instanceof Text) {
System.out.println("Failure");
} else { System.out.println("Success"); }
return new Text(expression.toString());
case "Int":
return new Int(
scanner.nextInt());
As you can see, the method simply assumes that there is more than one word in the scanner after checking if there is at least the one. How am I getting away with compiling this?
It is be cause NoSuchElementException is unchecked exception, which means that it "is-a" RuntimeException which does not force you to catch.
The unchecked exceptions classes are the class RuntimeException and its subclasses, and the class Error and its subclasses. All other exception classes are checked exception classes. The Java API defines a number of exception classes, both checked and unchecked. Additional exception classes, both checked and unchecked, may be declared by programmers. See ref for a description of the exception class hierarchy and some of the exception classes defined by the Java API and Java virtual machine.
Runtime exceptions serve the same purpose as checked exceptions; to communicate exceptional conditions (unexpected failures, etc) to the user.
checked exception forces the caller of a method to handle that exception, even if they do not know how to handle it. Often times, developers will end up catching the checked exception, only to re-throw it (or another exception). Hence the Runtime exceptions
Here is the exception hierarchy
As the question has already been answered, I'd like to point on that this is very poor design and not the intended usage of the Scanner class:
try {
keyword = scanner.next();
} catch (NoSuchElementException e) {
throw new IllegalStartOfExpression();
}
What you should really be doing is ask the scanner whether there is any input, and only then retrieving it, like so:
if(scanner.hasNext()) {
keyword = scanner.next();
}
else {
throw new IllegalStartOfExpression();
}
The same applies to the line which is causing your problem:
if(scanner.hasNextInt()) {
return new Integer(scanner.nextInt());
}
java.util.NoSuchElementException is a subclass of java.lang.RuntimeException. RuntimeExceptions don't have to be handled. From the Java API documentation:
RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine.
RuntimeException and its subclasses are unchecked exceptions. 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.
Requirements:
Section is created by selecting one teacher, one subject and one
schedule.
System verifies that all business rules are followed.
System detects that a business rule is not being followed.
System informs user of conflict.
System doesn't create new section.
3.System creates new section.
My problem is, if I define a constructor for section, Section(Teacher t, Subject s, Schedule c), I don't know how to return the error message for the conflict.
Should I just let my constructor throw an exception? If yes, how to return a string from a caught exception? How to create that exception?
Or is there any better, yet simple, implementation?
Reporting constructor failure boils down to two options:
Throw an exception as you suggest. This is a reasonable approach if failure is not expected to happen often and is truly "exceptional".
If failure is a normal part of the business logic, I'd recommend using the Factory pattern and returning a wrapper object that contains the newly created object plus a status variable that can indicate the detailed causes of the failure when it occurs.
You can throw the exception for sure.
throw new Exception("Some required files are missing");
Or create a new Exception to be used in your app (it will work the same way)
If you want to read the message inside of a try / catch statement just do this:
try
{
// ...
}
catch(Exception ex)
{
System.out.println(ex.getMessage()); //this will get "Some required files are missing"
}
For more information checke these links out:
http://en.wikibooks.org/wiki/Java_Programming/Throwing_and_Catching_Exceptions
How to throw a general exception in Java?
http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#getMessage()
It isn't possible to return a value from a constructor. Your only way to do this is to throw an exception of some sort. You can either use an existing exception type (if there are any applicable) or create your own by extending Exception. For example:
public class MyException extends Exception {
public MyException(){
super();
}
public MyException(String message){
super(message);
}
}
Your constructor would simply throw a new instance of the exception and set an appropriate message. The code creating the class instance would catch the exception and handle it. You can obtain the message at that point by calling getMessage().
I'm pondering on exception handling and unit tests best practices because we're trying to get some code best practices in place.
A previous article regarding best practices, found on our company wiki, stated "Do not use try/catch, but use Junit4 #Test(expect=MyException.class)", without further information. I'm not convinced.
Many of our custom exception have an Enum in order to identify the failure cause.
As a result, I would rather see a test like :
#Test
public void testDoSomethingFailsBecauseZzz() {
try{
doSomething();
} catch(OurCustomException e){
assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ, e.getFailure());
}
}
than :
#Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
doSomething();
}
when doSomethig() looks like :
public void doSomething throws OurCustomException {
if(Aaa) {
throw OurCustomException(FailureEnum.AAA);
}
if(Zzz) {
throw OurCustomException(FailureEnum.ZZZ);
}
// ...
}
On a side note, I am more than convinced that on some cases #Test(expected=blabla.class) IS the best choice (for example when the exception is precise and there can be no doubt about what's causing it).
Am I missing something here or should I push the use of try/catch when necessary ?
It sounds like your enum is being used as an alternative to an exception hierarchy? Perhaps if you had an exception hierarchy the #Test(expected=XYZ.class) would become more useful?
If you simply want to check that an exception of a certain type was thrown, use the annotation's expected property.
If you want to check properties of the thrown exception (e.g. the message, or a custom member value), catch it in the test and make assertions.
In your case, it seems like you want the latter (to assert that the exception has a certain FailureEnum value); there's nothing wrong with using the try/catch.
The generalization that you should "not use try/catch" (interpreted as "never") is bunk.
Jeff is right though; the organization of your exception hierarchy is suspect. However, you seem to recognize this. :)
If you want to check the raw exception type, then the expected method is appropriate. Otherwise, if you need to test something about the exception (and regardless of the enum weirdness testing the message content is common) you can do the try catch, but that is a bit old-school. The new JUnit way to do it is with a MethodRule. The one that comes in the API (ExpectedException) is about testing the message specifically, but you can easily look at the code and adapt that implementation to check for failure enums.
In your special case, you want to test (1) if the expected exception type is thrown and (2) if the error number is correct, because the method can thrown the same exception with different types.
This requires an inspection of the exception object. But, you can stick to the recommendation and verify that the right exception has been thrown:
#Test(expected = OurCustomException.class)
public void testDoSomethingFailsBecauseZzz() {
try {
doSomething();
} catch (OurCustomException e) {
if (e.getFailureEnum.equals(FailureEnum.ZZZ)) // use *your* method here
throw e;
fail("Catched OurCostomException with unexpected failure number: "
+ e.getFailureEnum().getValue()); // again: your enum method here
}
}
This pattern will eat the unexpected exception and make the test fail.
Edit
Changed it because I missed the obvious: we can make a test case fail and capture a message. So now: the test passes, if the expected exception with the expected error code is thrown. If the test fails because we got an unexpected error, then we can read the error code.
I came across this when searching how to handle exceptions.
As #Yishai mentioned, the preferred way to expect exceptions is using JUnit rules and ExpectedException.
When using #Test(expected=SomeException.class) a test method will pass if the exception is thrown anywhere in the method.
When you use ExpectedException:
#Test
public void testException()
{
// If SomeException is thrown here, the test will fail.
expectedException.expect(SomeException.class);
// If SomeException is thrown here, the test will pass.
}
You can also test:
an expected message: ExpectedException.expectMessage();
an expected cause: expectedException.expectCause().
As a side note: I don't think using enums for exception messages/causes is good practice. (Please correct me if I'm wrong.)
I made catch-exception because I was facing the same problem as you did, Stph.
With catch-exception your code could look like this:
#Test
public void testDoSomethingFailsBecauseZzz() {
verifyException(myObj, OurCustomException.class).doSomething();
assertEquals("Omg it failed, but not like we planned", FailureEnum.ZZZ,
((OurCustomException)caughtException()).getFailure() ;
}