log the exception in spring using aspectJ? - java

Please don't hesitate to edit the question or to ask more details about the questin.
I know I can log the ArithmeticException of the below method using the aspectJ as,
public void afterThrowingAspect(){
System.out.println("This is afterThrowingAspect() !");
int i=2/0;
System.out.println("i value : "+i);
}
The AspectJ class has,
#AfterThrowing(pointcut = "execution(* com.pointel.aop.test1.AopTest.afterThrowingAspect(..))",throwing= "error")
public void logAfterError(JoinPoint joinPoint,Throwable error) {
System.out.println("Hi jacked Method name : " + joinPoint.getSignature().getName());
log.info("Method name : " + joinPoint.getSignature().getName());
log.info("Error report is : " + error);
}
Normally I can handle exception using the TRY and CATCH block and log the errors in the every CATCH block as ,
public void someMehtod(){
try{
int i=2/0;
System.out.println("i value : "+i);
}catch{ArithmeticException err){
log.info("The exception you got is : " + err);
}
}
But I don't like to do the logging like with every single catch block individually in all the java classes of my project like ,
log.info("The exception you got is : " + err);
I would like to do the logging inside CATCH block in my application using the aspectJ class.
Hope you are all understand my question.Thanks.

Its possible to simply remove the try/catch from your code and simply log the exception in your aspect.
public void someMehtod(){
int i=2/0;
System.out.println("i value : "+i);
}
Because you don't re-throw the exception in the aspect then it won't bubble up. Although this is possible I strongly advise you to think more about what you are trying to do here. Why do you need to log the fact that an exception has been thrown? Exceptions aren't necessarily only for errors but can occur in normal code journeys. Simply logging only the exception name is unlikely to help you debug the problem. Therefore, you will probably want a bespoke log message for each catch block. If you do find repetition you could create a method to log out the result.
Hope this helps,
Mark

Related

complaining about logging and rethrowing the exception in sonar [duplicate]

I have the following piece of code in my program and I am running SonarQube 5 for code quality check on it after integrating it with Maven.
However, Sonar is complaining that I should Either log or rethrow this exception.
What am I missing here? Am I not already logging the exception?
private boolean authenticate(User user) {
boolean validUser = false;
int validUserCount = 0;
try {
DataSource dataSource = (DataSource) getServletContext().getAttribute("dataSource");
validUserCount = new MasterDao(dataSource).getValidUserCount(user);
} catch (SQLException sqle) {
LOG.error("Exception while validating user credentials for user with username: " + user.getUsername() + " and pwd:" + user.getPwd());
LOG.error(sqle.getMessage());
}
if (validUserCount == 1) {
validUser = true;
}
return validUser;
}
You should do it this way :
try {
DataSource dataSource = (DataSource) getServletContext().getAttribute("dataSource");
validUserCount = new MasterDao(dataSource).getValidUserCount(user);
} catch (SQLException sqle) {
LOG.error("Exception while validating user credentials for user with username: " +
user.getUsername() + " and pwd:" + user.getPwd(), sqle);
}
Sonar shouldn't bother you anymore
What sonar is asking you to do, is to persist the entire exception object.
You can use something like:
try {
...
} catch (Exception e) {
logger.error("Error", e);
}
I stumbled across the same issue. I'm not 100% sure if I'm completely right at this point, but basically you should rethrow or log the complete Exception. Whereas e.getMessage() just gives you the detailed message but not the snapshot of the execution stack.
From the Oracle docs (Throwable):
A throwable contains a snapshot of the execution stack of its thread at the time it was created. It can also contain a message string that gives more information about the error. Over time, a throwable can suppress other throwables from being propagated. Finally, the throwable can also contain a cause: another throwable that caused this throwable to be constructed. The recording of this causal information is referred to as the chained exception facility, as the cause can, itself, have a cause, and so on, leading to a "chain" of exceptions, each caused by another.
This means the solution provided by abarre works, because the whole exception object (sqle) is being passed to the logger.
Hope it helps.
Cheers.
If you believe that SQLException can be safely ignored, then you can add it to the list of exceptions for squid:S1166 rule.
Go to Rule-> Search squid:S1166.
Edit exceptions in Quality Profile.
Add SQLException to the list.

Java show me long error but missing in my log file

Hi all I know its a stupid question but I'm trying everything.
My game server show me a very long error which is too long for console and can see the top of it, but it is missing from my log and I can't see the details of this error.
Can somebody help me on how can I capture that error:
private void fix(L2PcInstance pl, int playerPoints)
{
try
{
IAchievement arc = Achievements.getInstance().GetAchivment(_id, pl.getAchivmentLevelbyId(_id) + 1);
if ((arc != null) && (playerPoints > arc.getNeedPoints()))
{
Achievements.getInstance().reward(pl, arc);
fix(pl, playerPoints);
}
}
catch (Exception e)
{
_log.error(getClass().getSimpleName() + ": Error in fix: " + e);
}
}
the error
the line 96 is
fix(pl, playerPoints);
but the error is missing from my log im try to capture the console to txt file from command
java myserver.jar > capturemyconsole.txt but again it's showing error in console that the txt is missing. How is this possible ? Thanks for your time and help :)
and sorry for my bad english :(
You method fix calls itself, with the same arguments, causing stack overflow...
Should add some modification to the arguments, or some more condition to the recursion...
You can catch "Error" instead of "Exception" and then log
[...] catch (Error e)
{
_log.error(getClass().getSimpleName() + ": Error in fix: " + e, e);
}
In Your current code StackOverflowException (which is not a child of Exception) is propagated without going into catch block. Remember to put additional "e" parameter to log full stacktrace.
It's not a good practice to catch Error, but it'll answer Your question.
More info: try/catch on stack overflows in java?

Java Error Catching Issue

I have a try/catch thing set up where it will catch all exceptions and then display the error.
Here is my code:
try {
//CODE THAT COULD ERROR HERE
} catch (final Exception e) {
System.err.println("Unexpected error: " + e.getStackTrace()[0]);
}
The above code gives me the LAST class that had the error. How do I detect the LAST class of MY PROGRAM that had the error?
Example Output: "Unexpected error: package.ClassName.method(ClassName.java:46)"
I want it to output the line of my program that had the error, not the line of a built-in java class that error-ed because of my program.
e.printStackTrace()
might make you happier. Or print the top of the array of stack trace entries available from the appropriate method.
http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#getStackTrace()
returns them. The first one is what you are asking for.
You can use getStackTrace to get an array of StackTraceElement instances, and filter that based on your package and/or class names (using getClassName for each element, which gives you the fully-qualified class name for that stack trace frame). That would let you winnow it down to your code rather than the JDK class the exception originated in.
try {
//error producing code
} catch (Exception e) {
for (StackTraceElement s : e.getStackTrace()) {
if (!s.getClassName().startsWith("java.")) {
System.out.println("file name: " + s.getFileName());
System.out.println("class name: " + s.getClassName());
System.out.println("method name: " + s.getMethodName());
System.out.println("line number: " + s.getLineNumber());
System.out.println();
//break; // will be the highest non java package...
}
}
}
You of course could switch it to be package specific so if (s.getClassName().startsWith("com.company")) { so it wont return for a third party library or something in the sun package or other non java package.

Print Alfresco exception

I've some problem printing the exception stack trace for Alfresco Exception.
On debug mode, step by step under Eclipse IDE I'm able to see the message when the exception is raised inspecting the Exception object but, when I send the error message to console output it's always null.
The exception is raised by this instruction:
try {
UpdateResult[] results = WebServiceFactory.getRepositoryService().update(cml);
}
catch (Exception ex) {
System.out.println(" " + ex.getStackTrace());
System.out.println("ERROR - createContent : " + ex.getMessage());
}
(in that case I tryed to write on a folder that not exists on repository) and inspecting the ex object on eclipse I can see the message:
java.lang.IllegalStateException: Failed to resolve to a single NodeRef with parameters (store=workspace:SpacesStore uuid=null path=/app:company_home/cm:UploadFromJava), found 0 nodes.
but ex.getMessage() returns null
Anyone could help me?
thanks,
Andrea
Implementing a method in this way:
NamedValue setNameProperty(String name) throws AlfrescoRuntimeException
{
try {
return Utils.createNamedValue(Constants.PROP_NAME, name);
}
catch (Exception ex) {
throw new AlfrescoRuntimeException(ex.getMessage());
}
}
The message is correclty printed with e.printStackTrace();
Try to replace your package in the log4j.properties from debug to error

How to display stack trace on a caught exception?

I have a generic function that prints exceptions (using log4j):
private void _showErrorMessage(Exception e) {
log.error(e.getClass() + ": " + e.getMessage() + ": " + e.getCause() + "\n" + e.getStackTrace().toString());
}
Instead of seeing the stack trace I'm seeing:
[Ljava.lang.StackTraceElement;#49af7e68
How can I view the stack trace of the exception properly?
update
log.error(e) <- shows the error, but doesn't show stack trace
Your logging framework should have the ability to log exceptions, so simply passing the exception to the proper .error(Object, Throwable) call should be enough:
log4j can do it
commons logging can do it
java.util.logging can do it
If your logging framework can't do that, or you need the stack trace in a String for any other reason, then it becomes a bit harder. You'll have to create a PrintWriter wrapping a StringWriter and call .printStackTrace() on the Exception:
StringWriter sw = new StringWriter();
ex.printStackTrace(new PrintWriter(sw));
String stacktrace = sw.toString();
Have you tried?
private void _showErrorMessage(Exception e) {
log.error("Hey! got an exception", e);
}
I use the ExceptionUtils#getFullStackTrace method of Jakarta Commons Lang
Throwable.getStackTrace returns an array of StackTraceElements, hence the toString method is returning a textual representation of the array itself.
In order to actually retrieve the stack trace information, one would have to go through each StackTraceElement to get more information.
You could also look at the Guava libraries from Google.
Throwables.getStackTraceAsString(Throwable throwable)
The exact answer to your question is that you should call Log4J like this:
private void _showErrorMessage(Exception e) {
log.error(e.getClass() + ": " + e.getMessage() + ": " + e.getCause(), e);
}
Although I would dispense with the call to e.getCause() because the stacktrace will give that to you anyway, so:
private void _showErrorMessage(Exception e) {
log.error(e.getClass() + ": " + e.getMessage(), e);
}
ExceptionUtils is fine if you really need a string of the stacktrace, but since you are using Log4J, you lose a lot by not utilizing its built in exception handling.
Exception Stacktrace logging shows two methods for this purpose, one based on Apache Commons and another using the standard JDK method.

Categories