Why doesn't EJBException use Throwable.cause? - java

Quite for a long time I'm wondering why doesn't EJBException use standard Throwable.cause field to reach an exception it wraps?
It complicates getting the original root cause to something like that
private String getRootCauseErrorMessage(final Exception ex) {
Throwable currentException = ex;
Throwable nextException = null;
do {
if (nextException != null) {
currentException = nextException;
}
/* For some reason EJBException stores cause in a separate field rather the all generic Throwables */
if (currentException instanceof EJBException) {
nextException = ((EJBException) currentException).getCausedByException();
} else {
nextException = currentException.getCause();
}
} while (nextException != null);
return currentException.getMessage();
}
ps: I'm on Java6 and EJB3

Throwable.getCause was not added until Java 1.4. Some implementations of EJBException do retrofit the getCausedByException method to use the getCause method (similar to how the RemoteException.getCause method was retrofitted), but it sounds like your application server does not do this.

Related

Is this a redundant NullPointerException catch?

Below Spring REST code returns List for a given ticketId.
Could a NullPointerException be thrown in this code ?
NullPointerException explicitly caught in TicketController:
catch (NullPointerException nullPointerException) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, nullPointerException.getMessage(), nullPointerException);
}
The thinking may have been when checking for null on the ticket id:
if (ticketId == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ticket id cannot be null");
}
the expectation is that a NullPointerException would be thrown but instead a ResponseStatusException is thrown ?
If the variable ticketId is a path parameter it can never be null as hit the base url / without a ticketId I receive:
There was an unexpected error (type=Method Not Allowed, status=405).
Entire source:
#RestController
public class TicketController {
private final TicketServiceImpl ticketServiceImpl;
public TicketController(TicketServiceImpl ticketServiceImpl) {
this.ticketServiceImpl = ticketServiceImpl;
}
#GetMapping(path = "/{ticketId}")
public ResponseEntity<List<TicketResponse>> getTicketsById(
#PathVariable("ticketId") final Long ticketId) {
try {
final List<TicketResponse> ticketsById = ticketServiceImpl.getAll(ticketId);
return new ResponseEntity<>(ticketsById, HttpStatus.OK);
}
catch (NullPointerException nullPointerException) {
throw new ResponseStatusException(
HttpStatus.BAD_REQUEST, nullPointerException.getMessage(), nullPointerException);
}
catch (TicketNotFoundException ticketNotFoundException) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Ticket id not found",
ticketNotFoundException);
}
}
}
#Service
public class TicketServiceImpl implements TicketService {
private final TicketRepository ticketRepository;
public TicketServiceImpl(TicketRepository ticketRepository) {
this.ticketRepository = ticketRepository;
}
#Override
public List<TicketResponse> getAll(Long ticketId) {
final List<TicketResponse> ticketResponselist = ticketRepository.findData(ticketId);
if (ticketId == null) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "ticket id cannot be null");
}
else if (ticketResponselist.size() == 0) {
throw new TicketNotFoundException("ticket not found");
}
else {
return ticketResponselist;
}
}
}
#Repository
public interface TicketRepository {
public List<TicketResponse> findData(Long ticketId);
}
The if (ticketId == null) check should happen before the ticketRepository.findData(ticketId); is called.
Otherwise, the validation doesn't make sense.
Also, as a side note, catching NullPointerException is a bad practice. The reason is that having a null pointer exception thrown is mostly a sign of a coding smell. The code should be null-safe, by either using e.g. Optional or having a proper validation at the method level. In this case, it would be at the route level (which is the external input). From that point onward, if the validation is set, you're dealing with non nullable id.
This is also somehow related to returning null from a method, which is also a bad practice, since it requires a check in every method which then uses the returned value. This would pollute the code, will introduce a new level of abstraction, and will generally lead to nasty bugs.
NullPointerException check is not required in this case.
Side note : Its better to use the super type when passing as a method parameter until and unless you are pretty sure that no exception will be thrown instead of yours.

Java, what if I want to return different types from function?

public WHATTOWRITEHERE test()
{
try
{
transaction.begin();
code which may trigger exception
transaction.commit();
return true;
}
catch (javax.script.ScriptException ex)
{
transaction.rollback();
return ex.getMessage();
}
}
the code above intend to do something, if its OK then return true if not (error happened), this error message string should be returned. It do possible with Php but not with Java
EDIT: expection cant go outside, it has to be handled right here.
You can't return multiple types but you can redesign so you don't have to. Some possibilities:
Don't return an error message. Throw or rethrow an exception instead and let the caller handle it.
Create some class that can encapsulate a success and error state and all related info, return an instance of that.
I recommend option 1. You're already handling an exception, you can see its use for it error handling. No reason to stop it in its tracks there, handle any local cleanup then keep it going up to the caller.
Some hastily constructed examples now that I'm back at a keyboard, intended only to illustrate concepts, not to be exhaustive or necessarily used verbatim:
Cleanup then rethrow:
public boolean test () throws javax.script.ScriptException {
try {
transaction.begin();
...
transaction.commit();
return true;
} catch (javax.script.ScriptException ex) {
transaction.rollback();
throw ex;
}
}
Clean up then rethrow a different exception type if needed:
public boolean test () throws MyGreatException {
try {
transaction.begin();
...
transaction.commit();
return true;
} catch (javax.script.ScriptException ex) {
transaction.rollback();
throw new MyGreatException(ex);
}
}
Return an object that provides status information (this is just a quick example of the general idea):
public class TransactionResult {
private final boolean failed;
private final String reason;
/** Construct a result that represents a successful transaction. */
public TransactionResult () {
failed = false;
reason = null;
}
/** Construct a result that represents a failed transaction with a reason. */
public TransactionResult (String failedReason) {
failed = true;
reason = failedReason;
}
public boolean isFailed () {
return failed;
}
public String getReason () {
return reason;
}
}
And then:
public TransactionResult test () {
TransactionResult result;
try {
transaction.begin();
...
transaction.commit();
result = new TransactionResult();
} catch (javax.script.ScriptException ex) {
transaction.rollback();
result = new TransactionResult(ex.getMessage());
}
return result;
}
Etc.
Don't return anything. Just re-throw the original exception after you roll-back.
public void test()
{
try
{
transaction.begin();
code which may trigger exception
transaction.commit();
}
catch (javax.script.ScriptException ex)
{
transaction.rollback();
throw ex; // re-throw the original exception
}
}
If you insist, you can return Object. In that case, true will be autoboxed to Boolean.TRUE. It’s certainly not recommended, and it will give the caller some extra trouble figuring out whether the returned object is a String or a Boolean. To make matters worse, the caller has no guarantee that return types are limited to the mentioned two, but should also take into account that it could be yet another class.
Better options depend on the situation, so I probably cannot tell you what’s best. A couple of ideas spring to mind, but please don’t use uncritically: (1) Return String, and return null instead of true on success. (2) Design your own return class; for instance, it may hold both a boolean and a message string.
UGLY Workaround but if you really want to do this you can always define a Helper class which wraps status and Error Message, but I would prefer #JsonC's approach.
// Helper class
class Pair<First,Second>{
private First first;
private Second second;
Pair(First first,Second second){
this.first = first;
this.second = second;
}
public First getFirst(){ return this.first; }
public First getSecond(){ return this.second; }
}
// Function returning two types
public Pair<boolean,String> returnSomething(){
try {
return new Pair<boolean,String>(true,null);
}catch(Exception e){
return new Pair<boolean,String>(false,e.getMessage());
}
}
// Calling this method would look like this
Pair<String,boolean> result = returnSomething();
// Retrieve status
boolean status = result.getFirst();
// Retrieve error message (This is null if an exception was caught!)
String errorMessage = result.getSecond();
Exceptions can't go outside, it has to be handled here.
I must say this restriction can only make the interface more difficult to use. Assume you want to return something for the caller to check whether an exception happened in this method, while the caller can ignore the returned value no matter what. So I guess you want to give the caller some flexibility: that he/she doesn't need to bother with the final result if possible. But with the exception approach the caller can still do that, with empty (not recommended) catch clauses.
Exception is the best approach here. Unless "outside" is an environment where exceptions are not supported. Then you have no choice but to come up with something like Try in Scala.
In your case, exceptions should probably be used, not hidden. It's not a result but an error. Learn how to do exception handling in transactions!
Functional programming fanboys will advocate a Monad-like structure, as you can find in the Optional<T> API of Java 8.
I.e. you could return Optional<String> and leave it unset on success (if you do not have a return false and a return true).
For clarity it would be better to build something like this instead with custom classes:
interface Result {}
class BooleanResult implements Result {
boolean result;
public boolean getResult() { return result; }
}
class ErrorResult implements Result {
Exception cause;
public Exception getCause() { return cause; }
}
You could emulate Optional with null values (if you have only one boolean result). On success, return null. Non-null values indicate errors.
String perform() {
try{
...
return null; // No error
} except(Exception e) { // bad code style
return e.getMessage(); // Pray this is never null
}
}
String err = perform();
if (err != null) { throw up; }
Similar APIs are fairly common in old C libraries. Any return value except 0 is an error code. On success, the results are written to a pointer provided at the method call.
You could use Object.
public Object perform() {...}
Object o = perform();
if (o instanceof Boolean) { ...
This is 1980s programming style. This is what PHP does, so it actually is possible in Java! It's just bad because it is no lpnger type safe. This is the worst choice.
I suugest your try 1., 3., 2., 4., 5. in this preference. Or better, only consider the options 1 and 3 at all.
As for option 1. you really should learn how to use try-with-resources. Your transaction is a resource.
When done right, your code will look like this:
try(Transaction a = connection.newTransaction()) {
doSomethingThatMayFail(a);
a.commit();
} // No except here, let try handle this properly
Java will call a.close() even if an exception occurs. Then it will throw the exception upwards. Sour transaction class should have code like this to take care of the rollback:
public void close() {
if (!committed) rollback();
}
This is the most elegant and shortest and safe-to-use approach, as Java ensures close() is called. Throw the Exception, then properly handle it. The code snipped you showed above is an anti-pattern, and known to be very error prone.
If you are using Java 8 you could return an Optional<String>. Then if the code succeeds you return an empty Optional and if there is a failure you return an optional wrapping the failure message.

Throwing exceptions through components, good practice?

When a sub method throws an exception, would encapsulation in a dedicated "package" exception be considered good pratice ?
public String doStuff() throws UtilsException {
try {
throw new NullPointerException("test");
} catch (NullPointerException e) {
throw new UtilsException("something occured", e);
}
}
//use this exception for all classes of this package / component
public class UtilsException extends Exception {
private static final long serialVersionUID = 1L;
public UtilsException() {
super();
}
public UtilsException(String message, Throwable cause) {
super(message, cause);
}
public UtilsException(String message) {
super(message);
}
public UtilsException(Throwable cause) {
super(cause);
}
}
Could Optional.empty() be an alternative to avoid throwing/catching of a complex app?
public Optional<String> doStuff() throws UtilsException {
try {
return Optional.of("ok");
} catch (NullPointerException e) {
LOG.error("Something append... {}", e.getMessage());
return Optional.empty();
}
}
First, you should never catch a NullPointerException (or runtime exceptions in general) an return someting else like you are doing.
Ok, maybe there are a very few cases where you need to do that (like a buggy third party api).
Exceptions like those (NullPointer, ClassCast, IllegalArgument, ect) happen when your program has a bug and you should let
them bubble up and handle them in some high order component of your program.
That being said, (and there comes the infamous phrase) it depends...
Exceptions are "responsible" for informing errors,thus they need to be informative for the caller will use them to decide what to do. Consider the following:
public void readFile(String path) throws IOException {
// read file content
return content;
}
try {
return readFile("foo.txt");
} catch(FileNotFound e) {
// For this specific scenario not finding the file is not a problem
return "";
} catch(IOException e) {
// This we are not expecting to happen, if the file exists we should be
// able to read it, otherwise we should inform the user.
log.error(e);
display("We had a problem reading the file, Check the file permissions and try again");
}
As you can see in the example above, you won't want to wrap the IOException in another exception in this case
because you will remove the client's ability to decide what to do when an error happened.
Also, note that the IOException is a form of "wrap" since exceptions are objects too you can use inheritance
to generalize what kind of errors your method throws and then throw more specific errors so the caller can
decide what to do.
When to wrap.
There are cases when wrapping exceptions is a good practice and is the way to go.
For example, if you are creating a lib whose main functionality is to get weather information.
For the first version you kept it simple and used a third party api to get the values for the day.
The main method of your api looks like this.
public Weather getWeather(Date day) throws HTTPException {
return weather.get(day);
}
Your api is doing pretty well but you noticed you're doing too much requests to the weather api and
you will have to start paying for it very soon. You then decided to cache the results in a database table
so you can reduce the amount of requests.
public Weather getWeather(Date day) throws HTTPException, SQLException {
Weather w = getFromCache(day);
if (w != null) {
return w;
} else {
return getAndCache(day);
}
}
Now you have a problem, you can't add this new exception to the throws statement because you will most certainly break
your api's users code.
And if you think about it, your api's users are no interested if you had problems getting the data from the wheter api or
from your cache, they just want to be informed of errors. This is a very good case to wrap those exceptions in
a more generic one, like WeatherFetchException.
As you can see, it really depends...
The rule of thumb to me is, keep your exceptions meaningful and if you want to wrap them, do only when
it makes sense and when it doesn't remove the caller's ability to handle errors.
Wrapping exceptions just for the sake of it is most definitely not a good practice.

Where can I add exception handling in a Java class definition?

So, I had to create two files. One is a class definition. The other one uses the class' methods/fields.
(Artifact.java) Artifact Class definition:
public class Artifact {
int artNumber;
String arcName;
String artType;
int artYear;
double artWeight;
Artifact(int artNumber, String arcName, String artType, int artYear,double artWeight) {
this.artNumber = artNumber;
this.arcName = arcName;
this.artType = artType;
this.artYear = artYear;
this.artWeight = artWeight;
}
public void changeArtYear(int x) {
this.artYear = x;
}
public void changeArcName(String x) {
this.arcName = x;
}
public int getArtNumber() {
return artNumber;
}
public String getArcName() {
return arcName;
}
public String getArtType() {
return artType;
}
public int getArtYear() {
return artYear;
}
public double getArtWeight() {
return artWeight;
}
public String toString(){
return("The artifact #"+artNumber+" was discovered by "+arcName+". The artifact is made of "+artType+" and was discovered in "+artYear+". The artifact weighs "+artWeight+" kilograms.");
}
}
(ArtifactTester.java) Testing methods:
public class ArtifactTester {
public static void main(String[] args){
Artifact test = new Artifact(88888888,"ben","clay",1624,46.4);
System.out.println(test.toString()); //toString()
System.out.println(test.getArtWeight()); //getArtWeight()
System.out.println(test.getArtYear()); //getArtYear()
System.out.println(test.getArtType()); //getArtType()
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtNumber()); //getArtNumber()
test.changeArcName("zack");
test.changeArtYear(1400);
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtYear()); //getArtYear()
}
}
Anyways, my teacher to told me to add exception handling, but I am not sure where I would add exception handling.
Question: Is it possible to use exception handling in this situation?
Well to be blunt. Yes. Of course. You can use exception handling wherever and whenever you please (most of the time). Although, in this specific case I don't really see a good reason for it. But, I'll take your word for the need.
Now, as for where to handle exceptions, this is up to you. You can add exception handling in one of two places. You can either add exception handling when you call the methods like this:
try { //try executing a block of code which may throw exception
test.toString()
}
catch(Exception e) { //use Exception for all types of exceptions, or make it specific
//do something here if the exception is thrown
}
or you can excpetion handle in the methods themselves like so:
public void changeArtYear(int x) {
try{
this.artYear = x;
}
catch(Exception e){ //catch the exception that could be thrown
//do something
}
}
This should do the trick in your case if you want to add exception handling here. However, I would strongly urge you to learn exception handling and the different exceptions in Java, it is one of the most improtant fundamentals to programming in this language.
Also, let me point this out again: In this program, there is really no need to use exception handling except for practice. There is nothing here that would throw an exception for any reason. (Except maybe a NullPointerException if you passed a null parameter through one of your method calls)
Good Reference/Tutorial:
http://www.tutorialspoint.com/java/java_exceptions.htm
This site is an excellent java reference point in general, but specifically for your question today, this page shows you how to work with exceptions.
Is it possible to use exception handling in this situation?
I don't think so. You should probably go and ask your teacher.
In your code, Artifact is just a POJO (Plain Old Java Object). It would not throw any exceptions. All you do in the class is getters and setters, right? How can that throw any exceptions?
You can throw exceptions though. In your setters, you can check whether the argument is null before setting it to the fields. For example:
public void changeArcName(String x) {
if (x == null) throw new ArgumentException ("x is null!");
this.arcName = x;
}
Alternatively, you can just use brute force and use try...catch. like this:
Artifact test = new Artifact(88888888,"ben","clay",1624,46.4);
try {
System.out.println(test.toString()); //toString()
System.out.println(test.getArtWeight()); //getArtWeight()
System.out.println(test.getArtYear()); //getArtYear()
System.out.println(test.getArtType()); //getArtType()
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtNumber()); //getArtNumber()
test.changeArcName("zack");
test.changeArtYear(1400);
System.out.println(test.getArcName()); //getArcName()
System.out.println(test.getArtYear()); //getArtYear()
} catch (Exception ex) {
ex.printStackTrace ();
}
Warning: The catch block can never be reached!
I don't know whether the above is what your teacher wants. Just try both methods and hand it in and see what he/she says!

correctly printstacktrace of servlet exception

so i am using a filter to catch servlet exception (because we are using a mix of jsf/plain servlets)
when catching the ServletException and calling printstacktrace most of the information is lost.
the "true" root exception seems to be hidden behind the "funny" expression
((ServletException) e.getRootCause().getCause()).getRootCause().getCause().getCause().getCause()
this is clearly not the way to do it.
is the an easy way to print the "full" information of such an exception.
can someone explain me why the exception is wrapped this way?
Take a look at the ExceptionUtils class from commons-lang. It contains several useful methods for printing the entire chain of exceptions.
after i had a look at ExceptionUtils, this solved the problem!
final StringWriter stacktrace = new StringWriter();
ExceptionUtils.printRootCauseStackTrace(throwable,new PrintWriter(stacktrace));
msg.append(stacktrace.getBuffer());
this prints out the full stacktrace with every piece of information that is relevant.
That is called exception chaining. By wrapping an exception in a different exception you can let exceptions bubble up the stack without having your main application classes to worry about some low-level exceptions.
Example:
public void doStuff() throws StuffException {
try {
doDatabaseStuff();
} catch (DatabaseException de1) {
throw new StuffException("Could not do stuff in the database.", de1);
}
}
This way your application only has to handle StuffException but it can get to the underlying DatabaseException if it really needs to.
To get to the bottom-most (and all other) exception(s) of an exception you caught you can iterator over its root causes:
...
} catch (SomeException se1) {
Throwable t = se1;
logger.log(Level.WARNING, "Top exception", se1);
while (t.getCause() != null) {
t = t.getCause();
logger.log(Level.WARNING, "Nested exception", t);
}
// now t contains the root cause
}
Exception chaining for ServletException is tricky. Depending on the web server implementation and web development framework in use, at runtime the chain may use cause and/or rootCause. This link explains it very well. To complicate things, I've seen exceptions where the cause points to the exception itself.
Here's a recursive method we have used that covers all bases for ServletExceptions:
public static Throwable getDeepCause(Throwable ex) {
if (ex == null) {
return ex;
}
Throwable cause;
if (ex instanceof ServletException) {
cause = ((ServletException) ex).getRootCause();
if (cause == null) {
cause = ex.getCause();
}
} else {
cause = ex.getCause();
}
if (cause != null && cause != ex) {
return getDeepCause(cause);
} else {
// stop condition - reached the end of the exception chain
return ex;
}
}

Categories

Resources