Solved

Simple EJB session client - problems with the JNDI lookup

Posted on 2007-03-24
32
5,052 Views
Last Modified: 2013-11-24
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
0
Comment
Question by:mhci_nne
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 18
  • 14
32 Comments
 

Author Comment

by:mhci_nne
ID: 18785031
by the way I'm using the j2sdk1.4.2_04
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18785722
>> 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
 

Author Comment

by:mhci_nne
ID: 18786018
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
Forrester Webinar: xMatters Delivers 261% ROI

Guest speaker Dean Davison, Forrester Principal Consultant, explains how a Fortune 500 communication company using xMatters found these results: Achieved a 261% ROI, Experienced $753,280 in net present value benefits over 3 years and Reduced MTTR by 91% for tier 1 incidents.

 

Author Comment

by:mhci_nne
ID: 18786021
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786024
Are you using Oracle JVM or Sun's JVM?
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786025
>> java.lang.ClassNotFoundException: oracle.j2ee.rmi.RMIInitialContextFactory

then you are not using Oracle's JVM.
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786033
Did you try with simply new InitialContext () without any params?
0
 

Author Comment

by:mhci_nne
ID: 18786074
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786078
The JAR XML is fine, its the client which is causing the problem.
0
 

Author Comment

by:mhci_nne
ID: 18786080
yes I tried with a new InitialContext () without any params, but I received the same error message as to begin with
0
 

Author Comment

by:mhci_nne
ID: 18786082
yes I'm using the Sun's JVM (j2sdk1.4.2_04)
0
 

Author Comment

by:mhci_nne
ID: 18786083
Thanks, just wanted to be sure (long time since I done any J2EE)
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786088
What is the provider URL you tried?
0
 

Author Comment

by:mhci_nne
ID: 18786090
by the way it's the same error when I use props.put(...)
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786094
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786098
>> by the way it's the same error when I use props.put(...)
 
What URL did you try
0
 

Author Comment

by:mhci_nne
ID: 18786129
[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
 

Author Comment

by:mhci_nne
ID: 18786134
   props.put ( Context.INITIAL_CONTEXT_FACTORY, "oracle.j2ee.rmi.RMIInitialContextFactory" ) ;
    props.put("java.naming.provider.url", "localhost:9227");
0
 

Author Comment

by:mhci_nne
ID: 18786136
but the same error :-(
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786158
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
 

Author Comment

by:mhci_nne
ID: 18786181
no still the same error with props.put ( Context.PROVIDER_URL, "rmi://localhost:23891" ) ;
0
 

Author Comment

by:mhci_nne
ID: 18786192
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786267
Perhaps try "rmi://myServer:oc4j_inst1/ejbsamples"
0
 

Author Comment

by:mhci_nne
ID: 18786283
No it didn't help, just wanted to try
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786540
Maybe try just "rmi://myServer:23891" - I think that should have worked
0
 
LVL 30

Expert Comment

by:Mayank S
ID: 18786550
0
 

Author Comment

by:mhci_nne
ID: 18787733
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
 

Author Comment

by:mhci_nne
ID: 18787737
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
 

Author Comment

by:mhci_nne
ID: 18787765
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
 
LVL 30

Expert Comment

by:Mayank S
ID: 18788931
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
 
LVL 30

Accepted Solution

by:
Mayank S earned 500 total points
ID: 18802785
>> 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
 

Author Comment

by:mhci_nne
ID: 18806226
Thanks :-)
0

Featured Post

Migrating Your Company's PCs

To keep pace with competitors, businesses must keep employees productive, and that means providing them with the latest technology. This document provides the tips and tricks you need to help you migrate an outdated PC fleet to new desktops, laptops, and tablets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you have done a reformat of your hard drive and proceeded to do a successful Windows XP installation, you may notice that a choice between two operating systems when you start up the machine. Here is how to get rid of this: Click Start Clic…
Today, still in the boom of Apple, PC's and products, nearly 50% of the computer users use Windows as graphical operating systems. If you are among those users who love windows, but are grappling to keep the system's hard drive optimized, then you s…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question