0

I have the following piece of code:

map =  db_.treeMapCreate(validMapName_)
          .keySerializer(Serializer.LONG)
          .valueSerializer(Serializer.LONG)
          .make(); //mapDB
protected void onTaskCompletion(TaskInfo task)
{
   long startBlk = task.blkId;
   long count = task.count;
   for (int i=0; i < count; ++i)
   {
      long blk = startBlk + i;
      Long oldVal = map.get(blk); //NPE here
      ...
      ...
   }
}

How is it possible to get an NPE while autoboxing? I can understand getting an NPE on unboxing i.e. if I had:

long oldVal = map.get(blk)

then that can throw an NPE.

Edit: Map isn't null. To be more specific, inside the BTreeMap code of mapDB, this line gets executed:

if(key==null) throw new NullPointerException();

In case someone wants to take a look: BtreeMap of mapDB Line: 1024

Partial stacktrace:

java.lang.NullPointerException
        at org.mapdb.BTreeMap.get(BTreeMap.java:1024)
        at org.mapdb.BTreeMap.get(BTreeMap.java:1013)
        at com.service.onTaskCompletion(TaskHandler.java:312)

I'm unable to reproduce it so I cannot give a minimal, verifiable example. I have tried to run it so that I perform a get() for a key that doesn't exist, and it DOESN'T give an NPE.

user1715122
  • 947
  • 1
  • 11
  • 26
  • 2
    Are you **absolutely sure** that map isn't null? Have you actually tested this in a line of code placed just above the involved line? i.e., `System.out.println("is map null: " + (map == null));` – Hovercraft Full Of Eels Dec 08 '15 at 22:57
  • Is your map custom data structure? – Iliiaz Akhmedov Dec 08 '15 at 22:59
  • Variable "map" isn't null else this will get hit at the start itself, i.e. as soon as this code gets hit, which isn't the case. Once created, it never changes, so it doesn't become null later. – user1715122 Dec 08 '15 at 23:25
  • 2
    It is obviously time for a [minimal, complete, and verifiable example](http://stackoverflow.com/help/mcve). It is currently impossible to answer this question, if you say that `map` is not `null`. And is there a reason for not adding the stacktrace? – Tom Dec 08 '15 at 23:51
  • @Tom I know that chances of map being null is discussed and overruled, I am curious to know if map.get(key) returning null or throwing NPE (as shown in my answer). What do you think? – Raf Dec 09 '15 at 00:51
  • What happens if you put `Long boxedBlk = blk;` just before the call to `map.get()` and then pass `boxedBlk` to that call? Is `boxedBlk` ever null? – Julian Wright Dec 09 '15 at 02:11
  • 1
    @Raf The stacktrace makes it clear, that the NPE comes from the `BTreeMap` class itself. Even if it would return `null` (what it could), it wouldn't be a problem, because the program would end up with `Long oldVal = null`, which is ok. – Tom Dec 09 '15 at 10:52
  • @user1715122 Like Worakarn Isaratham said in his answer: please don't look at GitHub to see what is happening in your library. Use your local version instead, because it could be a different version and the line numbers may differ. – Tom Dec 09 '15 at 10:53
  • @Tom thanks for pointing out, the recently added stacktrace makes sense. – Raf Dec 09 '15 at 12:06

4 Answers4

2

I think the problem is that you are looking at the wrong version of the BTreeMap code. If you go back to the previous commit of this class, line 1024 is not:

if(key==null) throw new NullPointerException();

but:

while(!A.isLeaf()) {...}

where A is set by:

BNode A = engine.get(current, nodeSerializer);

This makes much more sense. Basically, null is returned from engine.get. How that is possible is beyond my understanding, but this could very well be a bug of mapdb itself.

Worakarn Isaratham
  • 1,034
  • 1
  • 9
  • 16
1

The NPE could be due to any of the following:

  1. Map being null
  2. Passing a null value to get method (not the case)
  3. Passing a key to get() that does not exist in MapDB

I am more concerned about number 3 in here because, if you pass a key that does not exist then null is returned and trying to store null in Long oldVal cause the exception (I believing that something as follow happens):

Long l = new Long(null); //NPE

To find one whether it is #3 do the following

//if key don't exist MapDB returns null
if(map.get(blk) != null) { //not null } else { //yes null}

To find out if map is null obviously as pointed out by others, you do as follow

//invoking get on a null can cause NPE too, so another reason
if(map != null) { // not null } else { //yes null}

To support the fact that #3 could be causing the NPE, see this post with a similiar issue.

Looking into the docs for BTreeMap the get(Object) below

public V get(Object key)
Specified by:
get in interface Map<K,V>
Overrides:
get in class AbstractMap<K,V>

Looking at Map and AbstractMap the get(Object key) is specified as follow:

Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.

get(Object) of Map<K,V> and AbstractMap<K,V> returns null if no mapping is found. It is also capable of throwing NullPointerException. So #3 could still be the case that there is no entry for the key passed to get method in map.

Raf
  • 7,505
  • 1
  • 42
  • 59
  • 1
    The issue you mentioned isn't the same since that person was returning an int and since instance.get("a's") returned a null, it caused an NPE. Again, that is a problem with unboxing i.e. null Integer being converted into an int – user1715122 Dec 09 '15 at 01:42
0

NPE is because map object is null and you are referring to get() method of null,thereby NPE. Do check of map for null and you will find your solution.

if(map!=null){
long oldVal = map.get(blk);}
 else {
System.out.println("Map is null");
}
Naruto
  • 4,221
  • 1
  • 21
  • 32
0

I see only one possibility: The variable "map" is null.

Your code sample is incomplete, as you didn't show and where "map" is really initialized.

Andreas Vogl
  • 1,776
  • 1
  • 14
  • 18