cancel
Showing results for 
Search instead for 
Did you mean: 

A Dumb Question About the Calculator Tutorial

Former Member
0 Kudos

Calculator deployed and worked as it was supposed to, but what if I wanted to test without messing with JSP?

I put the following into CalcProxy.java:

<pre>

public static void main(String[] args) throws Exception {

CalcProxy proxy = new CalcProxy();

String ADD = "3";

proxy.getResult("1","1",ADD);

}

</pre>

But when I try to run the application, I get:

CalcProxy.init error in context lookup: 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

So what do I need to do to make this work?

Anybody???

Message was edited by: Dale Seng

Accepted Solutions (0)

Answers (2)

Answers (2)

Former Member
0 Kudos

This was easier than I thought!

Early-on, I had figured I would need to alter the initial context so it could find the server:

//InitialContext ctx = new InitialContext();

Properties prop = new Properties();

prop.put(Context.PROVIDER_URL,"localhost:50004");

InitialContext ctx = new InitialContext(prop);

And I knew I wouldn't be able to use the special EJB naming from an 'outside' client:

//Object ob = ctx.lookup("java:comp/env/ejb/CalBean");

Object ob = ctx.lookup("CalBean");

But somehow the JNDI name that I put in (CalBean) got 'lost'. Once I put it back, it worked fine.

Thanks to Benny for posting today and getting me to look at this again! And thanks to Astrid for putting up with my exploration of the classpath angle.

Dale

Former Member
0 Kudos

Hi Dale,

regarding the classpath, you won't need much more than these two entries except from the specific bean classes you have to reference:

SAP_SYSTEM_ADD_LIBS/comp/SAP-JEE/DCs/sap.com/com.sap.engine.client.lib/_comp/gen/default/public/default/lib/java/sapj2eeclient.jar

SAP_EXCEPTION_LIB_HOME/lib/exception.jar

These and the following lines in main() are enough to call the QuickOrderProcessorBean of the QuickCarRental tutorial:

  public static void main(String[] args) {
    try {
      String connectionString = "MOBILE:50004";
      java.util.Properties p = new java.util.Properties();
      p.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl");
      p.put(Context.PROVIDER_URL, connectionString);
      Context initialContext = new InitialContext(p);
      QuickOrderProcessorHome remoteHome =
        (QuickOrderProcessorHome) initialContext.lookup("QuickCarRental/QuickOrderProcessorBean");
      QuickOrderProcessor remote =
        (QuickOrderProcessor) PortableRemoteObject.narrow(remoteHome.create(), QuickOrderProcessor.class);
      QuickBookingModel[] bookings = remote.viewActiveBookings();
      if (bookings != null) {
        for (int ix = 0; ix < bookings.length; ix++) {
          System.out.println(bookings[ix].getBookingId());
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

Regards

Stefan

Former Member
0 Kudos

Stefan, Agreed. But you will need to define a name in JNDI. The tutorial doesn't show you exactly how to do it. I says only this:

<i>Adding Descriptions to ejb-j2ee-engine.xml

The deployment descriptor ejb-j2ee-engine.xml generally defines other properties specific to

the SAP J2EE Engine. For example, you can specify the JNDI name of the beans in this file.

However, these special entries are not required for this example application.</i>

stefan.send(new Thanks());

I like how you put your code in "code" tags!

Dale

Benny
Product and Topic Expert
Product and Topic Expert
0 Kudos

I thinik you shopuld have a deeper look into what you're doing here. You cannot change a server application into a standalone one by just adding a main method.

I don't know what it is specially, but you surely are unaware about some J2EE facts...

Regards,

Benny

Former Member
0 Kudos

Hi,

I think what he is talking about is accessing the server part not by jsp but with a plain Java-Client. That's what we do sometimes to test the server part before handing the methods over to the jsp-developers.

The difference is that you have to access the application from the outside. I guess you are looking for something similar like this:

<i>String connectionString = "localhost:50004";

java.util.Properties p = new java.util.Properties();

p.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl");

p.put(Context.PROVIDER_URL, connectionString);

Context initialContext = new InitialContext(p);

CalculatorSessionHome calculatorSessionHome = (CalculatorSessionHome) initialContext.lookup("sap.com/<name of your calculator application>/CalculatorSessionBean");

CalculatorSession calculatorSession = calculatorSessionHome.create();</i>

This is only a sniplet you cannot copy and paste it without modifications.

Best Regards, Astrid

Former Member
0 Kudos

Astrid, Thanks! After the original post, I used ctx.getEnvironment() and run that through the jsp code to discover what values were set:

localhost:1050

com.sap.engine.services.jndi.InitialContextFactoryImpl

But there's the problem of jar files not being found. Not having jar files results in class not found exceptions during runtime (it compiles okay).

I've found a few that need to be added, but there needs to be more:

naming.jar

frame.jar

(I'm working on finding the security one right now).

Benny, I understood that clients of EJB's can be any number of things, including a Java application. That would lead me to believe that indeed adding a main method is a valid way to interact with an EJB. If those are invalid statements, I'd like some enlightenment.

Dale

Former Member
0 Kudos

Astrid,

Assuming that you have the ability to access your naming environment from a Java application, could you please look to see what you have in the Eclipse IDE under your project > properties > Java Build Path, as well as what you have in your run > (appropriate Java Application) > User classes (and also Bootstrap classes).

Thanks.

Dale

Former Member
0 Kudos

Hello,

this is my .classpath-file from the Test-Project from where I call the server-methods in the bean:

<?xml version="1.0" encoding="UTF-8"?>

<classpath>

<classpathentry kind="src" path=""/>

<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>

<classpathentry kind="var" path="TSSAP_JAVAX_HOME/lib/ejb20.jar"/>

<classpathentry kind="var" path="TSSAP_JAVAX_HOME/lib/jdbc20.jar"/>

<classpathentry kind="var" path="TSSAP_JAVAX_HOME/lib/servlet.jar"/>

<classpathentry kind="lib" path="D:/usr/sap/J2E/JC00/j2ee/j2eeclient/sapj2eeclient.jar"/>

<classpathentry kind="lib" path="D:/usr/sap/J2E/JC00/j2ee/j2eeclient/exception.jar"/>

<classpathentry kind="src" path="/transparenz-server"/>

<classpathentry kind="output" path="bin"/>

</classpath>

The transparenz-server entry is a reference to my server-project. Everything else is Java-Standard or WAS-jar's.

I have set no extra environmental varibles, additional classpathes, external jars or anything in the Debug-Feature of Eclipse.

Hope that help. Maybe I didn't get your question right.If so, please explain a bit more.

Best Regards, Astrid

Former Member
0 Kudos

Astrid,

You have been so kind to post the .classpath file that's used in the build process; sapj2eeclient.jar is key.

If I could trouble you one more time? I presume that you can run one or more transparentz-server classes from within Eclipse? And those classes use EJB's?

If so, then the information under "Run > Run ..." must be configured to allow that. In my case, under the Classpath tab, for User classes, I have the web and ejb project folders, plus the same TSSAP* entries as your build path. For Bootstrap classes I only have JRE (no SAP related entries).

Under the "Classpath" tab, do you have "Use default class path" enabled (checked)? If this IS checked, I wonder if you would share your default classpath (suspect if you typed "set classpath" at a command prompt, it would be displayed). What do you see under User classes and Bootstrap classes?

Dale

Former Member
0 Kudos

Dale,

yes I use the default Classpath but that should not be the System Classpath but the classpath I have defined in my project with classpaht-file.

Bootstrap is only the JRE.

Since my client-project references the server-project all the custom build session interfaces are there. All the stub/skeleton handling is done on the WAS server and if I debug through the methods I access only the 'handwritten' beans.

Regards, Astrid

Benny
Product and Topic Expert
Product and Topic Expert
0 Kudos

> Benny, I understood that clients of EJB's can be any

> number of things, including a Java application. That

> would lead me to believe that indeed adding a main

> method is a valid way to interact with an EJB. If

> those are invalid statements, I'd like some

> enlightenment.

The idea of the CalcProxy is to work as controller of an JSP. This means it get's some parameters from there, which are mandatory. Without them it will not do anything.

Regards,

Benny

Former Member
0 Kudos

>> Benny, I understood that clients of EJB's can be any

>> number of things, including a Java application. That

>> would lead me to believe that indeed adding a main

>> method is a valid way to interact with an EJB. If

>> those are invalid statements, I'd like some

>> enlightenment.>

>The idea of the CalcProxy is to work as controller of an

>JSP. This means it get's some parameters from there,

>which are mandatory. Without them it will not do

>anything.

I just checked the file jsp_Cal1087482969963.java (this is built by the platform and it's the code that really runs when the page runs, right?). All it does is get a reference to the CalProxy and then it calls getResult on it, with parms from the page. I suspect that the getAttribute call will instantiate the CalProxy object if needed, since the constructor is NOT called in the JSP code. Here's the interesting stuff from the code:

CalProxy proxy = (CalProxy)pageContext.getAttribute("proxy", PageContext.SESSION_SCOPE);

proxy.getResult(request.getParameter("firstnumber"),request.getParameter("secondnumber"),request.getParameter("expression")));

So, as a client, the JSP did these two things. I suggest that any other client, should also be able to do these two things as well.

In the original entry in this thread, I posted code that did these two things:

CalcProxy proxy = new CalcProxy();

String ADD = "3";

proxy.getResult("1","1",ADD);

The problem is that the environment in which the CalcProxy class runs is different when the container starts running jsp_Cal1087482969963.java as opposed to when I start CalcProxy from the Eclipse IDE. I think it's a matter of things missing from the classpath.

The result is that during CalcProxy.init, things having to do with initial context and lookup do not work. Even when it is able to find com.sap.engine.services.jndi.InitialContextFactoryImpl, something is still not right with the initial context. But any client, anywhere on the network should be able to lookup the home object. That's what EJB is all about, yes? If it bothers you that the code is in the main of the controller, imagine it out in it's own class, on another machine... it would make no difference to the discussion.

Dale

(this has got to be the longest anyone has ever spent trying to add 1 + 1)

Message was edited by: Dale Seng