Avatar billede callisen Nybegynder
24. marts 2007 - 15:33 Der er 13 kommentarer og
1 løsning

Simpel EJB session client - problemer med JNDI lookup

Simpel EJB session client - problemer med JNDI lookup

Jeg prøver at få en simpel EJB session client til at virke (jeg eksikvere den fra Oracle9i Jdeveloper) men jeg får følgende 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)

jeg benytter j2sdk1.4.2_04
Please hjælp:

Her er kode:
--------------------------------------

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;
}

Hvis der er nogen der kan lave et et simpelt eks. på hvordan man invoker en EJB entity object fra en EBJ session bean ville det være super cool :-)
Avatar billede arne_v Ekspert
24. marts 2007 - 16:05 #1
jeg tror at fejlen skyldes at du ikke gemmer noget i props inden du laver lookup
Avatar billede arne_v Ekspert
24. marts 2007 - 16:06 #2
bruger du OC4J som EJB container ?
Avatar billede arne_v Ekspert
24. marts 2007 - 16:07 #3
en session bean slår en entity bean på samme måde som en client slår en
session bean op

(bortset fra at der normalt bruges local interfaces og derfor ikke skal
narrow'es)
Avatar billede arne_v Ekspert
24. marts 2007 - 16:11 #4
http://www.eksperten.dk/artikler/182 har eksempler

og jeg sætter

java.naming.factory.initial
java.naming.factory.url.pkgs
java.naming.provider.url

i dem (lidt anderleds end du gør men principielt det samme)

eneste forskel er at jeg sætter dem til JBoss værdierne hvor du formentligt skal have
sat dem til OC4J værdierne
Avatar billede callisen Nybegynder
24. marts 2007 - 20:30 #5
hej arne

ja jeg bruger OC4J som EBJ container (standard i Oracle9i Jdev..)
jeg har ændret følgende efter at have kigget på 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,"opmn:ormi://3eCode:classes2/examples");
   
har også prøvet med:
    env.put(Context.PROVIDER_URL,"ormi://localhost:23891");

men jeg får følgende fejl:
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.
Avatar billede callisen Nybegynder
24. marts 2007 - 20:54 #6
min ebj-jar-xml ser således ud:
<?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>

og min or orion-ejb-jar.xml ser således ud

<?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>
Avatar billede callisen Nybegynder
24. marts 2007 - 21:21 #7
Hej Arne
Hvis jeg benytter local interfaces hvordan skal jeg gøre, og vil det løse mit problem her og nu (jeg skal jo ikke til min EBJ fra en anden maskine ud over for fornøjelsens skyl) ?
Avatar billede arne_v Ekspert
24. marts 2007 - 23:06 #8
ClassNotFoundException må skyldes at dit client program mangler jar filen med
de klasser i classpath (der nå være en Oracle EJB client jar til det)
Avatar billede arne_v Ekspert
24. marts 2007 - 23:07 #9
du kan kun bruge local calls inde i serveren

og syntaxen er den samme bortset fra at du kan nøjes med at caste fremfor at
narrowe
Avatar billede callisen Nybegynder
25. marts 2007 - 11:57 #10
Jeg har inkludert BC4J EJB Client, det burde da være OK ikke?
Avatar billede callisen Nybegynder
25. marts 2007 - 12:19 #11
Jeg har fundet en løsning der virker:

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);
  }
}

Jeg er dog ikke med på hvordan jeg kan invoke en EJB entity bean fra min EJB session Bean skal du ikke give mig et simplet eks?
Det er vel ikke mere en 1-3 linjers kode :-)
Avatar billede arne_v Ekspert
25. marts 2007 - 15:18 #12
remote:

Context context = getInitialContext();
HelloRemoteHome hrh = (HelloRemoteHome)PortableRemoteObject.narrow(context.lookup("HelloRemote"), HelloRemoteHome.class);
HelloRemote hr =  hrh.create();

local:

Context context = getInitialContext();
HelloLocalHome hlh = (HelloLocalHome)context.lookup("HelloLocal");
HelloLocal hl =  hlh.create();

(bemærk at jeg har ændret lidt på din remote navngivning for at få tydeligere navne)
Avatar billede callisen Nybegynder
25. marts 2007 - 18:01 #13
Jeg her ikke testede det, men jeg men det ser jo simpelt ud.
Hvis du vil have nogle point må du lige angive et svar :-)

Mange tak for hjælpen
Avatar billede arne_v Ekspert
25. marts 2007 - 18:27 #14
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester