Simple EJB session client - problems with the JNDI lookup

I trying to make a simple  EJB session client work (I'm running the client from within Oracle9i Jdeveloper) but I get the following error:

javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file:  java.naming.factory.initial
      at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:640)
      at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:243)
      at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:280)
      at javax.naming.InitialContext.lookup(InitialContext.java:347)
      at examples.HelloClient.main(HelloClient.java:36)

Please help

Here is the code:

package examples;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Properties;

/** This class is an example of client code which invokes
 * methods on a simple stateless session bean. */
public class HelloClient {

      public static void main(String[] args) throws Exception {
            /* Setup properties for JNDI initialization.
             * These properties will be read-in from
             * the command-line. */
            Properties props = System.getProperties();

            /* Obtain the JNDI initial context.
             * The initial context is a starting point for
             * connecting to a JNDI tree. We choose our JNDI
             * driver, the network location of the server, etc
             * by passing in the environment properties. */
            Context ctx = new InitialContext(props);

            /* Get a reference to the home object - the
             * factory for Hello EJB Objects */
            Object obj = ctx.lookup("HelloHome");


            /* Home objects are RMI-IIOP objects, and so
             * they must be cast into RMI-IIOP objects
             * using a special RMI-IIOP cast. */
            HelloHome home = (HelloHome)
                  javax.rmi.PortableRemoteObject.narrow(
                        obj, HelloHome.class);

            /* Use the factory to create the Hello EJB Object */
            Hello hello = home.create();

            /* Call the hello() method on the EJB object.  The
             * EJB object will delegate the call to the bean,
             * receive the result, and return it to us.
             *
             * Print the result to the screen. */
            System.out.println(hello.hello());

            /* Done with EJB Object, so remove it.
             * The container will destroy the EJB object. */
            hello.remove();
      }
}

package examples;

import javax.ejb.SessionContext;

/**
 * Stateless session bean */
public class HelloBean implements javax.ejb.SessionBean
{
    // EJB-required methods
    public void ejbCreate()
    {
        System.out.println("ejbCreate()");
    }

    public void ejbRemove()
    {
        System.out.println("ejbRemove()");
    }

    public void ejbActivate()
    {
        System.out.println("ejbActivate()");
    }

    public void ejbPassivate()
    {
        System.out.println("ejbPassivate()");
    }

    public void setSessionContext(SessionContext ctx)
    {
        System.out.println("setSessionContext()");
    }

    // Business methods
    public String hello()
    {
        System.out.println("hello()");
        return "Hello, World!";
    }
}

package examples;
/** This is the HelloBean remote interface. */
public interface Hello extends javax.ejb.EJBObject
{
  /* The one method - hello - returns a greeting to the client. */
  public String hello() throws java.rmi.RemoteException;
}

package examples;
/**This is the home interface for HelloBean.*/
public interface HelloHome extends javax.ejb.EJBHome
{
    /** This method creates the EJB Object.
     * @return The newly created EJB Object. */
    Hello create() throws java.rmi.RemoteException,
        javax.ejb.CreateException;
}

package examples;
/**This is the HelloBean local interface.*/
public interface HelloLocal extends javax.ejb.EJBLocalObject
{
  /** The one method - hello - returns a greeting to the client. */
  public String hello();
}

package examples;
public interface HelloLocalHome extends javax.ejb.EJBLocalHome
{
    /**This method creates the EJB Object.
     * @return The newly created EJB Object. */
    HelloLocal create() throws javax.ejb.CreateException;
}

I also need somone to make a simple example of how to invoke a EJB entity object from with the session bean
mhci_nneAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mhci_nneAuthor Commented:
by the way I'm using the j2sdk1.4.2_04
0
Mayank SAssociate Director - Product EngineeringCommented:
>> Properties props = System.getProperties();

Did you try with no properties:

InitialContext ctx = new InitialContext () ;

Otherwise, You need to set the initial context factory and provider URL.

props.put ( "javax.naming.factory.initial", "class name for initial context factory" ) ;

or

props.put ( Context.INITIAL_CONTEXT_FACTORY, "class name for initial context factory" ) ;

And also props.put ( Context.PROVIDER_URL, "the provider URL" ) ;
0
mhci_nneAuthor Commented:
Hi mayankeagle

I have now tried that, but no difference, however I  found this as http://download-east.oracle.com/docs/cd/B25221_04/web.1013/b14428/usclient.htm#BABBBGDF under Accessing an EJB 2.1 EJB Using RMI from a Standalone Java Client:

    Hashtable env = new Hashtable();

    env.put(Context.INITIAL_CONTEXT_FACTORY,"oracle.j2ee.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "oc4jadmin");
    env.put(Context.SECURITY_CREDENTIALS, "password");
    env.put(Context.PROVIDER_URL,"ormi://localhost:23891");
Have also tried:
 env.put(Context.PROVIDER_URL,"opmn:ormi://3eCode:classes2/examples");
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

mhci_nneAuthor Commented:
but not I get the following error:
javax.naming.NoInitialContextException: Cannot instantiate class: oracle.j2ee.rmi.RMIInitialContextFactory [Root exception is java.lang.ClassNotFoundException: oracle.j2ee.rmi.RMIInitialContextFactory]

    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:652)

    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:243)

    at javax.naming.InitialContext.init(InitialContext.java:219)

    at javax.naming.InitialContext.<init>(InitialContext.java:195)

    at examples.HelloClient.main(HelloClient.java:46)

Caused by: java.lang.ClassNotFoundException: oracle.j2ee.rmi.RMIInitialContextFactory

    at java.net.URLClassLoader$1.run(URLClassLoader.java:199)

    at java.security.AccessController.doPrivileged(Native Method)

    at java.net.URLClassLoader.findClass(URLClassLoader.java:187)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:289)

    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:274)

    at java.lang.ClassLoader.loadClass(ClassLoader.java:235)

    at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:302)

    at java.lang.Class.forName0(Native Method)

    at java.lang.Class.forName(Class.java:219)

    at com.sun.naming.internal.VersionHelper12.loadClass(VersionHelper12.java:42)

    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:649)

    ... 4 more

Exception in thread "main"
Process exited with exit code 1.
0
Mayank SAssociate Director - Product EngineeringCommented:
Are you using Oracle JVM or Sun's JVM?
0
Mayank SAssociate Director - Product EngineeringCommented:
>> java.lang.ClassNotFoundException: oracle.j2ee.rmi.RMIInitialContextFactory

then you are not using Oracle's JVM.
0
Mayank SAssociate Director - Product EngineeringCommented:
Did you try with simply new InitialContext () without any params?
0
mhci_nneAuthor Commented:
my ebj-jar-xml looks the following:
<?xml version = '1.0' encoding = 'windows-1252'?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
  <enterprise-beans>
    <session>
      <description>Session Bean ( Stateless )</description>
      <display-name>Hello</display-name>
      <ejb-name>Hello</ejb-name>
      <home>examples.HelloHome</home>
      <remote>examples.Hello</remote>
      <local-home>examples.HelloLocalHome</local-home>
      <local>examples.HelloLocal</local>
      <ejb-class>examples.HelloBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
    </session>
  </enterprise-beans>
</ejb-jar>

and my orion-ejb-jar.xml looks the following:

<?xml version = '1.0' encoding = 'windows-1252'?>
<!DOCTYPE orion-ejb-jar PUBLIC "-//Evermind//DTD Enterprise JavaBeans 1.1 runtime//EN" "http://xmlns.oracle.com/ias/dtds/orion-ejb-jar.dtd">
<orion-ejb-jar>
  <enterprise-beans>
    <session-deployment max-instances="-1" name="Hello"/>
  </enterprise-beans>
  <assembly-descriptor>
    <default-method-access>
      <security-role-mapping impliesAll="true" name="&lt;default-ejb-caller-role>"/>
    </default-method-access>
  </assembly-descriptor>
</orion-ejb-jar>
0
Mayank SAssociate Director - Product EngineeringCommented:
The JAR XML is fine, its the client which is causing the problem.
0
mhci_nneAuthor Commented:
yes I tried with a new InitialContext () without any params, but I received the same error message as to begin with
0
mhci_nneAuthor Commented:
yes I'm using the Sun's JVM (j2sdk1.4.2_04)
0
mhci_nneAuthor Commented:
Thanks, just wanted to be sure (long time since I done any J2EE)
0
Mayank SAssociate Director - Product EngineeringCommented:
What is the provider URL you tried?
0
mhci_nneAuthor Commented:
by the way it's the same error when I use props.put(...)
0
Mayank SAssociate Director - Product EngineeringCommented:
InitialContext without params would also not work as you need to specify the provider URL. Was checking if the exception was the same. The EJB is hosted remotely in a container - so you need to specify the URL
0
Mayank SAssociate Director - Product EngineeringCommented:
>> by the way it's the same error when I use props.put(...)
 
What URL did you try
0
mhci_nneAuthor Commented:
[Starting OC4J using the following ports: HTTP=8988, RMI=23891, JMS=9227.]

I tried the following:
props.put ( Context.INITIAL_CONTEXT_FACTORY, "oracle.j2ee.rmi.RMIInitialContextFactory" ) ;
props.put("java.naming.provider.url", "localhost:8988");

props.put ( Context.INITIAL_CONTEXT_FACTORY, "oracle.j2ee.rmi.RMIInitialContextFactory" ) ;
props.put("java.naming.provider.url", "localhost:23891");
0
mhci_nneAuthor Commented:
   props.put ( Context.INITIAL_CONTEXT_FACTORY, "oracle.j2ee.rmi.RMIInitialContextFactory" ) ;
    props.put("java.naming.provider.url", "localhost:9227");
0
mhci_nneAuthor Commented:
but the same error :-(
0
Mayank SAssociate Director - Product EngineeringCommented:
Its not the Oracle context factory. Its the Sun context factory to be used. Maybe that's set as the default in JDK, so just try the URL:

props.put ( Context.PROVIDER_URL, "rmi://localhost:23891" ) ;
0
mhci_nneAuthor Commented:
no still the same error with props.put ( Context.PROVIDER_URL, "rmi://localhost:23891" ) ;
0
mhci_nneAuthor Commented:
if I were to write something like this how whould that be in my case?
put(Context.PROVIDER_URL,"opmn:ormi://myServer:oc4j_inst1/ejbsamples)
0
Mayank SAssociate Director - Product EngineeringCommented:
Perhaps try "rmi://myServer:oc4j_inst1/ejbsamples"
0
mhci_nneAuthor Commented:
No it didn't help, just wanted to try
0
Mayank SAssociate Director - Product EngineeringCommented:
Maybe try just "rmi://myServer:23891" - I think that should have worked
0
mhci_nneAuthor Commented:
In the sample:
http://jaitechwriteups.blogspot.com/2006/07/accessing-secure-ejb-through.html
he does like this (is that not what I did?)

/* Now that the user has logged in, invoke the method on the EJB    */  
Context context = new InitialContext();  
//lookup the home object  
Object lookupObj = context.lookup("MyTestEJBHomeJndiName");  
MyTestEJBHome home = (MyTestEJBHome) PortableRemoteObject.narrow(lookupObj, MyTestEJBHome.class);  
//create the bean object from the home object  
MyTestEJB myBean = home.create();
0
mhci_nneAuthor Commented:
The other link use the ibm.websphere so how does that help (I have to use OC4J as a EJB container in the Oracle9i Jdev)
0
mhci_nneAuthor Commented:
I found a solution:

package examples;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import examples.Hello;
import examples.HelloHome;
import javax.naming.NamingException;

public class HelloClient1
{
  public static void main(String [] args)
  {
    HelloClient1 helloClient1 = new HelloClient1();
    try
    {
      Context context = getInitialContext();
      HelloHome helloHome = (HelloHome)PortableRemoteObject.narrow(context.lookup("Hello"), HelloHome.class);
      Hello hello;

      // Use one of the create() methods below to create a new instance
      hello = helloHome.create();
     
      // Call any of the Remote methods below to access the EJB
      System.out.println(hello.hello());

    }
    catch(Throwable ex)
    {
      ex.printStackTrace();
    }

  }

  private static Context getInitialContext() throws NamingException
  {
    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "admin");
    env.put(Context.SECURITY_CREDENTIALS, "welcome");
    env.put(Context.PROVIDER_URL, "ormi://localhost:23891/current-workspace-app");

    return new InitialContext(env);
  }
}

How ever I not sure I understand how to connect to the local interface (that's what I need if I have a Session Bean
invoking a EJB entity bean right?
0
Mayank SAssociate Director - Product EngineeringCommented:
You can invoke an EJB using local or remote interfaces. Depends on whether they are deployed in the same app server instance or not. If yes, making local calls saves performance because there is no serialization/ de-serialization of parameters involved. Making remote calls is costlier but it allows better distribution of components. In case of local interfaces, your home interface has to implement the EJBLocalHome interface and you don't need to use PortableRemoteObject.narrow ()
0
Mayank SAssociate Director - Product EngineeringCommented:
>> that's what I need if I have a Session Bean invoking a EJB entity bean right

If its in the same container - yes. See this to learn local calls:

http://www.onjava.com/pub/a/onjava/2004/11/03/localremote.html
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mhci_nneAuthor Commented:
Thanks :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java EE

From novice to tech pro — start learning today.