Forums Register Login

generic Client Code to access arbitrary EJBs

+Pie Number of slices to send: Send
Is it possible to develop a generic client code to access arbitrary EJBs deployed in the application server. The user will deploy their own EJBs in the production environment along with a xml file which provides the complete info about EJB like JNDI name,LocalHome,LocalInterface etc.

But the Client Code should be Generic enough to narrow down any EJBHome(Client should not hardcode any specific Home Class in narrow() method). The client is a web component deployed in the same application server.

With Regards
Vinoth Selvaraj
+Pie Number of slices to send: Send
I think this will do what you want.

package webxml;

import java.util.*;
import java.lang.reflect.*;
import java.io.*;
import java.rmi.*;
import javax.rmi.*;
import javax.ejb.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.naming.*;

import com.boa.amg.invp.webxml.*;
import com.adaptinet.xmlregistry.RegEntry;

public class XMLServletEJB extends XMLServlet {

public XMLServletEJB() {
}

public void init(ServletConfig config) throws ServletException {
super.init(config);
}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}

public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
String ejbName = (String)request.getAttribute(RegEntry.EJBJNDINAME);
String ejbRemoteClass = (String)request.getAttribute(RegEntry.EJBCLASSNAME);
String ejbMethod = (String)request.getAttribute(RegEntry.EJBMETHOD);
javax.servlet.http.HttpSession session = request.getSession();
Context ctx = (Context)session.getAttribute(XMLServlet.INITIALCONTEXT);
if( ctx == null )
{
if( bAllowAnonymousContext )
{
ctx = new InitialContext();
}
else
{
throw new XMLServletException("Unauthorized user: no user context can be found");
}
}

Object remoteObj = createInstance(ejbName, ejbRemoteClass, ctx);

Object args[] = new Object[1];
args[0] = request.getAttribute("xml.in");
Object returnObj = executeMethod(remoteObj, ejbMethod, args, true);

response.getWriter().print(returnObj);
}
catch(XMLServletException e)
{
throw e;
}
catch(Exception e) {
throw new XMLServletException("Unexpected error: " + e);
}
}

protected Object createInstance(String name, String className, Context ctx) throws XMLServletException {

Object remoteObj = null;
try {
if(ctx == null)
throw new ServletException("Initial context unavailable, unable to perform this transaction at this time");

// Load the home interface class and locate the object through JNDI
Class requestClassHome = Class.forName(className+"Home");
Object home = ctx.lookup(name);
home = PortableRemoteObject.narrow(home, requestClassHome);

// Load the remote interface class and create an instance using the home interface
Class requestClass = Class.forName(className);
remoteObj = create(requestClassHome, home);
remoteObj = PortableRemoteObject.narrow(remoteObj, requestClass);

return remoteObj;
}
catch(ClassNotFoundException excnf)
{
throw new XMLServletException("Class not found error: " + excnf);
}
catch(ClassCastException excc)
{
throw new XMLServletException("Error performing object narrow: " + excc);
}
catch(XMLServletException e) {
throw e;
}
catch(Exception e) {
throw new XMLServletException("Unexpected error "+e.getMessage()+ " while creating instance of " + name);
}
}
protected Object create(Class requestClassHome, Object home) throws XMLServletException {
Object ret=null;

try {
Method m = requestClassHome.getMethod("create", null);
ret = m.invoke(home, null);
}
catch(NoSuchMethodException exmnf)
{
throw new XMLServletException("Unable to find create method on home interface: " + exmnf);
}
catch(InvocationTargetException e) {
throw new XMLServletException("Unable to execute create method on home interface " + requestClassHome + " " + e.getTargetException());
}
catch(Exception e) {
throw new XMLServletException( "Unable to create object from Home interface : " +
requestClassHome + " Exception thrown " + e );
}
return ret;
}

protected Object executeMethod(Object targetObject, String name, Object args[], boolean bLogError) throws XMLServletException {
Object ret=null;

try {
Class[] paramdef = {Object.class};
Method m = targetObject.getClass().getMethod(name, paramdef );
ret = m.invoke(targetObject, args);
}
catch(NoSuchMethodException e)
{
throw new XMLServletException("Unable to find method " + name + " on remote interface: " + e);
}
catch(InvocationTargetException e)
{
throw new XMLServletException("Exception while executing method " + name + ": " + e.getTargetException());
}
catch(Exception e) {
throw new XMLServletException("Unknown Error while attempting to execute method "+name+" :" + e);
}
return ret;
}

}
+Pie Number of slices to send: Send
Hi Anthony Graffeo,

Thanks for your reply.

It is working fine now by incorporating the logic given by you.

With Regards
Vinoth Selvaraj
+Pie Number of slices to send: Send
Reflection is working fine if the Remoteinterface and RemoteHome class files
are packaged along with the Calling Servlet war file.

Will this technique work if we don't have Remoteinterface and RemoteHome class files in the claling servlet war?(I suppose it is not possible).

Please suggest the solution to acheive the same.

Thanks
Vinoth Selvaraj
+Pie Number of slices to send: Send
I don't think there is a simple answer to that. The only way I could think of would involve generating byte-code.
Ever since I found this suit I've felt strange new needs. And a tiny ad:
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com


reply
reply
This thread has been viewed 1150 times.
Similar Threads
Problems hot-deploying EJBs to an existing application
This Weeks Giveaway
Client jar compatability - multiple versions of Weblogic
Aplication Client Container question
generic lookup of Home interface in JNDI
More...

All times above are in ranch (not your local) time.
The current ranch time is
Mar 29, 2024 03:40:49.