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/
Related
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I am getting the below error from a simple line of code having log.info statement
java.lang.NullPonterException
at java.io.Writer.write(Writer.java:157)
at org.apache.log4j.helpers.CountingQuietWriter.write(CountingQuietWriter.java:45)
at org.apache.log4j.WritingAppender.subAppend(WriterAppender.java:310)
at org.apache.log4j.RollingAppender.subAppend(RollingAppender.java:276)
at org.apache.log4j.WritingAppender.append(WriterAppender.java:162)
at org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
at org.apache.log4j.helpers.AppenderAttachbleImpl.appendLoopOnAppenders(AppenderAttachbleImpl.java:66)
at org.apache.log4j.Category.callAppenders(Category.java:206)
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.info(Category.java:666)
at com.bizcase.Helper.showTip(Helper.java:32)
Can anyone advice if this issue is encountered?
I am using log4j version 1.2.17 and normal rolling appender .
Its not a NullPonterException for null object.Its coming from log4j library and beyond my control to figure out which log4j property or code is causing this issue.
Looking at the source code1:
"org.apache.log4j.helpers.CountingQuietWriter.write(CountingQuietWriter.java:45)" is a call to Writer.write(String).
Writer.write(String) can only throw an NPE if the string is null.
That means CountingQuietWriter.write was called with a null argument.
And so on. (You can do the rest!)
I think you will find that the root cause is that org.apache.log4j.Category.info(...) is being called with a null message.
Also, note that the javadoc for Category states:
There is absolutely no need for new client code to use or refer to the Category class. Whenever possible, please avoid referring to it or using it.
So, if com.bizcase.Helper is your code, then it needs to be revised, both to fix the NPE bug and to avoid direct usage of Category.
If it is not your code, you need to figure out where the null string comes from in the info call. My guess would be is that it is a missing tool tip ... or something like that.
1 - I am hampered in this because I don't know the precise versions of Java and log4j that you are using, and therefore can't be sure I have the right source code. And I don't know what the source of com.bizcase.Helper looks like. On the other hand, you ... as the developer ... can find these things out. Which makes it a whole lot easier for you.
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.
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.
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.
I'm currently working on a Java project and was having a problem with a stack overflow error. What happens is first the program reads in a file of about 1,500,000 words and adds it to an array. It then reads in a small file of about 600 words and adds it to an array. It checks how many words in the 600 word file occur in the other file. Each word in the big file is associated with a number. So when it finds a word in the big file it takes a copy of the word and its associated integer and adds it to an array. My problem is that I am getting a stack overflow error:
"AWT-EventQueue-0" java.lang.StackOverflowError
The thing is that when the small file is about 200 words the program runs fine.
The last line the program has to execute is:
result.setPage("file:file for gui NEW.html");
(where result is an JEditorPane)
For some reason I get a stackoverflow error when the small file is 600 words but runs ok when it is 200 words. It runs the last line and produces this file but doesn't print it to the editor pane as that is when the exception kicks in.
Can anyone help to tell me why this may happen and how I could go about fixing it?
Thanks.
The error in the console in full is:
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source)
at sun.awt.SunToolkit.getSystemEventQueueImpl(Unknown Source)
at java.awt.Toolkit.getEventQueue(Unknown Source)
at java.awt.EventQueue.isDispatchThread(Unknown Source)
at javax.swing.SwingUtilities.isEventDispatchThread(Unknown Source)
at javax.swing.JComponent.revalidate(Unknown Source)
at javax.swing.plaf.basic.
BasicTextUI$RootView.preferenceChanged(Unknown Source)
at javax.swing.text.View.preferenceChanged(Unknown Source)
at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
at javax.swing.text.View.preferenceChanged(Unknown Source)
at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
at javax.swing.text.View.preferenceChanged(Unknown Source)
at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
(... repeating forever ...)
EDIT: So basically it seems that two controls in the GUI keep invoking each other's preferenceChanged() method.
The Gui seems like the most likly cause because when I run the program without the gui and print the contents of the file to the console instead it works fine. I've no idea what is actually causing the problem. I'm not using preference changed routine. Only thigs like setSize(), setVisible() etc. would that cause it?
Do you have a recursive function somewhere? This is usually the source of stack overflows.
Additional info here.
I think you have ran into a variation of this issue:
http://www.jdocs.com/harmony/5.M5/javax/swing/text/BoxView.html#M-layout(int,int)
protected void layout ( int width, int height )
This method may cause stack overflow
if upon each layout try a child
changes its preferences, i.e.
preferenceChanged is called.
I'm not sure how you managed do achieve this but try to not to change prefences of childs on layouts. I'm sure that someone with more experience with swing than me could provide a more valuable answer.
The stack overflow is in a GUI object's preferenceChanged() routine. The culprit is something your GUI is doing, your array usage is just the trigger.
Are you subclassing any GUI objects, especially one with your own preferenceChanged() function anywhere? Best guess is that it has something to do with displaying a scrollbar, since the exception depends on how many objects you're adding to this array. Check the docs very carefully for any GUI objects or events that you are working with.
Look at the stacktrace of the StackOverflowError. It will almost certainly show you one or two methods repeatedly calling itself/each other. Rewrite those methods so that this does not happen (or does not happen that often).
I would check the file that's being output since the recursion seems to be happening in the JEditorPane rather than in your code - does this file show up in a normal web browser okay? Keep in mind the the JEditorPane is not the most advanced component in the world and may choke if you're trying to show something complex.
I've also experienced layout errors in JEditor Pane which occur seemingly at random and I've never found the bottom of, although this is usually when I'm editing the contents of the pane rather than just showing a web page.
If you're changing the size of the window whilst you're loading the file it may cause the kinds of errors that you're describing - I would try and just load the file into the editor pane without altering it.
Assuming you can attach a debugger, on Eclipse (sorry, I don't know Netbeans/Idea) you can then add an exception breakpoint for StackOverflowError. In the breakpoint view's toolbar, there is a button which has a blue J with an exclamation mark - "J!" - click this, then enter StackOverflowError and choose to suspend on uncaught exceptions only.
Perhaps this will provide some more context as to what is going wrong.
If it is a recursion issue then you can try to change your algorithm with a new one that uses an explicit stack instead of an implicit stack like BFS or DFS
You should check for recursion - both direct recursion (when a function calls itsself) and indirect recursion (when A calls B and B calls A again).
The easiest way to do this is to attach a debugger and look at the call stack at the moment you've got stack overflow.