Solved

Simple EJB session client - problems with the JNDI lookup

Posted on 2007-03-24
32
4,990 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
  • 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:mayankeagle
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
 

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:mayankeagle
ID: 18786024
Are you using Oracle JVM or Sun's JVM?
0
 
LVL 30

Expert Comment

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

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

Expert Comment

by:mayankeagle
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:mayankeagle
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:mayankeagle
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:mayankeagle
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:mayankeagle
ID: 18786098
>> by the way it's the same error when I use props.put(...)
 
What URL did you try
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 

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:mayankeagle
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:mayankeagle
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:mayankeagle
ID: 18786540
Maybe try just "rmi://myServer:23891" - I think that should have worked
0
 
LVL 30

Expert Comment

by:mayankeagle
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:mayankeagle
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:
mayankeagle 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

Free Gift Card with Acronis Backup Purchase!

Backup any data in any location: local and remote systems, physical and virtual servers, private and public clouds, Macs and PCs, tablets and mobile devices, & more! For limited time only, buy any Acronis backup products and get a FREE Amazon/Best Buy gift card worth up to $200!

Join & Write a Comment

Suggested Solutions

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…
Introduction This article is the first of three articles that explain why and how the Experts Exchange QA Team does test automation for our web site. This article explains our test automation goals. Then rationale is given for the tools we use to a…
The viewer will learn how to implement Singleton Design Pattern in Java.
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.

757 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now