aspose file tools*
The moose likes EJB and other Java EE Technologies and the fly likes generic Client Code to access arbitrary EJBs Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "generic Client Code to access arbitrary EJBs" Watch "generic Client Code to access arbitrary EJBs" New topic
Author

generic Client Code to access arbitrary EJBs

Vinoth Selvaraj
Greenhorn

Joined: Jun 07, 2006
Posts: 18
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

Joined: Mar 11, 2005
Posts: 2
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

Joined: Jun 07, 2006
Posts: 18
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

Joined: Jun 07, 2006
Posts: 18
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

Joined: Mar 11, 2005
Posts: 2
I don't think there is a simple answer to that. The only way I could think of would involve generating byte-code.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: generic Client Code to access arbitrary EJBs