• Post Reply Bookmark Topic Watch Topic
  • New Topic

Problem with Session Beans  RSS feed

 
paramesh ande
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi ,
I have written a SFSB for a bank application.And I used servlets as client.
I am able to call all the business logic functions in the bean except one,i.e transferMoney(). It is giving the error on the server console(weblogic 7.0) as fallows.

<Dec 15, 2005 5:04:50 PM PST> <Error> <HTTP> <101019> <[ServletContext(id=401058
4,name=accweb,context-path=/accweb)] Servlet failed with IOException
java.rmi.UnmarshalException: Method not found: 'transferMoney(IID)'
at weblogic.rmi.internal.MethodDescriptor.init(MethodDescriptor.java:157
)
at weblogic.rmi.internal.ServerRequest.sendReceive(ServerRequest.java:12
6)
at weblogic.rmi.internal.BasicRemoteRef.invoke(BasicRemoteRef.java:127)
at account.Account_5ysgq2_EOImpl_WLStub.transferMoney(Unknown Source)
at servlets.AccountServlet.doGet(AccountServlet.java:92)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run
(ServletStubImpl.java:945)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubIm
pl.java:332)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubIm
pl.java:242)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationActio
n.run(WebAppServletContext.java:5360)
at weblogic.security.service.SecurityServiceManager.runAs(SecurityServic
eManager.java:721)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppSe
rvletContext.java:3043)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestIm
pl.java:2468)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:152)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:133)
>


plz tell me the solution for this problem.

thanks in advance
 
Manoj Kumkumath
Ranch Hand
Posts: 71
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ensure that the object you are passing is serialized.
 
paramesh ande
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Manoj,
Thanks for ur reply, but i am not passing any objects ,I am just passing the integer values to that function. The other functions in the same bean are being executed.
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are you sure that the transferMoney method is declared in the bean's interface? If is isn't, then you can't invoke it even if it is declared public in the bean's class.
 
Rajesh Agarwal
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am sure the problem is similar to what manoj pointed out. I see that the Stub is not able to serialize the parameters.
 
paramesh ande
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I declared the function in the RemoteInterface of the bean class.
[ December 15, 2005: Message edited by: paramesh ande ]
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I suggest that you post the code for the client, interface, bean class and parameter class.
 
paramesh ande
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The Bean class:


package account;
import javax.ejb.*;
import java.rmi.*;
import java.sql.*;
import javax.sql.*;
import javax.naming.*;
import java.util.*;
public class Account implements SessionBean
{
SessionContext sctxt;
int accno;
String name;
double bal;
boolean flag;
Connection con;
Statement st;
ResultSet rs;
Context ctxt;
DataSource ds;

public void setSessionContext(SessionContext sctxt)
{
this.sctxt=sctxt;
System.out.println("Inside the setSessionContext");
}
public void ejbCreate()
{
System.out.println("Inside the ejbCreate()");
getConnection();
}
public void ejbPassivate(){
try{
con.close();
}
catch(Exception e){
System.out.println(e);
}
}
public void ejbActivate(){
getConnection();
}
public void ejbRemove(){
try{
st.close();
con.close();
}
catch(Exception e){
System.out.println(e);
}

}
public void getConnection(){
try{
System.out.println("Inside the getConnection()");
Hashtable ht= new Hashtable();
ht.put(Context.PROVIDER_URL,"t3://localhost:7001");
ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
Context context =new InitialContext(ht);
DataSource ds=(DataSource)context.lookup("paramesh");
con=ds.getConnection();
System.out.println("Connection object has been created"+ds.getConnection());
st=con.createStatement();
System.out.println("ST has been created");
}
catch(Exception e)
{
System.out.println("Exception raised in getConnection(): "+e);
}
}
public boolean deposit(int accno,double amt)
{
try{
rs=st.executeQuery("select bal from account where accno="+accno+"");
if(!rs.next()){
flag=false;
throw new RemoteException();
}else{
bal=rs.getDouble(1);
}
bal+=amt;
int i =st.executeUpdate("update account set bal="+bal+" where accno="+accno+"");
if(i==0){
flag=false;
throw new RemoteException();
}
else{
flag=true;
}

}
catch(Exception e){
System.out.println(e);
}
return flag;
}
public boolean withdraw(int acno,double amt)
{
try{
rs=st.executeQuery("select bal from account where accno="+acno+"");
if(!rs.next()){
flag=false;
throw new RemoteException();
}else{
bal=rs.getDouble(1);
}
if(bal>amt+1000)
{
bal=bal-amt;
int i=st.executeUpdate("update account set bal="+bal+" where accno="+acno+"");
if(i==1)
flag=true;
else
flag=false;
}
else{
flag=false;
}
}
catch(Exception e)
{
System.out.println(e);
}
return flag;
}

public double getBalance(int acno) throws RemoteException
{
try{
rs=st.executeQuery("select bal from account where accno="+acno+"");
if(rs.next()){
bal=rs.getDouble(1);
flag=true;
}
else{
flag=false;
}
}
catch(Exception e){
System.out.println(e);
}
if(!flag)
{
throw new RemoteException("Invalid Account ");
}
return bal;
}
public boolean createAccount(String name,double amt)throws RemoteException
{

int i=0;
try{
System.out.println("Inside the createAccount()");
rs=st.executeQuery("select max(accno) from account");
if(rs.next())
{
System.out.println("Max Accno has been retrieved");
accno=rs.getInt(1);
}
else{
accno=0;
}
accno+=1;
System.out.println("New accno is:"+accno);
i=st.executeUpdate("insert into account values("+accno+",'"+name+"',"+amt+")");
if(i==1){
flag=true;
System.out.println("Data has been inseted in createAccount()");
}
else{
flag=false;
}

}
catch(Exception e){
System.out.println("Exception in createAccount:: "+e);
}
if(flag==false){
throw new RemoteException("Account not created");
}

return flag;


}
public boolean closeAccount(int acno)throws RemoteException
{
int i=0;
try{
i=st.executeUpdate("delete from account where accno="+acno+"");
if(i==1)
{
flag=true;
}
else{
flag=false;
}
}
catch(Exception e)
{
System.out.println(e);
}
if(!flag){
throw new RemoteException("Account was not closed");
}
return flag;

}

public boolean transferMoney(int src,int dest,double amt)throws RemoteException{
try{
withdraw(src,amt);
deposit(dest,amt);
System.out.println("Money transfer completed successfull");
}
catch(Exception e){
System.out.println(e);
}
return true;
}
}


Remote Inteface:


package account;
import javax.ejb.*;
import java.rmi.*;
public interface AccountRemote extends EJBObject{
public boolean deposit(int acno,double amt)throws RemoteException;
public boolean withdraw(int accno,double amt)throws RemoteException;
public double getBalance(int acno)throws RemoteException;
public boolean createAccount(String name ,double amt) throws RemoteException ;
public boolean closeAccount(int accno)throws RemoteException;
public boolean transferMoney(int src,int dest,double amt)throws RemoteException;
}


Home Interface:
--------------

package account;
import java.rmi.*;
import javax.ejb.*;
public interface AccountHome extends EJBHome
{
public AccountRemote create()throws CreateException,RemoteException;

}


Client Program:
---------------


package servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.*;
import account.*;

public class AccountServlet extends HttpServlet {

Hashtable ht;
Context ctxt;
AccountHome hello;
AccountRemote remote;
public void init(ServletConfig config){
try{

System.out.println("Inside the init method");
ht=new Hashtable();
System.out.println("Hash table is created");
ht.put(Context.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL,"t3://localhost:7001");
ctxt=new InitialContext(ht);
System.out.println("Context has been created");
hello=(AccountHome)ctxt.lookup("account.AccountHome1");
System.out.println("Home interface is retreived");
remote=hello.create();
System.out.println("remote reference has been created");
}
catch(Exception e){}

}

/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html");
PrintWriter out = response.getWriter();
System.out.println("Inside the servlet");

String action=request.getParameter("button1");
System.out.println("The action submitted is:"+action);

if(action.equals("Create")){
String name=request.getParameter("name");
String bal=request.getParameter("bal");
System.out.println("The name is:"+name);
System.out.println("The balance is:"+bal);
try{
boolean flag=remote.createAccount(name,Double.parseDouble(bal));
System.out.println("The account no is:"+flag);
out.println("<h1>Account Has bee created succesfully</h1>");
}
catch(Exception e){
System.out.println(e);
}
}
else if(action.equals("GetBalance")){
double bal1=remote.getBalance(1);
out.println("The balance is :"+bal1);
}
else if(action.equals("transferMoney")){
String acno1=request.getParameter("src");
String acno2=request.getParameter("dest");
int src=Integer.parseInt(acno1);
int dest=Integer.parseInt(acno2);
String bal=request.getParameter("bal");
double amt=Double.parseDouble(bal);
System.out.println("Data entered is:"+src+dest+amt);

//remote.deposit(dest,amt);
System.out.println("Amount Deposited successfully");
//remote.withdraw(src,amt);
System.out.println("Amount WithDrawn successfully");
remote.transferMoney(src,dest,amt);
out.println("Amount transefered successfully");
}


out.flush();
out.close();
}

}
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is much I do not like about your code, but I think the problem lies elsewhere. It looks as if your client is out of synch with the server as it appears to be passing the wrong parameter list into the transferMoney() method. Rebuild and redeploy, and ensure that your client gets the newly regenerated interfaces and classes on its classpath. When you rerun, your client should work.
 
Devender Thareja
Ranch Hand
Posts: 187
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Roger,

What is it that you don't like. Can you provide some guidelines.

Thanks
 
Roger Chung-Wee
Ranch Hand
Posts: 1683
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The most obvious are:

1. Your bean methods are declaring RemoteException and sometimes throwing RemoteException, this is in violation of the EJB spec.

2. You are swallowing exceptions, this should never be done.

3. Your bean methods must, if there is an error, either throw an application exception or a system exception. Assuming that you are using container managed transactions (usually best) when doing DB updates, you will get an automatic rollback of your transactions by throwing RuntimeException. And be careful to wrap any checked SQLException in EJBException (a subclass of RuntimeException) and throw that EJBException.

4. Do not declare boolean return types, either the method will succeed or an exception will be thrown.

5. Your client must handle the exceptions, either recovering if an application exception is received or giving up if a RemoteException is received.

6. Your code will most likely cause excessive DB locks and cursor leaks if put live. In each method, you should declare a local variable for the ResultSet (if needed), the Statement and the Connection. Obtain the Connection as late as possible and ensure the closure of all these JDBC objects in the finally clause.

Also, obtain the DataSource and Connection in separate methods.

7. Do not use System.out.println, learn to do logging. Java 1.4 has the Logger class, if your EJB server supports a previous version then use Apache log4j.

8. Your code is invoking the close() method, this must never be done. Leave the container to manage the Connections.

Hope this helps.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!