Proper EJB Exception handling - ClassNotFoundException from client - java

I have some EJBs that use Hibernate to persist data to the database. I have a thick Swing client that talks to these EJBs. The client knows nothing about the database (no driver jar).
During one transaction a Hibernate ConstraintViolationException can be thrown. I catch all exceptions and wrap them in an EJBException like so:
catch(HibernateException e) {
e.printStackTrace();
throw new EJBException(e);
}
The problem I am getting is that when the exception is unmarshalled by the JBoss Invoker on the client side, a ClassNotFoundException is thrown (for PSQLException) since the client has no sql driver jar in the classpath.
I changed this application to always pass the caught exception to the ejbexception constructor like this so we could have a stack trace history. Now I am finding why the original developers didn't do this.
At this point I see two options - either include the postgres driver jar with the client, or remove passing the caught exception to the EJBException constructor. I am curious if anyone has any other suggestions and also how others handle exceptions in their EJBs?

My take is that the client, end user, doesn't need to know the technical details of the problem. Hence at various layer boundaries it's quite reasonble to convert a technical exception to a general "An error of nature XYZ ocurred".
A scheme I've seen used is for the server to allocate a unique error number at the point the exception is detected. It then writes diagnistics to its logs including that number. Messages reported to the client simply include the number. A support desk can then correlate the user's report of the issue via that specific error number.

Related

How to handle exceptions during spring-boot start-up?

This isn't about how to handle exceptions in Spring MVC or anything. I specifically need to handle an exception that can happen while spring is starting, i.e. before the whole application context is even initialised.
For a bit of background, the application in question is an IoT node that allows remote access to electronic equipment. It has a little h2 database built in to persist some data. That data is nice to have at some moments, but not really essential for the application to work.
It so happens that the device the application is running on can get its power cut every once in a while, and if that happens while there was a write operation to the database going on, the file is corrupt and a JdbcSQLException will be thrown when the application tries to boot again.
Since the data is not really essential, the easiest way to make the application work again is to just delete the database and let h2 recreate it. But in order to do that, I have to catch the exception so I can react to it. The application does not have to continue starting, it will be booted up again by systemd. I really just need to identify the exception and delete the file, that's it.
There is one obvious way to do it, which is to put SpringApplication.run in a try-catch block. But it's also really ugly, because I get the exception I'm looking for nested inside a gazillion spring exceptions that were caused by h2 failing to start.
It was also suggested that I catch the exception in the bean that instantiates the database, but unfortunately there is no bean instantiating it. The DB serves as a Quartz job-store and as such is fully managed by spring. Its entire presence in the code are the following entries in the properties file:
spring.quartz.job-store-type=jdbc
spring.quartz.properties.org.quartz.jobStore.misfireThreshold=900000
spring.datasource.name=h2
spring.datasource.url=jdbc:h2:file:${config.folder}controller
spring.datasource.driverClassName=org.h2.Driver
My question is, is there a way to register some kind of exception handler, or other means, to handle the exception directly when it happens, when I can identify it much more easily?
Depends how you've declared the bean. What's wrong with simply wrapping the bean like this?
#Configuration
class Conf {
#Bean
public DB foo() throws JdbcSQLException
{
try
{
return new DB();
}
catch(JdbcSQLException e)
{
deleteDatabase();
throw JdbcSQLException;
}
}
public static void deleteDatabase()
{
//...
}
}

Logging and Exception handling in a micro-service in Java

I am working on a microservice which does some calculation based on certain configurations stored in its own data store. The calculations apis are stored via REST APIs. The application is a spring boot application.
Now there are mainly 3 layers in the application :
REST Controller
Service layer
DAO layer - it used spring data.
I am planning to handle the logging and exception handling using below points:
Log each request that the service receives and response or at least
the response if the status is not in 2xx series.
If there are any checked exception in either DAO layer or Service
layer then log them and throw a custom exception derived from
RuntimeException.
Have Several custom exception which should be thrown from Service
layer mainly if we come across scenarios like invalid values, null
values etc.
Have a try catch block in the REST Controller and log the
exception i.e. message along with stacktrace and return the
response accordingly.
So overall idea is to let the RuntimeExceptions propagate all the way to REST Controller where they should be logged and accordingly the response should be sent. Incase of checked exceptions log them in the same method and throw custom exceptions instead.
Please suggest what should be the correct or a good approach for logging exception in such applications.
Write controller advice which will catch all the exceptions & logs the required contents. You may catch exceptions here. I implemented same what you asked here.
*/
/**
* Uncaught exception handler
* #param e - Exception
*/
#ExceptionHandler(Exception.class)
#ResponseStatus(code=HttpStatus.INTERNAL_SERVER_ERROR)
#ResponseBody
public void handleError(Exception e,HttpServletRequest request, HttpServletResponse response){
logger.error("Exception occured : {}",e);
//logs request & response here
}
Also please check AbstractRequestLoggingFilter described here.
For all custom application specific exeptions create your own custom exception type & handle it with the help of #ExceptionHandler as specified in above code block.
Choose only one place to log the exceptions.
In your design, if an exception occurs in DAO, it will:
Get logged in DAO
Then trigger a runtime exception, which will be caught and logged in controller
Which should then return non-2xx response status via REST, which will trigger logging the response as per your first point
So you'll have either the same information in three places, or you will have the different bits of information regarding a single error scattered in two or three places across the log.
Choose a single place to log the errors, and make sure all relevant info is present at that place (i.e. set the underlying DAO exception as a cause of the runtime exception, and don't forget to log the runtime exception along with its cause).

How does a Shiro enabled web application handle CacheExceptions

I have a question about handling org.apache.shiro.cache.CacheException.
What is shiro's responsibility when a cache exception occurs? This RTE ripples through the whole stack, but I'm unclear where it is handled and in what manner.
Can a shiro enabled web application recover?
Is the cache manager reinitialised?
Do I have to restart the application when a cache exception occurs?
For example, a timeout exception or a failed to connect to node exception occurs on cache.get(key). What's the expected outcome apart from bubble to the stop and die?
Thanks
I have checked all usages of CacheException and the only thing shiro does is throw it. It never gets catched let alone handled.
So the only expected outcome is to "bubble to the stop and die".
What you can do about it is have a servlet filter in front of shiro that catches this exception, then get a hold of the CacheManager instance (how you do that depends on your setup) and call cacheManager.getCache().clear() so the cache is reset.

Load error messages in singleton bean in spring

I have error_messages table, which contains the site-wide error messages.
I use the error messages across application. So, I created singleton bean of error messages (ErrorMessagesLoad.java)
ErrorMessagesLoad uses ErrorMessageDao to retrieve the error messages from database.
Should I create static variable in ErrorMessagesLoad to hold all the error messages and use it in all classes? or is there better way of doing it?
Thanks,
Satya
You should use your own implementation of MessageSource in Spring to resolve any messages. Here is a good point to start.
When implemented, you just wire your bean to any service or controller and it handles messages for you, with ability to iternationalize them.
In general global static variables should be avoided. Error handling can get tricky. Many applications try to put a global catch handler somewhere near the top (e.g. web applications the top would be filters) which has the ErrorMessagesLoad injected into it. That handler catches underlying exceptions, translates them into something user readable and then throws that higher.
Some examples include Spring's exception translation filter and Jersey's exception mapping mechanism.

RESTEasy hides real exception

My code is throwing an exception (due to a bug). In the log, I see:
org.jboss.resteasy.spi.UnhandledException: java.lang.NullPointerException
at org.jboss.resteasy.core.SynchronousDispatcher.handleApplicationException(SynchronousDispatcher.java:323)
at org.jboss.resteasy.core.SynchronousDispatcher.handleException(SynchronousDispatcher.java:199)
at org.jboss.resteasy.core.SynchronousDispatcher.handleInvokerException(SynchronousDispatcher.java:175)
at org.jboss.resteasy.core.SynchronousDispatcher.getResponse(SynchronousDispatcher.java:529)
etc...
The stack of the actual exception is not logged. If I wrap my code in a try..catch and log the caught exception I can verify that my code is at fault. No other library in my system does this, even for deeply-wrapped exceptions, so it must be a problem in RESTEasy, perhaps in UnhandledException?
Is there a way to get around this behavior? I can't think of a good reason why it should be hiding the actual exception.
Jetty
Java
Spring 3.0.3
RESTEasy 2.0.1GA
Do you have an ExceptionMapper? See Chapter 27, Exception Handling, in the RESTEasy documentation.
I used RESTEasy to add REST to an existing system, and the existing system has a weird way of wrapping exceptions within exceptions, so my ExceptionMappers do a lot of unwrapping.
Throwable t = exception;
while (t.getCause() != null) {
t = t.getCause();
}
t.printStackTrace();
I don't use RESTeasy, but it appears to be a dispatch mechanism for RESTful web services.
Assuming this is the case, then it has different design goals from other libraries: they are invoked from your application, but RESTeasy is responsible for invoking your application. It therefore has to protect itself from poorly written code. A "last ditch" exception handler is a common way to do this; you'll see the same thing in Swing.
Whether or not it should log the uncaught exceptions is a different matter. Perhaps there's a configuration option to do this. Or perhaps you need to add a couple lines of code. It is open-source, after all, and I'm sure the maintainers would appreciate a well-written bug report with patch.
Yes, your exception is swallowed by RESTeasy, wrapped in UnhandledException and logged. But your exception lies too deep within to be included in the stacktracs.
To print out your exception to the console, you could append the following to 'WEB-INF/classes/logging.properties'
org.apache.catalina.core.ContainerBase.[Catalina].level = FINEST
org.apache.catalina.core.ContainerBase.[Catalina].handlers = java.util.logging.ConsoleHandler

Categories