1

I want to catch all exceptions/errors that occur in my application.
Therefor I searchd on stackoverflow and stubled over this question: Java Exception Listener
Now I am wondering if this can be accomplish in a better way.

My current application:
I am using the Spring framework with the Spring JPA in an standalone code without the web component. I have a Config.java file with the four main Beans:

  • Time Weaver
  • Data Source
  • entity Manager Factory
  • transaction Manager

I now thought that I could maybe use something like the following:

package me.test;

import java.beans.ExceptionListener;
import org.springframework.stereotype.Component;

@Component
public class ErrorListener implements ExceptionListener {
    @Override
    public void exceptionThrown(Exception e) {
        System.out.println("Some error occured ... That's bad :(");
    }
}  

I am not really sure if this ExceptionListener works like I want him to work, so I thought maybe someone can explain to me if what I want is possible or not.
Maybe not with this Listener but with an other method?

Also a other general Question:
How do I register an Listener in general? Isn't there also a @EventListener anotation? Do I have to put this before an method and then let it scan by spring as a part of a Component?
Or do I have to register it manually in my context?

Thanks :)

--- EDIT ---

The idea with the AfterThrowing seems very nice (see comments below). Now my project is like the following:

in the Main:

new AnnotationConfigApplicationContext(Config.class);

Config.java

@EnableTransactionManagement
@ComponentScan("me.test.*")
@Configuration
@EnableJpaRepositories
@EnableAspectJAutoProxy
public class Config {
    @AfterThrowing(pointcut = "execution(public * *(..)", throwing = "ex")
    public void doRecoveryActions(DataAccessException ex) {
        System.out.println("Error found");
    }
    /* loadTimeWeaver, dataSource, entityManagerFactory and transactionManager with the "@Bean" annotation */
}

And then in an random file something that throws an error like int i2 = 5 / 0; and in an other class throw new Exception("test");.
But unfortunately it is nor working :(
What am I doing wrong?

Community
  • 1
  • 1
toddeTV
  • 1,447
  • 3
  • 20
  • 36

1 Answers1

1

You may use Spring AOP Advice for this where you would use after throwing advice.

Nitin Prabhu
  • 624
  • 6
  • 10
  • I already thought about it, but the `@Around` needs a function as parameter. So how can I accomplish to get a function, that is executed whenever a exception is thrown, no matter where? – toddeTV Feb 14 '16 at 00:26
  • 1
    What you can do is as below @Aspect public class AfterThrowingExample { @AfterThrowing( pointcut="execution(public * *(..)", throwing="ex") public void doRecoveryActions(DataAccessException ex) { // ... } } – Nitin Prabhu Feb 14 '16 at 00:38
  • Basically if any public method throws exception execute the advice method.You can change the pointcut as per your requirement – Nitin Prabhu Feb 14 '16 at 00:39
  • ok, that sounds great. thanks :) but now I have two more questions: first, is there a `)` missing? `"execution(public * *(..))"` the last one ... or is it correct without the clip? and second: how do I integrate this class in my spring project? on all tutorials there is an xml file (servlet, web, ...) but I do not have any of these. I did all in pure java without such configs. – toddeTV Feb 14 '16 at 00:51
  • 1
    1.I don't think so there is missing ')'.However you will get to know when you execute the program. 2.In spring you can provide meta information in two ways either by xml or annotation.If you do not have any xml config then you can use annotation to use Aspect. You can do it as below`code` @EnableAspectJAutoProxy does the job it is used with @Configuration @Configuration @EnableAspectJAutoProxy public class AspectJAutoProxyConfig{..} – Nitin Prabhu Feb 14 '16 at 01:19
  • To get the annotations in your java class you need to add dependency org.springframework spring-aop ${spring.version} org.aspectj aspectjrt 1.6.11 org.aspectj aspectjweaver 1.6.11 – Nitin Prabhu Feb 14 '16 at 01:22
  • ok, I now tried it and added all the parts in my **config** class but it is not working at all. I extended my post/question at the top to show my current classes. What am I doing wrong? – toddeTV Feb 14 '16 at 09:29
  • You should define aspect in a new class and not in the config class as below@Aspect public class ExceptionHandingAspect { @AfterThrowing(pointcut = "execution(public * *(..)", throwing = "ex") public void doRecoveryActions(DataAccessException ex) { System.out.println("Error found"); } } – Nitin Prabhu Feb 14 '16 at 09:37
  • the result is the same: It is doing nothing. But when I write `@Aspect @Configuration @EnableAspectJAutoProxy` before the class, he at least is throwing an own error `Caused by: java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting ')' at character position 0` – toddeTV Feb 14 '16 at 09:58
  • I think you missed the closing brace for execution Instead of "execution(public * *(..)" use "execution(public * *(..))" – Nitin Prabhu Feb 14 '16 at 10:26
  • I already tried that ... `Caused by: java.lang.IllegalArgumentException: Cannot subclass final class com.sun.proxy.$Proxy44`. I am more then irritated and maybe the approach is wrong. Isn't it easier to set an `UncaughtExceptionHandler` for the thread the program is running in? where is the difference to the AspectJAutoProxy? And are both solutions also possible to use in an spring web application? (Because I now try some things in an spring standalone application that is later used in an web context.) – toddeTV Feb 14 '16 at 10:36