Avatar billede fredand Forsker
15. september 2004 - 16:17 Der er 6 kommentarer og
1 løsning

Access EJB:s from an other app

Hello Mates!

I guess that I suck at EJB developing and should need some help.

I got 2 web apps at a orion server, main.ear and admin.ear. What I would like to do is to use some  EJB:s that could performe tasks for booth of the two webb apps. So my attempt is to develop a ejb-module that is standalone on the orion server and the idea is that it will work as a shared resource for the apps main.ear and admin.ear.

Booth of the web-apps works fine but I can't get access to the ejb-module from them.

In the webapps a got a Servlet (just for testing right now) that tries to access a EJB.class in the web module but I only get this exception:

Communication error: MyCacheManagerHandler not found in admin, there are no bound values
javax.naming.NameNotFoundException: MyCacheManagerHandler not found in admin, there are no bound values
        at com.evermind._jj.lookup(.:78)
        at com.evermind._bq._ex(.:121)
        at com.evermind._bq.lookup(.:63)
        at javax.naming.InitialContext.lookup(InitialContext.java:347)
        at admin.servlets.CacheManagerHandlerServlet.start(CacheManager
HandlerServlet.java:23)
        at admin.servlets.GeneralServlet.doGet(GeneralServlet.java:49)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:195)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:309)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:336)
        at com.evermind._efb._plc(.:518)
        at com.evermind._efb._adc(.:174)
        at com.evermind._cs._yqb(.:614)
        at com.evermind._cs._yrb(.:189)
        at com.evermind._bx.run(.:62)

The Servlet looks like:

package admin.servlets;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.rmi.RemoteException;
import javax.ejb.*;
import javax.naming.*;
import javax.rmi.PortableRemoteObject;

import tools.*;
import my_ejb.ejb.*;

public class CacheManagerHandlerServlet extends GeneralServlet
{
    //Called bu doPost()
    public void start(HttpServletRequest request, HttpServletResponse response) throws IOException
    {
        try
        {
            //Create access to the naming context.
            Context context = new InitialContext();

            Object object = context.lookup("java:comp/env/MyCacheManagerHandler");
            //Object object = context.lookup("ormi:localhost/my_ejb/MyCacheManagerHandler");

            CacheManagerHandlerHome cacheManagerHandlerHome = (CacheManagerHandlerHome)PortableRemoteObject.narrow(object, CacheManagerHandlerHome.class);

            CacheManagerHandler cacheManagerHandler = (CacheManagerHandler)PortableRemoteObject.narrow(cacheManagerHandlerHome.create(), CacheManagerHandler.class);

            cacheManagerHandler.list();
        }
        catch(RemoteException e)
        {
            System.err.println("System/communication error: " + e.getMessage());
            e.printStackTrace();
        }
        catch(NamingException e)
        {
            System.err.println("Communication error: " + e.getMessage());
            e.printStackTrace();
        }
        catch(CreateException e)
        {
            System.err.println("Error creating cart: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

My 3 EJB classes that I guess is correct looks like (they is packed into a jar and seems to get deployed by the server):

package my_ejb.ejb;

import java.util.*;
import javax.ejb.*;
import java.rmi.RemoteException;

public interface CacheManagerHandler extends EJBObject
{

    public void list() throws RemoteException;

    public void clear() throws RemoteException;

}

package my_ejb.ejb;

import java.rmi.RemoteException;
import javax.ejb.*;

public interface CacheManagerHandlerHome extends EJBHome
{
    public CacheManagerHandler create() throws CreateException, RemoteException;
}

package my_ejb.ejb;

import java.util.*;
import javax.ejb.*;
import java.rmi.RemoteException;

public class CacheManagerHandlerEJB implements SessionBean
{
    public void ejbCreate(){}

    public void list()
    {
        System.out.println("EJB LIST");
    }

    public void clear()
    {
        System.out.println("EJB CLEAR");
    }

    public void ejbActivate(){}

    public void ejbPassivate(){}

    public void ejbRemove(){}

    public void setSessionContext(SessionContext context){}
}

...Not so much code as you see. Just for testing right now.

To deploy this I also got a ejb-jar.xml:

<?xml version="1.0"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.2//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_1_2.dtd">

<ejb-jar>
    <display-name>My EJB</display-name>
    <description>My ejb module</description>
    <enterprise-beans>
        <session>
            <display-name>MyCacheManagerHandler</display-name>
            <description>MyCacheManagerHandler</description>
            <ejb-name>MyCacheManagerHandler</ejb-name>
            <home>my_ejb.ejb.CacheManagerHandlerHome</home>
            <remote>my_ejb.ejb.CacheManagerHandler</remote>
            <ejb-class>my_ejb.ejb.CacheManagerHandlerEJB</ejb-class>
            <session-type>Stateful</session-type>
            <transaction-type>Container</transaction-type>
        </session>         
    </enterprise-beans>
    <assembly-descriptor>
    </assembly-descriptor>
</ejb-jar>

The orion server also creates a xml-file for me when I deploy this orion-ejb-jar.xml:

<?xml version="1.0"?>
<!DOCTYPE orion-ejb-jar PUBLIC "-//Evermind//DTD Enterprise JavaBeans 1.1 runtime//EN" "http://www.orionserver.com/dtds/orion-ejb-jar.dtd">

<orion-ejb-jar deployment-version="1.6.0" deployment-time="ff025f6e89">
    <enterprise-beans>
        <session-deployment name="MyCacheManagerHandler" location="MyCacheManagerHandler" wrapper="CacheManagerHandlerHome_StatefulSessionHomeWrapper1" persistence-filename="MyCacheManagerHandler" />
    </enterprise-beans>
    <assembly-descriptor>
        <default-method-access>
            <security-role-mapping name="&lt;default-ejb-caller-role&gt;" impliesAll="true" />
        </default-method-access>
    </assembly-descriptor>
</orion-ejb-jar>


I know that this was much fact for one question but perhaps I miss something that you could see. Perhaps I'm heading the wrong way and this is not possible or a good idea at all. I have spent the day reading the orinserver doc and I think it should look like this but again I guess that I have miss something.


Hopefully you could help me with this.

Best regards
Fredrik
Avatar billede arne_v Ekspert
15. september 2004 - 20:07 #1
I do not think it is necesarry to narrow to get from home interface create method result
to remote interface.
Avatar billede arne_v Ekspert
15. september 2004 - 20:08 #2
The obvious guess is that the EJB gets a JNDI name different from
java:comp/env/MyCacheManagerHandler
Avatar billede arne_v Ekspert
15. september 2004 - 20:17 #3
Jeg kender ikke Orion men prøv:

java:comp/env/ejb/MyCacheManagerHandler
MyCacheManagerHandler
Avatar billede fredand Forsker
18. september 2004 - 17:36 #4
Hello Arne!
Just give me a svar so I can reward your help!

I finally solved how to connect to EJB:s in apps outside the app where they are located. Perhaps I should say that these apps are located at the same webserver.

On the way I received alot of exceptions, but I tracked them down one by one.

I have created a ZIP file that you can download at:
http://hem.passagen.se/millhills/HOW_TO_CONNECT_TO_EJBS.zip

It will be avialible for at least a month, after that you can email me if you would like me to send it to you. fredand44@hotmail.com

Best regards
Fredrik
Avatar billede arne_v Ekspert
18. september 2004 - 17:41 #5
answer
Avatar billede arne_v Ekspert
18. september 2004 - 17:42 #6
I assume that you either needed to lookup another name or you needed to
specify the name in an orion specific deployment descriptor.
Avatar billede fredand Forsker
18. september 2004 - 17:48 #7
Hello!

I just created a ejb-jar.xml in the ejb app:
<?xml version="1.0" encoding="UTF-8"?>

<!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>
    <display-name>ejb</display-name>
    <enterprise-beans>
        <session>
            <display-name>TestEJB</display-name>
            <ejb-name>TestEJB</ejb-name>
            <home>ejb.beans.TestHome</home>
            <remote>ejb.beans.TestRemote</remote>
            <ejb-class>ejb.beans.TestEJB</ejb-class>
            <session-type>Stateless</session-type>
            <transaction-type>Bean</transaction-type>
            <security-identity>
                <description></description>
                <use-caller-identity></use-caller-identity>
            </security-identity>
        </session>
    </enterprise-beans>
</ejb-jar>

Then I created a application-client.xml in the app that would connect to the ejb-app and put it in a META-INF folder at my classes folder:
<?xml version="1.0"?>
<!DOCTYPE application-client PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE Application Client 1.2//EN" "http://java.sun.com/j2ee/dtds/application-client_1_2.dtd">
<application-client>
    <ejb-ref>
        <ejb-ref-name>ejb/TestEJB</ejb-ref-name>
        <ejb-ref-type>Session</ejb-ref-type>
        <home>ejb.beans.TestHome</home>
        <remote>ejb.beans.TestRemote</remote>
    </ejb-ref>
</application-client>

Then I just called for the EJBs like from the client apps:
        try
        {
            Hashtable hashtable = new Hashtable();
            hashtable.put(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.ApplicationClientInitialContextFactory");
            hashtable.put(Context.PROVIDER_URL, "http:ormi://127.0.0.1:2000/ejb");
            hashtable.put(Context.SECURITY_PRINCIPAL, "admin");
            hashtable.put(Context.SECURITY_CREDENTIALS, "123");

            Context context = new InitialContext(hashtable);

            Object object = context.lookup("java:comp/env/ejb/TestEJB");

            TestHome testHome = (TestHome)PortableRemoteObject.narrow(object, TestHome.class);

            TestRemote testRemote = (TestRemote)PortableRemoteObject.narrow(testHome.create(), TestRemote.class);

            String output = testRemote.getStringFromFile("applications/ejb/ejb/outputs/output.html");

            printString(output);
            flush();
        }
        catch(RemoteException e)
        {
            System.err.println("System/communication error: " + e.getMessage());
            e.printStackTrace();
        }
        catch(NamingException e)
        {
            System.err.println("Communication error: " + e.getMessage());
            e.printStackTrace();
        }
        catch(CreateException e)
        {
            System.err.println("Error creating cart: " + e.getMessage());
            e.printStackTrace();
        }

Or from inside the ejb-app itself a little easier way:
        try
        {
            Context context = new InitialContext();

            Object object = context.lookup("java:comp/env/ejb/TestEJB");

            TestHome testHome = (TestHome)PortableRemoteObject.narrow(object, TestHome.class);

            TestRemote testRemote = (TestRemote)PortableRemoteObject.narrow(testHome.create(), TestRemote.class);

            String output = testRemote.getStringFromFile("applications/ejb/ejb/outputs/output.html");

            printString(output);
            flush();
        }
        catch(RemoteException e)
        {
            System.err.println("System/communication error: " + e.getMessage());
            e.printStackTrace();
        }
        catch(NamingException e)
        {
            System.err.println("Communication error: " + e.getMessage());
            e.printStackTrace();
        }
        catch(CreateException e)
        {
            System.err.println("Error creating cart: " + e.getMessage());
            e.printStackTrace();
        }

I think that was all!

Best regards
Fredrik
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
Kategori
Kurser inden for grundlæggende programmering

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