0

I have some problem with my simple exercise program. I want to call a session bean from thread but it become NullPointer exception! but if I call it from a main thread it can run normally

this is warning and exception

Warning: C:\Documents andSettings\User\MyDocuments\NetBeansProjects\ThreadCounter\dist\gfdeploy\ThreadCounter does not exist.
Exception in thread "Thread-2" java.lang.NullPointerException
at threadcounter.Main.run(Main.java:14)
at java.lang.Thread.run(Thread.java:744)

This is runnable class which calling remote session bean

package threadcounter;

import javax.ejb.EJB;
import mysessionbean.CounterSessionBeanRemote;

public class Main implements Runnable {
@EJB
private static CounterSessionBeanRemote counterSessionBean;

@Override
public void run() {
 System.out.println("counter : "+counterSessionBean.getCounter());  //NullPointer
  } 
}

this is my main function

package threadcounter;

public  class Ya {

public static void main(String[] args){
Main t1 = new Main();
new Thread(t1).start();
  }

}

and this is session bean

package mysessionbean;

import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.Stateless;

@Stateless
public class CounterSessionBean implements CounterSessionBeanRemote {
private int counter = 0;

@Override
public int getCounter() {
    int temp = counter;
    temp++;
    Random r = new Random();
    try {
    Thread.sleep(r.nextInt(20));
    } catch (InterruptedException ex) {
    Logger.getLogger(CounterSessionBean.class.getName()).log(Level.SEVERE, null, ex);
    }
    counter = temp;
    return counter;
}


}
Robin Green
  • 32,079
  • 16
  • 104
  • 187
cherry
  • 37
  • 1
  • 1
  • 9
  • is the counterSessionBean injected properly?? – bjhaid Nov 23 '13 at 19:14
  • I think I have injected it properly, I do everything follow to my teacher's instruction but the difference is my client must be threads not a single main program, so I don't know I 'm doing something wrong with threads. – cherry Nov 24 '13 at 03:59

2 Answers2

1

I've figured it out! I have to inject session bean in main function and hand on the session bean to threads with constructor like this

package threadcounter;

import javax.ejb.EJB;
import mysessionbean.CounterSessionBeanRemote;

public class Main implements Runnable {
    @EJB
    private static CounterSessionBeanRemote counterSessionBean;
    Main(CounterSessionBeanRemote x){
        counterSessionBean = x;
    }
   @Override
   public void run() {
   System.out.println("counter : "+counterSessionBean.getCounter());   
   }
}

this is class that contain main function

package threadcounter;

import javax.ejb.EJB;
import mysessionbean.CounterSessionBeanRemote;
public  class Ya {
 @EJB
private static CounterSessionBeanRemote counterSessionBean;

  public static void main(String[] args){
  Main t1 = new Main(counterSessionBean);
  new Thread(t1).start();
  Main t2 = new Main(counterSessionBean);
  new Thread(t2).start();
  Main t3 = new Main(counterSessionBean);
  new Thread(t3).start();
  Main t4 = new Main(counterSessionBean);
  new Thread(t4).start();
  }

}
BenMorel
  • 34,448
  • 50
  • 182
  • 322
cherry
  • 37
  • 1
  • 1
  • 9
1

You cannot inject an EJB with @EJB in a not container manged class like this

@EJB
private static CounterSessionBeanRemote counterSessionBean;

Your class should be a container managed to make it work. Otherwise you can do it with jndi lookup

Context jndiContext = new InitialContext();
CounterSessionBeanRemote bean = (CounterSessionBeanRemote ) jndiContext.lookup("....");

Another thing is: why would you use @EJB annotation and then assign a value later in the constructor? There is no point in doing this.

You may want to read through at least this http://docs.oracle.com/javaee/6/tutorial/doc/gipjf.html#girfl to make your simple exercise done well.

jjd
  • 2,158
  • 2
  • 18
  • 31