Google Play Console Stack Trace - java

In Google Play Console, I am getting the below exception trace. Although I have added deobfuscation files, the line numbers are being displayed as 0.
java.lang.NullPointerException:
at com.ae.apps.common.managers.ContactManager.getContactIdFromAddress(ContactManager.java:0)
at com.ae.apps.messagecounter.utils.MessageCounterUtils.sortThisMap(MessageCounterUtils.java:0)
at <OR>.getMessageCountDegrees(MessageCounterUtils.java:0)
at <OR>.getContactMessageList(MessageCounterUtils.java:0)
at <OR>.convertAddressToContact(MessageCounterUtils.java:0)
at <OR>.getIndexFromDate(MessageCounterUtils.java:0)
at <OR>.getWeekStartDate(MessageCounterUtils.java:0)
at <OR>.getMessageLimitValue(MessageCounterUtils.java:0)
at <OR>.getCycleSentCount(MessageCounterUtils.java:0)
at com.ae.apps.messagecounter.activities.MainActivity$1.run(MainActivity.java:0)
at java.lang.Thread.run(Thread.java:818)
I dont't understand what this <OR> statements in the stack trace. The ContactManager.getContactIdFromAddress() is only called from the method MessageCounterUtils.convertAddressToContact().
How to properly understand this stack trace?
I believe I have added the necessary Null checks in the above method anyways.
https://github.com/midhunhk/ae-apps-library/blob/master/app/src/main/java/com/ae/apps/common/managers/ContactManager.java#L377

I believe you're running into the same issue answered in this question: Android ProGuard return Line Number
Proguard doesn't keep the line numbers by default.

How to properly understand this stack trace?
< OR > literally means "OR". When stack trace is created for some lines of it there are several possibilities (LineNumberTable is missing or it is corrupted?) so they are printed with this prefix.

Related

Debug NullPointerException in Eclipse

I ran a program and received an null pointer exception. I added a Java Exception breakpoint and debug. For example, it broke at line 11 in a method called "myMethod". On line 11, it shows that the object "Box" is null in debuger. From here, how can I step back to trace the root of the cause? I think the problem occurs outside of the method "myMethod", because the object Box is passed as a parameter of the method and is shown as null.
Thank you.
You should see a stacktrace in the tab called "Debug" in the debug view. When you hit the breakpiont in myMethod, go to the stack trace in the debug view and click on the previous method in the stack trace and look at the value.

How to read and understand the java stack trace? [duplicate]

This question already has answers here:
What is a stack trace, and how can I use it to debug my application errors?
(7 answers)
Closed 8 years ago.
For example, I got a stack trace like this:
java.lang.NullPointerException
abc.investxa.presentation.controllers.UnixServerJobController.handleRequest(UnixServerJobController.java:66)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:501)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
So what is the root cause of this exception?
From the stack trace, I found out that there is a problem with doFilter function in the OncePerRequestFilter class! However, when I put a break point there and the program never stop at that break point.
Could anyone give explanation about this!?
And in general case, how should I use that stack case for debugging (read from bottom to top or from top to bottom)!
You should generally read from the top - so in this case, there's a NullPointerException at line 66 of UnixServerJobController, in the handleRequest method. That method was called by SimpleControllerHandlerAdapter.handle, which was called by DispatcherServlet.doDispatch etc.
However, in this particular case it's likely that the first frame of the stack trace is all you need. Look at line 66 of UnixServerJobController, work out what might be null, and act accordingly.
Note that sometimes one exception is wrapped in another (which may in turn be wrapped in another, etc). In this case you should look at each of the stack traces - often it's the "most nested" exception which gives the most useful information, as that's the root cause.
Generally the exact reason for the Exception is at the first line of your Stack Trace, and for more information about the cause of that exception, you need to gradually move down, and the root cause can often be found somewhere near the bottom of the stack trace.
But in most cases, you can even get the cause of the exception from the first few lines..
So, in this case, your exception is at handleRequest method, and when you move downwards, those are the methods, which invoked your previous method (The one at above the current method in stack trace)
This tutorial might shed some light on your problem and help you understand things better.
As per your problem, you seem to have a Null Pointer Exception at line 66 of the Unix Server Job Controller class.
I found this tutorial is highly useful to me
https://forums.bukkit.org/threads/how-to-read-stack-traces-and-troubleshoot-your-own-plugins-by-yourself.32457/

Is there a way to print stack trace on demand?

I am looking for a way to get a stack trace when I am at a certain breakpoint. Is this possible? Ideally without having to crash the application and modifying the code. I tried playing with the Android debugger but couldn't find anything very helpful.
The reason is that sometimes I am not certain how the application arrived at a point in code, so I am open to other suggestions that would help me trace the method calls.
This can be done in Java:
new Throwable().printStackTrace();
In Eclipse, if you create an "expression" with that code in the Expressions view of Debug perspective, it will print current stack trace (i.e. the stacktrace of the breakpoint your code stopped on) in the Console view.
Log.e("AppName", "Debug exception", new Exception());
The easiest way is to throw an exception, immediately catch it and use printStackTrace().
You could also try Thread.currentThread().getStackTrace() which gives you a StackTraceElement[] in case you want to to anything else besides having the textual representation that printStackTrace() does.

Logging good practice

I use sl4j / logback as a logging framework. I am unsure about the right way to log errors. Namely, assuming e is an Exception I want to log, I always hesitate between:
logger.error("Something bad happened: {}\nError: {}", someInfo, e.getMessage());
I understand this is not good practice because the stack trace is lost - not great to understand what happened.
logger.error("Something bad happened: {}\nError: {}", someInfo, e.getMessage(), e);
Using both e.getMessage() and e seems redundant, although I don't know if it is possible that e.getMessage() might contain extra information that would not be seen if I used:
logger.error("Something bad happened: {}", someInfo, e);
which is the syntax I generally use - but I want to make sure I am not missing anything.
I usually use number two, although I NEVER break one line of log into 2 lines (\n), although when printing the stack trace, it won't matter much (in all other cases, it creates too much visual entropy when your logs become really huge).
Why do I use number 2?
I want to see the message right away, on the first line, since it's the first thing that tells me what happened. Some might be expected and I can safely skip them, and some might not be.
In case I need to examine exactly what happened, I take a better look at the stack trace.
I reckon number 3 is also fine, since you'll get the information you need anyway.
NEVER use option 1.
By the way, and just a particular opinion, saying that something bad happened on a ERROR line is a bit redundant ;)
If you look at the source code of Throwable (http://www.docjar.com/html/api/java/lang/Throwable.java.html) you'll find that a Throwable when asked to print its stacktrace starts by priting itself, which prints its message.
I find it unlikely that anybody would change this behaviour, so your arguments are all correct and the 3. option is fine
You definitely want the stack trace.
Message is handy in circumstances where you've done something like "Error : Unable to find customer with ID : {0}", which may not be in the stacktrace. Trivial example but you get what I mean.
Another one for message is if you do the log as say a csv so you can analyse it. You can standarise message, and make filtering easier.
Last but not least redundant info in an error log, is way way way less of a problem, then the info you need not being in it. Err on the side of extreme verbosity is my guiding principle.
Oh this is for contrrolled access to a log file ,never say put stack trace as a response in asp for instance. Hackers wet dream that.

How do I find out the calling class?

how can i find out which class/method has called the actual method?
You could try to create an exception to get its stacktrace.
Throwable t = new Throwable();
StackTraceElement[] stackTraceElements = t.getStackTrace();
Now stackTraceElement[0] contains the caller of the current method.
But beware (from Throwable.getStackTrace()):
Some virtual machines may, under some
circumstances, omit one or more stack
frames from the stack trace. In the
extreme case, a virtual machine that
has no stack trace information
concerning this throwable is permitted
to return a zero-length array from
this method. Generally speaking, the
array returned by this method will
contain one element for every frame
that would be printed by
printStackTrace.
Here's one way that I've used:
StackTraceElement element=Thread.currentThread().getStackTrace()[3];
String className=element.getClassName();
String methodName=element.getMethodName();
[3] is hardcoded because:
[0] is Thread.dumpThreads()
[1] is Thread.getStackTrace()
[2] is the current method
[3] is the one before the current method
A faster but non-portable solution is to use the following. It does not create a stack trace and just gives you the information you need. However, not all JVMs will have this and future version of Java might not either.
Class callerClass = sun.reflect.Reflection.getCallerClass(2);
You can print a stack trace to do this.
If you want to do this dynamically, I'm not really sure if this is possible (aside from printing and parsing a stack trace dynamically).
You could use a debugger, or a profiler. Netbeans has both, but a lot of other options exists.
Else, if you can modify the code you can throw a new exception() and have a stacktrace printed in the console.
To echo and elaborate on matt b and yishai's comments:
If you are doing this because you are writing a logger or maintaining trace information or some such, okay, cool. I've used stack traces in production code exactly once, and even that was really a debugging issue: We had a problem with database connections not being properly closed, so I modified the "get database connection" function to save the identity of the caller, and then had a periodic sweep to look for dead connections and see where they had been created.
Java's built-in logging function does stack traces so it can write who called the logger to the log file. I worry about the overhead of this as I understand that stack traces are expensive, but whatever.
But if you're doing this because your function is going to behave differently depending on where it was called from, like "if called from class X update customer data else if called from class Y update employee data" or something like that: Really really bad idea. Pass a parameter or write separate functions.

Categories

Resources