ANSWER:
If you ever see these lines and are mistified like I was, here's what they mean.
Thread[AWT-EventQueue-0] (Suspended (exception NullPointerException))
EventDispatchTread.run() line: not available [local variables unavailable]
It's not that the variables are unavailable because they are lurking behind a shroud of mystery in a library somewhere dank. No no, they just went out of scope! It's still your fault, you still have to find the null, and no you can't blame the library. Important lesson!
QUESTION:
One of the most frustrating things for me, as a beginner is libraries! It's a love/hate relationship: On the one hand they let me do things I wouldn't normally understand how to do with the code that I do understand, on the other hand because I don't completely understand them, they sometimes throw a wrench in code that is otherwise working fine! It's because I don't understand the errors that can occur when using these libraries, because I didn't write them, and because eclipse doesn't give me a great deal to go with when one of imports starts acting up...
So here's the problem: I've been working with java.awt.event to handle a bunch of JButtons on the screen for this and that. I get an error when I use one of the buttons I've made. The error is:
Thread[AWT-EventQueue-0] (Suspended (exception NullPointerException))
EventDispatchTread.run() line: not available [local variables unavailable]
What does this mean? What could be causing it? I'm embarrassed to post code, but if you can stand to try to decipher my terrible style, here is the method that seems to cause this error to be thrown.
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String name;
code...
if(cmd.equals("Play")) {
name = field.getText();
card = getCard(name);
if(card != null) {
if(rules.zoneHasCard(card, rules.hand)) {
display.updateStatusMessage(rules.play(card));
field.setText("");
display.updateHand(rules.zoneList("hand"));
display.updateDiscard(rules.zoneList("Discard")); // This is the error here! The discard Zone was empty!
}
else {
field.setText("You do not have " + card.getName());
field.selectAll();
}
}
else {
field.setText("That cardname is unused");
field.selectAll();
}
}
}
Welcome to the complexity of writing GUI code.
When you run a Swing program, a background thread called the Event Dispatch Thread is created. When the user clicks on a JButton, for example, JButton creates and fires an event using this Event Dispatch Thread. Hence the name: it's the thread that dispatches events!
Your code:
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
String name;
// more code...
}
is called by this Event Dispatch Thread, so your code can handle the event.
Somewhere within your code you are trying to do something with a variable that is currently equal to null. The error message is telling you, "hey while running some code on the event dispatch thread, I encountered a NullPointerException" in your code.
Why are you not receiving more info? Possibly you configured Eclipse not to include debug info when compiling?
For now, I recommend adding some lines to your actionPerformed method to show the state of variables:
System.out.println("field = " + field);
System.out.println("rules = " + rules);
System.out.println("display = " + display);
See if this shows you any nulls.
Even if the NullPointerException comes from a library, the stack trace will show which line of your code called that library. But only if you've configured Eclipse to generate debugging info.
In the longer term, work through the Sun's Swing Tutorial to learn more about these issues.
Any method call on a null object will raise a null pointer exception.
In your code, rules, name or display could be null and cause an exception.
Use a debugger (such as the one included in the eclipse IDE) and set a breakpoint at the start of the actionPerformed() method, then step through it line by line to see when a variable you try to invoke a method on is null.
Just don't stop reading the stack trace after two lines. Somewhere in the stack trace you'll recognise the name of one of the classes/methods which you did write. Start looking there. (btw, people spend way to much time inside debuggers :-))
You might have forgotten to actually set an ActionCommand.
In the ActionEvent API Doc there's a note regarding possible null results of getActionCommand().
Related
I have this specific scenario:
my exceptions have a code and a localized message
The thrower just knows the code
The catcher expects a localized message
The localization is inside of a DB table
Would it be wrong something like this:
public class MyException{
public MyException(int code){
try{
this.message = db.selectMessage(code);
}catch(Exception ex){
this.message = "";
}
}
}
This would completely hide from the thrower the fact that the message is localized.
Alternatively I should go with something like this:
public class ExceptionUtils{
public static throwMyException(int code) throws MyException{
String message = db.selectMessage(code);
throw new MyException(code, message);
}
}
But this requires the thrower to know about this util.
I would suggest using ResourceBundle class as it is widely accepted way for localization. This way you store your messages in files as oppose to DB. Also reading your messages from those files is handled by JVM and you don't have to write your own code for it. However, if you insist on using DB, I would sudgest to read all your messages from DB into file system or onto your memory during your app initialization and then you don't have to read from DB and risk DB connectivity failure for each exception.
This is a better approach:
public class MyException extends Exception {
private int code;
public MyException(String message, int code) {
super(message);
this.code = code;
}
public int getCode() {
return code;
}
}
Usage:
Integer messageCode = null;
try {
// do stuff
} catch (MyException e) {
logger.log(e.getMessage(), e); // log actual message
messageCode = e.getCode();
}
if(messageCode != null /* && you really want to show it to end user */) {
String localizedMessage = db.selectMessage(code);
// show localized message to end user
}
Adavantages:
You don't need a Util class to throw exceptions.
You don't need to access db every time you throw an exception but
only when you catch it and "decide" to fetch the message if you want
to show it to user.
You don't need to catch an exception inside another exception.
You don't lose the actual non-localized message.
You don't lose actual stack trace in case db.getMessage() fails and throws exception.
Edit:
There is a dispute about whether the if part is a good idea or not so I have to elaborate.
message and localized version of message, these are very different.
Message:
is a description of what has gone wrong.
is what you see in console and in log records when exception occurs.
is in English.
must be shown regardless of any conditions and if not shown it's considered a very bad practice.
Localized Message:
is a translation of Message for the benefit of End User and not programmer.
is not in English.
is not expected to be shown either in console or log records.
is only needed when interacting with End User in UI.
is not expected to be used in non-UI related parts of code.
In the actual code provided by asker, message is replaced by localized message which violates expected behavior of a well-designed exception so I separated these two. In my code the message is Always shown and can be logged whenever exception occurs regardless of any conditions; Fetching localized message occurs only IF you actually need to interact with End Users. So access to DB can be skipped when you are not interacting with them.
the catch block is designed to do some actions after an exception occurs in your program, hence i would recommend you to provide some of the exception handling code in the catch block as it will allow others to understand your program efficiently
It is not bad as long it is code that helps you best handle the exception
The problem is one of too many moving parts. If your database access within the catch block fails by throwing an exception - and it can fail for any one of a number of reasons - then you won't ever see even your original exception. The same goes for anything you do in the catch block that could itself throw an exception.
This has recently happened to me, in fact, in legacy code (different language though same idea). Man is that a pain when you know your production system is failing for some specific reason but you have no idea what that specific reason is ...
It may be the case that your routine db.selectMessage() is itself protected against and won't throw an exception. Ok then. But it's going to be your responsibility to check that in every catch block you write. It's better to go with a design approach that doesn't involve catch blocks that do much of anything except things known to be 'safe'.
In some languages, by the way, catching all exceptions catches some really nasty ones (in Java, those aren't usually subclasses of java.lang.Exception though). And sometimes you really don't want to do anything unnecessary, 'cause you don't know what state you're in and what'll happen.
In this case, you're probably going to be logging that exception somewhere (or otherwise notifying the user). That logging code is (or should be) centralized in your application. That's the place to carefully translate/localize/interpret the exception code ... someplace where in one place you can make sure it works and is protected ... same as the logging code itself.
I have a static method used to get the title from a PDF using the metadata via itext, which is used as a small part of a major Task.
I noticed an inexplicable path that I narrowed down to this section of code. Specifically, in the line where I instantiate a PdfReader, the process doesn't throw an exception or continue through to the print statement. In fact, it clears out all of my for loops up to the top level of my program and acts as if nothing has happened and my task completed.
try {
System.out.println("Entered method");
PdfReader myReader = new PdfReader(file.getAbsolutePath());
System.out.println("Reader instantiated"); //if no issues, prints to console
Map<String, String> info = myReader.getInfo();
System.out.println(info.get("Title"));
return info.get("Title");
} catch (IOException e) {
System.out.println("PdfReader throws exception"); //if issues, prints to console
e.printStackTrace();
}
Unless I'm mistaken, when this set of code is executed in my method, either "Reader Instantiated" or "PdfReader throws exception" is printed out to the console.
Neither happens. Instead, the process skips every if/for/while loop it is currently in and ends the task.
I'm wondering if someone can explain to me what is happening and how I should go about fixing it?
In the odd event this is searched for, yes, catching Throwable stops the thread from bailing out. I had never seen something like this before. The cause behind the problem was that a PDF was password-protected, so getInfo() failed.
I have multiple Jasper Reports (with sub-reports) throughout my application. For some reason, one report (that also contains sub-reports) isn't working anymore. After debugging more than 1 day, I found out that it enters an infinite loop and keeps creating Threads for sub-report filling.
Debugger keeps looping between:
JRSubReportRunnable.java
public void run()
{
running = true;
error = null;
try
{
fillSubreport.fillSubreport();
}
catch (JRFillInterruptedException e)
{
//If the subreport filler was interrupted, we should remain silent
}
// we have to catch Throwable, because it is difficult to say what would happen with the master
// filler thread in case we don't
catch (Throwable t) //NOPMD
{
error = t;
}
running = false;
}
The above method starts a Thread in order to fill a sub-report. Once done, sets running = false and the debugger gets to:
JRThreadSubreportRunner.java
public void run()
{
super.run();
if (log.isDebugEnabled())
{
log.debug("Fill " + subreportFiller.fillerId + ": notifying of completion");
}
synchronized (subreportFiller)
{
//main filler notified that the subreport has finished
subreportFiller.notifyAll();
}
}
Once the thread finishes, it gets to the above's method subreportFiller.notifyAll(); line. Then, the debugger goes back to JRSubreportRunnable.java, and so on.
Theoretically, if I have 5 sub-reports, it should create 5 threads (works for me for other reports). Unfortunately, for this case, it keeps creating threads, and my debugger gets "stuck" between the 2 methods mentioned above (FYI: the classes are from the jasperreports-3.7.6-sources.jar).
Also tried:
I found a similar StackOverflow question, but the answer proposed there did not work for me. Neither did any of the proposed solutions from this thread on the JasperSoft Community.
I really cannot figure why this issue appears. I am sure it is something minor as it used to work. Hopefully someone else stumbled upon this and might have a solution. Thanks in advance for any answer. (I know I haven't provided really much info about the content of my sub-reports, but it is pretty private; nevertheless, I can assure you that the contents of the report and associated sub-reports did not change - checked with Git)
I had the exact same problem and solved it by changing the isPrintWhenDetailOverflows property of my subreport from true to false
as suggested here:
http://community.jaspersoft.com/questions/527078/infinite-loop-subreport-fill
hope it helps
EDIT:
After making all the changes you suggested, the problem remained. The debugger said the lemma variable was null, but the fixes I applied didn't make things better. So, due to deadline issues, I decided to approach the problem from another view. Thank you all for your help. :)
I am writing a small program and a NullPointerException drives me crazy. I have two classes: SystemDir and Search. The first one is just an encapsulation of initial directory and a search lemma. The Search class is shown below. Briefly, I want one thread to search the first level directory and the other one to expand the subdirectories. That's where I get the exception. The exception string is
Exception in thread "Thread-0" java.lang.NullPointerException
at Search.searchFiles(Search.java:59)
at Search.<init>(Search.java:53)
at SystemDir.<init>(SystemDir.java:61)
at Search$1.run(Search.java:45)
at java.lang.Thread.run(Thread.java:679)
Where the 3 points are t.start() inside the final loop, searchFiles method call, some lines above and the new SystemDir call in the run method. Can you help me please?
public class Search {
private Thread t;
public Search(String[] subFiles, final String[] subDir, final String lemma) {
t = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0;i<subDir.length;i++) {
try {
System.out.println(subDir[i]);
new SystemDir(subDir[i], lemma);
}
catch (NoDirectoryException ex) {
Logger.getLogger(Search.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
});
searchFiles(subFiles,lemma);
}
private void searchFiles(String[] subFiles, String lemma) {
for(int i=0;i<subFiles.length;i++) {
t.start();
if(subFiles[i].contains(lemma)) {
System.out.println(subFiles[i]);
}
}
}
}
As a rule, never start a thread from a constructor. It can create all sorts of issues, which may be responsible for the exception you get.
Create the thread like you do in your constructor, make searchFiles public and call that method from the client code, not from the constructor.
Apart from that, have you checked that:
subFiles is not null
none of the subFiles[i] is null
lemma is not null
(add println statements if necessary)
and as pointed out by #Gray, you can't start a thread more than once.
You have failed to posted the source code for SystemDir, but the stack trace says that its constructor is trying to create a new Search object in addition to the one that created the thread in the first place.
More concretely, probably the new Search(...) expression somewhere in SystemDir's constructor is passing null for subFiles. Is there a call to File.list() somewhere that you haven't checked for a null return from, perhaps? Note that list() returns null if it cannot list a directory at all, due to anything from missing permissions to directory-not-found.
Also, It appears you're attempting to start the same thread object more than once. That will cause an IllegalThreadStateException if there is ever more than one element in subFiles.
You have not included all the code.
With the information provided:
in searchFiles either t, subFiles, or subFiles[i] is null.
Your code itself doesn't make much sense.
That makes it hard to spot the error.
I recommend using the Eclipse debugger, and check WHICH value is null.
As far as I can tell, your problem is within the recursion into SystemDir, where you don't provide the code of.
In your searchFiles method, what is the point of starting the thread in a loop? Do you want to run the thread on each execution of the loop? I think you are missing something here.
Check if some value that you are passing to the constructor is null.
This is gonna be a big mess to explain, but if anyone has any pointer, Please share!
From an applet I'm calling a 3rd parity lib which uses JNI do fetch some info in an OS specific manner. I don't know what it calls since I don't have the code and support isn't very responsive.
The thing is, all works well on windows (not just my machine) but on Mac OS one of the lib's methods throws a lib specific exception (a code and a "Cannot complete" ~message). It seems to be a security related issue since the method works when I call it from within init().
The jar with my applet is self-signed, the library has 4 more jars that are signed by the vendor. The lib's method is called from within an "AccessController.doPrivileged" block as an applet method that is called from JavaScript - and this all works, but on windows only.
On Mac this call from JavaScript to the applet method that calls the lib's method gets the exception.
Here is what I tried:
I moved the lib's method call in init() just for the test and it works ok, only without an "AccessController.doPrivileged" block.
I tried starting a Thread in init() (in start() as well):
- using a timer to have the Thread calls the lib's method every 10sec works fine and I can get the updated reply troughs a String buffer - this isn't a preferred solution.
- but if I use a flag in the thread so that the applet method can return the result it throws the same exception.
Here is the code in my applet's method:
checkRunner.refreshWindowsList = true;
while (checkRunner.refreshWindowsList) {
try {
Thread.sleep(300);
} catch (Exception ex) {
System.out.println("Ignoring exception: " + ex.getMessage());
}
}
return checkRunner.windowsTitles;
and in the Thread's run method:
try {
while (true) {
if (refreshWindowsList) {
windowsTitles = getWindowsTitlesPrivileged();
//windowsTitles = getWindowsTitles();
refreshWindowsList = false;
}
Thread.sleep(300);
}
} catch (Exception ex) {
System.out.println("Ignoring exception: " + ex.getMessage());
}
I don't understand how just passing a flag can cause the different results.
Furthermore, it seems that when the applet is created from JavaScript code all of it is sandboxed and the lib's method throws the exception even from init() ... again only on Mac OS.
If anyone made it this far - Thank You : )
To answer my question, even thought I highly doubt this is a common problem...
It turns out that the issue is not security related after all. The problem originates because of a quite inexplicable (to me) behaviour of the 3rd parity library - whenever the problematic method is called, even in a separate thread, and in the main thread their is a loop to wait for the answer - the exception is thrown.
So the following code fails, but when the sleep line at the end is removed it works ok. This happens no matter where the code is, init() or a method called from JavaScript - the behaviour is the same.
new Thread(new Runnable() {
public void run() {
AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
callTheMehod();
}
});
}
}).start();
try { Thread.sleep(5000); } catch (exce....) {}
I ended up splitting the code into two methods called from JavaScript - one that calls the library method, putting the result in a volatile String and another that simply returns this volatile String. In JavaScript their is a waiting loop between the two. Strange thing is that if this loop has an interval that is very short - and the method to check for the result is called too often the library method fails again.
So it seems whenever there is too much load on the main thread the exception is thrown. This is quite inexplicable to me but since the library is using JNI I guess is a lot that could go wrong.