Question: I'm having a weird problem where I get a NullPointerException when injecting a singleton bean (class B) into another singleton bean (class A) where both beans are using EJB 3.1 annotations. The NPE occurs because the map is null when accessing from class A even though class B was injected.
eg:

```java
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
import javax.inject.Inject;

@Singleton
@Startup
public class A {
    @Inject
    B b;

    @PostConstruct
    public void initialise() {
        b.map.put("test", 1);
        System.out.println("A initialised");
    }
}

```

```java
import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import java.util.HashMap;

@Singleton
public class B {
    HashMap<String, Integer> map;

    @PostConstruct
    public void initialise() {
        map = new HashMap<>();
        System.out.println("B initialised");
    }
}

```

However, if I use the CDI singleton annotation for class B, the code executes as expected:

```
import javax.annotation.PostConstruct;
import javax.inject.Singleton;
import java.util.HashMap;

@Singleton
public class B {
    HashMap<String, Integer> map;

    @PostConstruct
    public void initialise() {
        map = new HashMap<>();
        System.out.println("B initialised");
    }
}

```

Is there a reason why the EJB annotation is not working in this situation?

Answer: 
There is a difference between @EJB and @Inject.
Unfortunately CDI and EJB annotations are similar but might not work the same way!

In your case the Bean B is correct injected with CDI if it is a CDI Bean (annotated with CDI Singleton annotation)

I would assume the EJB injection will work if you use @EJB instead of @Inject - if Bean B is annotated with javax.ejb.Singleton.
An important fact that many fail to realise is that an EJB client only sees a "view" of the *public methods of an EJB* where ever it is injected. 

You are attempting to access one of it's instance variables directly:

```
    b.map.put("test", 1);

```

If you add a delegate method to EJB `B`:

```
public Integer put(String key, Integer value) {
    return map.put(key, value);
}

```

and invoke it:

```
@PostConstruct
public void initialise() {
    b.put("test", 1);
    System.out.println("A initialised");
}

```

then you will get

> 
> 20:18:16,823 INFO [stdout] (ServerService Thread Pool -- 70) B initialised  
> 
>  20:18:16,824 INFO [stdout] (ServerService Thread Pool -- 70) A initialised
> 
> 
> 

as expected.

See §3 of the EJB specification for more information. Here you will find the statement:

> 
> The container provides security, concurrency, transactions, swapping to secondary storage, and other services for the session object transparently to the client.
> 
> 
> 

If you were to successfully access the instance variable directly then you would bypass all of this.