Puzzled over NullPointerException

O

ohaya

Hi,

I originally had some code (for doing an LDAP search using ldapjdk.jar)
that looked something like:

while (results.hasMoreElements())
{
LDAPEntry findEntry = null;
try
{
findEntry = results.next();
LDAPAttribute attribute = findEntry.getAttribute("cn");
Enumeration enumValues = attribute.getStringValues();
String commonName = (String)enumValues.nextElement();
System.out.println("Common name: " + commonName);
}
catch (LDAPReferralException e)
 
R

Roedy Green

But, when I did that, I started getting a NullExceptionPointer error, I
believe on the line where commonName was being assigned.

Can anyone explain why?

see
http://mindprod.com/jgloss/runerrormessages.html#NULLPOINTEREXCEPTION


Whenever you ask for help about an exception on a newsgroup make sure
you include the following:

The complete error message and complete stack trace.

The source code for at least the lowest level class you wrote
mentioned in the stack trace with the relevant lines in the stack
trace marked in the source listing.
 
R

Roedy Green

findEntry = results.next();
LDAPAttribute attribute = findEntry.getAttribute("cn");
Enumeration enumValues = attribute.getStringValues();
commonName = (String)enumValues.nextElement();
System.out.println("Common name: " + commonName);

presumably any of this code might fail returning null, and you do
nothing about it:

e.g.
LDAPAttribute attribute = findEntry.getAttribute("cn"); could be null
Enumeration enumValues = attribute.getStringValues(); could be null
commonName = (String)enumValues.nextElement();
could be null

you should code defensively to handle the null case. The line number
in your stack trace will tell you exactly there the problem is.
 
O

ohaya

Roedy said:
presumably any of this code might fail returning null, and you do
nothing about it:

e.g.
could be null

you should code defensively to handle the null case. The line number
in your stack trace will tell you exactly there the problem is.


Roedy,

I forgot to mention that I had put in a bunch of printlns, to track
down which line was blowing up, and it was the "commonName =
(String)...." line.

If I'm understanding your post, you're implying that the nextElement()
might have returned a null instead of an object, which then caused the
NullPointerException.

I agree with that, but what's really puzzling me is why the
NullPointerException only occurs if I declare commonName inside the
try???

Thanks,
Jim
 
O

Oliver Wong

ohaya said:
Hi,

I originally had some code (for doing an LDAP search using ldapjdk.jar)
that looked something like:

while (results.hasMoreElements())
{
LDAPEntry findEntry = null;
try
{
findEntry = results.next();
LDAPAttribute attribute = findEntry.getAttribute("cn");
Enumeration enumValues = attribute.getStringValues();
String commonName = (String)enumValues.nextElement();
System.out.println("Common name: " + commonName);
}
catch (LDAPReferralException e)
.
.

The above code seemed to work ok, but then I wanted to have access to
the commonName outside of the try (for some println's, etc.), so I
changed it to:

String commonName = "";
.
.
while (results.hasMoreElements())
{
LDAPEntry findEntry = null;
try
{
findEntry = results.next();
LDAPAttribute attribute = findEntry.getAttribute("cn");
Enumeration enumValues = attribute.getStringValues();
commonName = (String)enumValues.nextElement();
System.out.println("Common name: " + commonName);
}
catch (LDAPReferralException e)
.
.

But, when I did that, I started getting a NullExceptionPointer error, I
believe on the line where commonName was being assigned.

Can anyone explain why?

I'm not familiar with Java's LDAP API, but I think the answer to your
question depends critically on the code that you did NOT post. Specifically,
on the code inside the catch clause. I recommend you construct and SSCCE and
post it. (http://www.physci.org/codes/sscce.jsp)

Given that you're using the LDAP API, I'm thinking a lot of people won't
actually bother to run your code as they might not have easy access to an
LDAP service. However, if you can replicate the problem in a small snippet
about one page long, then you avoid the risk of leaving out code that might
be important for answering the question.

- Oliver
 
O

ohaya

I'm not familiar with Java's LDAP API, but I think the answer to your
question depends critically on the code that you did NOT post. Specifically,
on the code inside the catch clause. I recommend you construct and SSCCE and
post it. (http://www.physci.org/codes/sscce.jsp)

Given that you're using the LDAP API, I'm thinking a lot of people won't
actually bother to run your code as they might not have easy access to an
LDAP service. However, if you can replicate the problem in a small snippet
about one page long, then you avoid the risk of leaving out code that might
be important for answering the question.


Oliver,

I've modified the original code (that had the problem) by now, and,
unfortunately, I didn't keep an exact copy of the code when the
exception was occurring.

I've been trying to undo the changes that I think I've made since then,
but now, I can't seem to make the problem happen :(...

I guess I'll have to live with the code that I have now, which is
working...

Thanks,
Jim
 
R

Ross Bamford

I've been trying to undo the changes that I think I've made since then,
but now, I can't seem to make the problem happen :(...

I guess I'll have to live with the code that I have now, which is
working...

IMHO that is one of the most dangerous attitudes in software development -
"It just fixed itself so I left it".

(that's not a dig at you, OP, just a general observation).
 
O

ohaya

Ross said:
IMHO that is one of the most dangerous attitudes in software development -
"It just fixed itself so I left it".

(that's not a dig at you, OP, just a general observation).


Ross,

I agree, and I was a little worried that that might be the reaction to
my post.

To be clear, I have working code now, including changes that I put in
specifically to eliminate the problem, and which seem to work, and in
the newer code, I've added additional checks for nulls, etc., as someone
else suggested earlier.

I spent about half a day today so far, trying to get my code back to
where the problem was occurring, to try to reproduce the problem,
because it seemed like a strange problem, but failed in that.

I'm not saying that the problem fixed itself... it's more like I can
make my now-working code replicate the problem.

I guess that if I had not been so anxious to get things working, I
might've taken a snapshot, but I generally only do snapshots when I'm at
a point that I have working code :(...

Jim
 
R

Ross Bamford

Ross said:
IMHO that is one of the most dangerous attitudes in software
development -
"It just fixed itself so I left it".

(that's not a dig at you, OP, just a general observation).


Ross,

I agree, and I was a little worried that that might be the reaction to
my post.

[ ... ]

I'm not saying that the problem fixed itself... it's more like I can
make my now-working code replicate the problem.

I guess that if I had not been so anxious to get things working, I
might've taken a snapshot, but I generally only do snapshots when I'm at
a point that I have working code :(...

:) And who needs a broken snapshot anyway ...

You don't expect to have to roll back to the problem I guess, so why would
you ? As I say it was just a reactionary observation, brought on by the
memory of a million (or not, probably) tiny bugs that 'went away', only to
return when least expected or desired.

And that's just in stuff I wrote ;)

(Aside: If you use Eclipse, you might find the 'Local History' feature
useful - RMB -> Compare with -> Local History. Other IDEs now have similar
features. I was pleasantly surprised by it recently myself.)
 
R

Roedy Green

I forgot to mention that I had put in a bunch of printlns, to track
down which line was blowing up, and it was the "commonName =
(String)...." line.

that is a very good clue.

String commonName = (String)enumValues.nextElement();

could return null unless you did a enumValues.hasMoreElements() first
that returned true.

Hint: why would code work outside a (try) block but fail inside?

The most common source of that problem is:

Did you redeclare any variables? The variable inside the block is not
the same as the variable outside.

You did not quote enough code to see if that applies.

I need to see your whole class and also the exact code you used
without the try.
 
R

Roedy Green

I spent about half a day today so far, trying to get my code back to
where the problem was occurring, to try to reproduce the problem,
because it seemed like a strange problem, but failed in that.

what you can do in such a situation is create an inprogress directory
on your disk and copy your work there every once in a while. That lets
you back up or trace changes in a very low tech way.

For a more format system, you can use a local CVS or Subversion
server, and you check your code in periodically. That way you can back
up, or create various branches for your experiments.

see http://mindprod.com/jgloss/cvs.html
 
O

ohaya

Roedy said:
that is a very good clue.

String commonName = (String)enumValues.nextElement();

could return null unless you did a enumValues.hasMoreElements() first
that returned true.

Hint: why would code work outside a (try) block but fail inside?

The most common source of that problem is:

Did you redeclare any variables? The variable inside the block is not
the same as the variable outside.

You did not quote enough code to see if that applies.

I need to see your whole class and also the exact code you used
without the try.


Roedy,

Try as I might (I've been spending more time on it tonight... a bit
embarrased because of my inability to create the problem again), I
haven't been able to reproduce the code and problem.

But, just to answer your question, no variables were redeclared inside
the try, and (really) sorry about not having posted enough code in the
first place.

Jim
 
O

ohaya

Ross,
I agree, and I was a little worried that that might be the reaction to
my post.

[ ... ]

I'm not saying that the problem fixed itself... it's more like I can
make my now-working code replicate the problem.

I guess that if I had not been so anxious to get things working, I
might've taken a snapshot, but I generally only do snapshots when I'm at
a point that I have working code :(...

:) And who needs a broken snapshot anyway ...

You don't expect to have to roll back to the problem I guess, so why would
you ? As I say it was just a reactionary observation, brought on by the
memory of a million (or not, probably) tiny bugs that 'went away', only to
return when least expected or desired.

And that's just in stuff I wrote ;)

(Aside: If you use Eclipse, you might find the 'Local History' feature
useful - RMB -> Compare with -> Local History. Other IDEs now have similar
features. I was pleasantly surprised by it recently myself.)


Ross,

I appreciated the restraint in your earlier post. My apologies that I
didn't acknowledge it...

I do use Eclipse on occasion, but mainly for larger projects. That's
possibly another "lesson learned" (for me).

Thanks,
Jim
 
R

Roedy Green

If you were a cat, a bug is a bit like a mouse that makes an
appearance only every week or so. You have to take full advantage of
every observation.

For code of any complexity I like to just watch it run in a debugger
for a goodly while and make sure everything that happens is what I
expect. 95% of the time strangenesses are actually ok. Surprises are
easier to spot than bug droppings.

Of course writing a test harness to thoroughly exercise any class is
your best insurance, but it won't catch everything, e.g duplicate
actions.
 
R

Ross Bamford

If you were a cat, a bug is a bit like a mouse that makes an
appearance only every week or so. You have to take full advantage of
every observation.

Nicely put :)
For code of any complexity I like to just watch it run in a debugger
for a goodly while and make sure everything that happens is what I
expect. 95% of the time strangenesses are actually ok. Surprises are
easier to spot than bug droppings.

I'm not sure about that 95% of the time, but even were it true you'd want
to make sure you were actually in that 95%. Debugging / profiling is a
necessity in modern systems - sad but true. The average Java is so far
removed from the machine, and usually with parts from many sources, that
you just can't hold it all to account otherwise. For example, I can't
remember the last time I did anything bitwise If my experience has taught
me anything, it's that computers aren't supposed to surprise me.
Of course writing a test harness to thoroughly exercise any class is
your best insurance, but it won't catch everything, e.g duplicate
actions.

I love it when you see a project that's obviously been written test-first,
and they've got clover on there, and made it a roadmap target to "reach
100% coverage" - like it's a deliverable. So you look through the pretty
(enormous) clover reports and sure enough, every statement has been
executed (apart from those few they excluded at the last minute), and all
the bars are green. Every class _works_, as demonstrated by the fact that
each and every method has been called with a carefully contrived set of
arguments by another method. Sometimes several times.

Of course, any newbie can write a class to spec - it's Java 101. Writing
classes that work, _together_, in the wild, well... that's just not what's
driving the design.

How many products / projects have you seen that didn't work, or didn't
perform, purely because no-one had checked the impact of everything
working _at the same time_ during development?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top