cancel
Showing results for 
Search instead for 
Did you mean: 

NoSuchMethodException calling a session bean method from a web service

Former Member
0 Kudos

I am running on NetWeaver 6.40 SP10 on Windows.

I have a Java class (not a SessionBean) exposed as a web service where I invoke a session bean method with an argument that is another Java class (basically, just a JavaBean with some getters and setters). I am getting a strange reflection-related error when I invoke a session bean method. The exception I see is a 'java.lang.reflect.UndeclaredThrowableException', and if I unwrap it with 'ex.getCause()', I see 'java.lang.NoSuchMethodException: com.xx.ejb.PersistentObjectSBObjectImpl0.createR3Config(com.xx.common.R3Config)'

I have spent several days trying to come up with a testcase for this, but to no avail. The calling class is:

--- snip R3UpdateTest.java ---

package com.xx.server.webse;

import com.xx.ejb.*;
import com.xx.common.*;

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

/**
 * @author william_woodward
 *
 * To change the template for this generated type comment go to
 * Window>Preferences>Java>Code Generation>Code and Comments
 */
public class R3UpdateTest {
	public String createR3Config(String a, String b, String c,
			String d, String e, String f) {
		String retval = "success!";
		
		try {
			PersistentObjectSB poSB = getPersistentObjectSB();
			R3Config r3cfg = new R3Config();
			r3cfg.setR3HostName(a);
			r3cfg.setR3SystemNumber(b);
			r3cfg.setRfcUserName(c);
			r3cfg.setRfcPassword(d);
			r3cfg.setRfcClient(e);
			r3cfg.setRfcLanguage(f);
			
			poSB.createR3Config(r3cfg);
		} catch (Exception ex) {
			retval = "Exception: " + ex + ", Causing Exception : " + ex.getCause();
		}
		
		return retval;
	}

	/**
	 ************************************************************************
	 * Private methods
	 ************************************************************************
	 */
	private PersistentObjectSB getPersistentObjectSB() throws RemoteException, CreateException, NamingException {

		Properties props = new Properties();
		props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sap.engine.services.jndi.InitialContextFactoryImpl");
		props.put(Context.PROVIDER_URL, "localhost:50004");
		InitialContext ctx;
		ctx = new InitialContext(props);

		PersistentObjectSBHome poSBHome =
			(PersistentObjectSBHome) javax.rmi.PortableRemoteObject.narrow(
				ctx.lookup("xx.com/CMPOBEAR/PersistentObjectSBBean"),
				PersistentObjectSBHome.class);
		return poSBHome.create();
	}
}

--- end R3UpdateTest.java ---

If I change the createR3Config() method to take an argument of class 'Object' instead of an argument of class 'R3Config', and then cast the object back into an R3Config in the method body, it all works fine.

Any clues, anyone?

Thanks,

- Bill

Message was edited by: Bill Woodward - Fixed some funky formatting

Accepted Solutions (0)

Answers (3)

Answers (3)

Former Member
0 Kudos

OK, replying to my own post. I installed NetWeaver '04 SP12 and the problem seems to be resolved. This confirms, I believe, my suspicion that the problem was in the EJB container method lookup.

Thanks for the help!

- Bill

0 Kudos

We had exactly the same problem with calling a EJB method from webdynpro and applied the same work-around (using java.lang.Object as method parameter, see ). At that time we used SP11 since a view months we use SP16 and it is not an issue anymore.

SidBhattacharya
Product and Topic Expert
Product and Topic Expert
0 Kudos

Is the R3Config config class implementing the Serializable interface?? Try implmenting it and running the code?

Former Member
0 Kudos

Yep, it was already there. I present R3Config.java:


package com.xx.common;

import java.io.Serializable;

public class R3Config implements Serializable {
	private String r3HostName;
	private String r3SystemNumber;
	private String rfcUserName;
	private String rfcPassword;
	private String rfcClient;
	private String rfcLanguage;

    /**
     * 
     */
    public R3Config() {
    }

	public R3Config(String r3HostName, String r3SystemNumber) {
		this.r3HostName = r3HostName;
		this.r3SystemNumber = r3SystemNumber;
	}


    /**
     * @return
     */
    public String getR3HostName() {
        return r3HostName;
    }

    /**
     * @return
     */
    public String getR3SystemNumber() {
        return r3SystemNumber;
    }

    /**
     * @return
     */
    public String getRfcClient() {
        return rfcClient;
    }

    /**
     * @return
     */
    public String getRfcLanguage() {
        return rfcLanguage;
    }

    /**
     * @return
     */
    public String getRfcPassword() {
        return rfcPassword;
    }

    /**
     * @return
     */
    public String getRfcUserName() {
        return rfcUserName;
    }

    /**
     * @param string
     */
    public void setR3HostName(String r3HostName) {
        this.r3HostName = r3HostName;
    }

    /**
     * @param string
     */
    public void setR3SystemNumber(String r3SystemNumber) {
        this.r3SystemNumber = r3SystemNumber;
    }

    /**
     * @param string
     */
    public void setRfcClient(String rfcClient) {
        this.rfcClient = rfcClient;
    }

    /**
     * @param string
     */
    public void setRfcLanguage(String rfcLanguage) {
        this.rfcLanguage = rfcLanguage;
    }

    /**
     * @param string
     */
    public void setRfcPassword(String rfcPassword) {
		this.rfcPassword = rfcPassword;
    }

    /**
     * @param string
     */
    public void setRfcUserName(String rfcUserName) {
		this.rfcUserName = rfcUserName;
    }
}

Former Member
0 Kudos

Looks like it is pretty clear to me:

com.xx.ejb.PersistentObjectSBObjectImpl0.createR3Config(

com.xx.common.R3Config)'

Well somewhere in your code you are attempting to call the

method specified above with the signature specified above.

However that method does not exist in the class com.xx.ejb.PersistentObjectSBObjectImpl0 with the signature above, or it is not visible (out of scope) at the time of the call.

Enjoy

Former Member
0 Kudos

Thanks for the reply. Unfortunately, it doesn't really address the problem. The method I am trying to call is a J2EE Session Bean method, which means that I'm really calling an interface, which is matched up with an actual implementing method by the EJB container. It looks to me like the EJB container itself is messing something up so that it is unable to locate/identify the method I'm trying to call.

At this point, I know that the method is in the interface (PersistentObjectSB.java), or I would not be able to compile the calling class. I also know that the R3Config class exists at runtime, because I can create a 'createR3Config' method that takes an 'Object', pass it the R3Config object in the client, and cast it from Object back to R3Config in the session bean method. This seems to be strictly a problem in the EJB container's session bean method lookup.

Anyone know if any defects were fixed in this area between SP10 and SP12?

Thanks again,

- Bill

Former Member
0 Kudos

Can you show the interface and / or implementation for

com.xx.ejb.PersistentObjectSBObjectImpl0 ??

Sorry don't have a system at hand where I could look it up.

Thanks

Former Member
0 Kudos

Sure, I can show them to you. They are very similar to a couple of non-DC classes/projects I put together to try and duplicate the problem.

First, the interface, PersistentObjectSB.java:


package com.xx.ejb;
import javax.ejb.EJBObject;

import com.xx.common.R3Config;
import java.rmi.RemoteException;
public interface PersistentObjectSB extends EJBObject {

	/**
	 * Business Method.
	 */
	public void updateR3Config(R3Config r3Config) throws RemoteException;

	/**
	 * Business Method.
	 */
	public void createR3Config(R3Config r3Config) throws RemoteException;
}

And the implementation, PersistentObjectSBBean.java:


package com.xx.ejb;

import java.util.*;
import javax.ejb.*;
import javax.naming.*;

import com.xx.common.*;
import com.xx.interfaces.*;
/**
 * @ejbHome <{com.xx.ejb.PersistentObjectSBHome}>
 * @ejbLocal <{com.xx.ejb.PersistentObjectSBLocal}>
 * @ejbLocalHome <{com.xx.ejb.PersistentObjectSBLocalHome}>
 * @ejbRemote <{com.xx.ejb.PersistentObjectSB}>
 * @stateless 
 */
public class PersistentObjectSBBean implements SessionBean {
	private R3ConfigEJBLocalHome _r3ConfigEJBLocalHomeIf = null;

	public void ejbRemove() {
	}

	public void ejbActivate() {
		try {
			setEJBLocalHome();
		} catch (NamingException e) {
			throw new EJBException(e);
		}
	}

	public void ejbPassivate() {
	}

	public void setSessionContext(SessionContext context) {
		myContext = context;
	}

	private SessionContext myContext;
	/**
	 * Create Method.
	 */
	public void ejbCreate() throws CreateException {
		try {
			setEJBLocalHome();
		} catch (NamingException e) {
			throw new CreateException();
		}
	}

	/**
	 * Business Method.
	 */
	public void updateR3Config(R3Config r3Config) {
		try {
			R3ConfigPrimaryKey primKey = new R3ConfigPrimaryKey();
			primKey.r3HostName = r3Config.getR3HostName();
			primKey.r3SystemNumber = r3Config.getR3SystemNumber();
			R3ConfigEJBLocal r3ConfigEJBLocal =
				_r3ConfigEJBLocalHomeIf.findByPrimaryKey(primKey);
			if (r3ConfigEJBLocal != null) {
				r3ConfigEJBLocal.updateR3Config(r3Config);
			}
		} catch (Exception e) {
			// What to do here?
		}
	}

	/**
	 * Business Method.
	 */
	public void createR3Config(R3Config r3Config) {
		try {
			R3ConfigEJBLocal r3ConfigEJBLocal =
				_r3ConfigEJBLocalHomeIf.create(r3Config);
		} catch (Exception e) {
			// What to do here?
		}
	}

	private void setEJBLocalHome() throws NamingException {
		Properties props = new Properties();
		props.put(
			Context.INITIAL_CONTEXT_FACTORY,
			"com.sap.engine.services.jndi.InitialContextFactoryImpl");

		InitialContext ctx = new InitialContext(props);
		Object obj = ctx.lookup("localejbs/R3ConfigEJB");
		_r3ConfigEJBLocalHomeIf = (R3ConfigEJBLocalHome) (obj);
	}
}

Thanks,

- Bill