cancel
Showing results for 
Search instead for 
Did you mean: 

Accessing Session Bean

Former Member
0 Kudos

Hi

I have created a simple stateless session bean, and want to call a business method, if the user clicks a button.

Do I need to import a XMI Model for that?

Can  I call the bean directly in the view controller or is it better to make the the call in the component controller?

I tried a normal JNDI lookup for the bean in the view controller, but it did not work.

Are there any How To's or Code Snippets on how to do that ?

Bye

Raphael

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

Hi Raphael,

It is possible to call the bean directly. Please find below a code example with EJB usage. This example usses the remote interface of the EJB, because the Web Dynpro application is running in the Web Dynpro Container and not in the EJB container.

Hope that helps!

Karin

-


try{

Context jndiCtx = new InitialContext();

// in the server's name space. Returnvalue: 'java.lang.Object' (RMI/IIOP compatible)

Object ref = jndiCtx.lookup("sap.com/My Hello World EJB/HelloWorldEJBBean");

// casting the jndi lookup() return type 'java.lang.Object' to the bean's EJBHome type

// using the method 'javax.rmi.PortableRemoteObject.narrow' (EJB1.1):

HelloWorldEJBHome home = (HelloWorldEJBHome)javax.rmi.PortableRemoteObject.narrow(ref,HelloWorldEJBHome);

HelloWorldEJB helloWorld = home.create();

wdContext.currentContextElement().setText(helloWorld.sayHello("World"));

}catch (Exception e) {

Former Member
0 Kudos

Hi Karin,

for me it seems it doesn't work, at least not with the version in the rampup.

I can use the code of your example from an outside Java-Standalone-Application, and it works fine. But if I copy the code into the controller of a Web Dynpro-Component, it failes.

The method

  "home.create()"

causes an

  "java.lang.IllegalArgumentException"

with Text

  "Object is not an instance of declaring class"

Has anyone made a different experience and can help?

Josef

Former Member
0 Kudos

Hi Josef,

Sorry for the delay. Did you install the new Sneak Preview II? Do you have the same error?

Best regards, Karin

Former Member
0 Kudos

Hi Karin,

I have installed the 6.40 Preview now and unfortunately the same result.

The above code-example works from an outside Java-standalone-application, but not within a web-dynrpo-controller.

I would like to know, whether anyone else has this working...

htammen
Active Contributor
0 Kudos

This message was moderated.

Former Member
0 Kudos

Hi Helmut,

it should not really be a problem to access a (in this case) stateless session bean.

Assume the following:

You have created a Ear project "HelloEar", which contains an Ejb Module "HelloEjb". HelloEjb contains a stateless session bean "HelloBean" with a method getHello() returning a string. HelloEar is already deployed and running.

Then these steps are necessary to access the bean from the WD project:

1. Add a project reference to "HelloEjb" to the Java Build Path in the project properties. This is necessary to be able to import/resolve the corresponding bean classes at design time.

2. Add a <b>Sharing Reference</b> named "sap.com/HelloEar" to the Web Dynpro References in the project properties. This is necessary to resolve the corresponding bean classes at runtime.

3. Somewhere, maybe in the Component controller implementation in wdDoInit(), add the following lines:


    try {
      InitialContext ctx = new InitialContext();
      HelloLocalHome localHome =
        (HelloLocalHome) ctx.lookup(
          "localejbs/sap.com/HelloEar/HelloBean");
      HelloLocal local = localHome.create();
      String result = local.getHello();
      wdComponentAPI.getMessageManager().reportSuccess("Hello says: " + result);

    } catch (Exception e) {
      wdComponentAPI.getMessageManager().reportException(e.getMessage(), true);
      e.printStackTrace();
    }

This should work. And yes, the lookup returns the <b>local</b> (home) interface for the bean access. This is possible for WD (server) applications also.

Hope that helps.

Best regards

Stefan

detlev_beutner
Active Contributor
0 Kudos

Hi Stefan,

you make us happy! It's working, great. Thanks, thanks, thanks ))

It's a bit too early to wish a nice weekend, but for the (unprobable) case that I have no problems today and tomorrow left, I don't want to miss this

Stay tuned

Detlev

htammen
Active Contributor
0 Kudos

Hi Stefan,

that was really a very good hint. I didn´t know the thing with the

Sharing Reference

.

But I have one more question. How can I use EJBs that are on a totally different server using the remote interface? The code published by Karin earlier in this thread should be ok.

But when I run it I get a ClassCastException when casting with PortableRemoteObject.narrow(...). The lookup returned an object that has the correct type.

ctx = new InitialContext();

Object obj = ctx.lookup("CounterBean");

home = (TestHome) javax.rmi.PortableRemoteObject.narrow(obj, TestHome.class);

Any ideas?

Best regards an thank you very much

Helmut

Former Member
0 Kudos

Hi Helmut,

no, it should work with remote (home) interfaces too. The following code snippet does the local and the remote lookup + method call:


    try {
      InitialContext ctx = new InitialContext();

      /* Begin local */
      HelloLocalHome localHome =
        (HelloLocalHome) ctx.lookup("localejbs/sap.com/HelloEar/HelloBean");
      HelloLocal local = localHome.create();
      String result = local.getHello();
      wdComponentAPI.getMessageManager().reportSuccess("Hello local  says: " + result);

      /* Begin remote */
      Object remoteRef = ctx.lookup("sap.com/HelloEar/HelloBean");
      HelloHome remoteHome = (HelloHome) PortableRemoteObject.narrow(remoteRef, HelloHome.class);
      Hello remote = (Hello) remoteHome.create();
      result = remote.getHello();
      wdComponentAPI.getMessageManager().reportSuccess("Hello remote says: " + result);

    } catch (Exception e) {
      wdComponentAPI.getMessageManager().reportException(e.getMessage(), true);
      e.printStackTrace();
    }

Looking at your sample, it seems a bit strange, that you lookup "CounterBean" and cast to TestHome.

Hope that helps.

Best regards

Stefan

Former Member
0 Kudos

Hi Detlev,

somehow i missed this thread (it's already there since 6.2.) so far, strange. Anyway, you (and Helmut of course) are welcome. I wish you a nice weekend too, but i think, we'll meet again here before

Keep it up

Stefan

PS:

1. This hints according bean access cover the lowest possible technical level only.

2. <b>NEVER</b> access your business logic in this direct way!

3. Use the ServiceLocator, BusinessDelegate and SessionFacade patterns or you're running into severe trouble, if you want to switch your business layer someday.

htammen
Active Contributor
0 Kudos

Hi Stefan,

your code seem to be the same as mine inspite of the difference that I use the JNDI Name ("CounterBean") of my bean.

My bean is of type "TestHome" (remote home interface) but does have the JNDI name "CounterBean".

The lookup works correct but the cast throws the error.

Of course I didn´t set the sharing reference because I cannot do that if referencing a bean on a server somewhere in the world.

Using J2EE Patterns:

We will of course use the J2EE Patterns you mentioned in the message to Detlev.

Regards and a nice weekend to you as well

Helmut