简体   繁体   中英

naming exception with EJB

I'm trying to follow an online tutorial and although I'm sure the writers of the tutorial know what they are doing, I keep getting an exception upon execution.

Remote Interface

package com.tutorialspoint.stateless;

import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibrarySessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

Stateless EJB

package com.tutorialspoint.stateless;

import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;

@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {

   List<String> bookShelf;    

   public LibrarySessionBean(){
      bookShelf = new ArrayList<String>();
   }

   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    

   public List<String> getBooks() {
      return bookShelf;
   }
}

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost

tester

package com.tutorialspoint.test;

import com.tutorialspoint.stateful.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }

   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testStatelessEjb();
   }

   private void showGUI(){
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }

   private void testStatelessEjb(){

      try {
         int choice = 1; 

         LibrarySessionBeanRemote libraryBean =
         LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }       
         LibrarySessionBeanRemote libraryBean1 = 
            (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateless object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(i));
         }       
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null){
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

I get this exception:

javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory [Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]
null
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:674)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.init(InitialContext.java:244)
    at javax.naming.InitialContext.<init>(InitialContext.java:216)
    at test.EJBTester.<init>(EJBTester.java:33)
    at test.EJBTester.main(EJBTester.java:42)
Caused by: java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory
    at java.net.URLClassLoader$1.run(URLClassLoader.java:372)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:340)
    at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:72)
    at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:61)
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:672)
    ... 5 more
java.lang.NullPointerException
    at test.EJBTester.testStatelessEjb(EJBTester.java:56)
    at test.EJBTester.main(EJBTester.java:44)

your help will be very appreciated! D

When you make a remote EJB invocation, basically you need to accomplish (on the client side) the following points:

  1. add to client CLASSPATH the necessary dependencis, this is:add the remote interfaces classes and the server client classes.
  2. instantiate the InitialConetxt using the correct properties.
  3. and provide a correct lookup name.

The stacktrace shows:

java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory,

which indicates that the problem could be that the client server classes are not in the classpath.

As the tutorial indicates, the solution is:

Add jboss libraries using Add jar/folder button in compile tab. Jboss libraries can be located at > client folder.

When I looked at the code thought resolving the JNDI lookup in client would solve the problem :) that was the main problem....read my comments in client code... but as i dug more realized that this is copy paste from another training without the Book JavaBean and so on....so ended up rewriting the whole thing...

Copy the code all good to go..... Restart the server where the EJBS' are deployed. Run the Client with client .jar[gf-client.jar in glassfish] on your classpath.

The interface

package com.au.ejbs;

import java.util.List;

public interface LibraryI {
    void addBook(Book bookName);

    List<Book> getBooks();

    void clearShelf();
}

The implementation

package com.au.ejbs;

import java.util.ArrayList;
import java.util.List;
import javax.ejb.Remote;
import javax.ejb.Stateless;
@Remote
@Stateless
public class Library implements LibraryI {

    private List<Book> bookShelf = new ArrayList<Book>();

    @Override
    public void addBook(Book bookName) {
        bookShelf.add(bookName);
    }

    @Override
    public List<Book> getBooks() {
        return bookShelf;
    }

    public void clearShelf(){
        if(!bookShelf.isEmpty())
        bookShelf.clear();
    }
}

package com.au.ejbs;


import javax.ejb.Remote;
import java.io.Serializable;
import java.util.StringJoiner;

@Remote
public class Book implements Serializable {
    private String bookName;

    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    @Override
    public String toString() {
        return new StringJoiner(", ", Book.class.getSimpleName() + "[", "]")
                .add("bookName='" + bookName + "'")
                .toString();
    }

}

The Client

package com.au.clients;

import com.au.ejbs.Book;
import com.au.ejbs.Library;
import com.au.ejbs.LibraryI;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class LibraryT {

    BufferedReader brConsoleReader = null;
    Properties props;
    InitialContext ctx;

    {
        props = new Properties();
        try {
            props.load(new FileInputStream("config.properties"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        try {
            ctx = new InitialContext(props);
        } catch (NamingException ex) {
            ex.printStackTrace();
        }
        brConsoleReader = new BufferedReader(new InputStreamReader(System.in));
    }

    public static void main(String[] args) {

        LibraryT LibraryT = new LibraryT();

        LibraryT.testStatelessEjb();
    }

    private void showGUI() {
        System.out.println("**********************");
        System.out.println("Welcome to Book Store");
        System.out.println("**********************");
        System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
    }

    private void testStatelessEjb() {
        List<Book> booksList = null;
        LibraryI libraryBean = null;
        try {
            int choice = 1;

            // LibraryI libraryBean = (LibraryI)ctx.lookup("LibrarySessionBean/remote");
            libraryBean = (LibraryI) ctx.lookup("java:global/ejb3_2_ear_exploded/ejb/Library");//Portable should work on jboss and any container , works on glassfish
              //portable syntax java:global/[ ear name]/[module name normally the jar name in my case ejb.jar within the ear, ejb3_2_ear_exploded]/Class Name of EJB impl

            while (choice != 2) {
                String bookName;
                showGUI();
                String strChoice = brConsoleReader.readLine();
                choice = Integer.parseInt(strChoice);
                if (choice == 1) {
                    System.out.print("Enter book name: ");
                    bookName = brConsoleReader.readLine();
                    Book book = new Book();
                    book.setBookName(bookName);
                    libraryBean.addBook(book);
                } else if (choice == 2) {
                    break;
                }
            }

            booksList = libraryBean.getBooks();

            System.out.println("Book(s) entered so far: " + booksList.size());
            int i = 0;
            for (Book book : booksList) {
                System.out.println((i + 1) + ". " + book.getBookName());
                i++;
            }
            // LibraryI libraryBean1 = (LibraryI)ctx.lookup("LibrarySessionBean/remote");
            LibraryI libraryBean1 = (LibraryI) ctx.lookup("java:global/ejb3_2_ear_exploded/ejb/Library");//Portable should work on jboss and any container , works on glassfish
            List<Book> booksList1 = libraryBean1.getBooks();
            System.out.println(
                    "***Using second lookup to get library stateless object***");
            System.out.println(
                    "Book(s) entered so far: " + booksList1.size());
            for (i = 0; i < booksList1.size(); ++i) {
                System.out.println((i + 1) + ". " + booksList1.get(i));
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        } finally {
            try {
                if (brConsoleReader != null) {
                    brConsoleReader.close();
                    libraryBean.clearShelf();
                }


            } catch (IOException ex) {
                System.out.println(ex.getMessage());
            }
        }
    }
}

config.properties

//JNDI specific to glassfish you can use the one for jboss java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory java.naming.provider.url=remote://localhost:4447

The output

**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Road Ahead
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Living the Past
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Enjoy the Present
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 3
1. Road Ahead
2. Living the Past
3. Enjoy the Present
***Using second lookup to get library stateless object***
Book(s) entered so far: 3
1. Book[bookName='Road Ahead']
2. Book[bookName='Living the Past']
3. Book[bookName='Enjoy the Present']

Process finished with exit code 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM