• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

generic Client Code to access arbitrary EJBs

 
Vinoth Selvaraj
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Anthony Graffeo
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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;
}

}
 
Vinoth Selvaraj
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Anthony Graffeo,

Thanks for your reply.

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

With Regards
Vinoth Selvaraj
 
Vinoth Selvaraj
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
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
 
Anthony Graffeo
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't think there is a simple answer to that. The only way I could think of would involve generating byte-code.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic