[jboss-cvs] jboss-ejb3/src/main/org/jboss/ejb3/iiop ...
Carlo de Wolf
carlo at nerdnet.nl
Fri Jul 28 04:04:34 EDT 2006
User: wolfc
Date: 06/07/28 04:04:34
Added: src/main/org/jboss/ejb3/iiop EJB3IIOPWebClassLoader.java
IORFactory.java BeanCorbaServant.java
Log:
EJBTHREE-667: work in progress
Revision Changes Path
1.1 date: 2006/07/28 08:04:34; author: wolfc; state: Exp;jboss-ejb3/src/main/org/jboss/ejb3/iiop/EJB3IIOPWebClassLoader.java
Index: EJB3IIOPWebClassLoader.java
===================================================================
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb3.iiop;
import javax.management.ObjectName;
import org.jboss.iiop.WebCL;
import org.jboss.mx.loading.RepositoryClassLoader;
/**
* The getKey method of the WebCL class is not working in EJB3, this class fixes that.
*
* @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
* @version $Revision: 1.1 $
*/
public class EJB3IIOPWebClassLoader extends WebCL
{
private String jndiName;
public EJB3IIOPWebClassLoader(ObjectName container, RepositoryClassLoader parent, String jndiName)
{
super(container, parent);
this.jndiName = jndiName;
}
@Override
public String getKey()
{
String className = getClass().getName();
int dot = className.lastIndexOf('.');
if( dot >= 0 )
className = className.substring(dot+1);
String key = className + '[' + jndiName + ']';
return key;
}
}
1.1 date: 2006/07/28 08:04:34; author: wolfc; state: Exp;jboss-ejb3/src/main/org/jboss/ejb3/iiop/IORFactory.java
Index: IORFactory.java
===================================================================
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb3.iiop;
import java.lang.annotation.Annotation;
import java.net.URL;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import org.jboss.annotation.ejb.IIOP;
import org.jboss.annotation.ejb.RemoteBinding;
import org.jboss.aop.Advisor;
import org.jboss.ejb3.Container;
import org.jboss.ejb3.ProxyFactoryHelper;
import org.jboss.ejb3.SessionContainer;
import org.jboss.ejb3.remoting.RemoteProxyFactory;
import org.jboss.iiop.CorbaORBService;
import org.jboss.iiop.codebase.CodebasePolicy;
import org.jboss.iiop.csiv2.CSIv2Policy;
import org.jboss.iiop.rmi.InterfaceAnalysis;
import org.jboss.iiop.rmi.ir.InterfaceRepository;
import org.jboss.invocation.iiop.ReferenceFactory;
import org.jboss.invocation.iiop.ServantRegistries;
import org.jboss.invocation.iiop.ServantRegistry;
import org.jboss.invocation.iiop.ServantRegistryKind;
import org.jboss.logging.Logger;
import org.jboss.metadata.IorSecurityConfigMetaData;
import org.jboss.mx.loading.RepositoryClassLoader;
import org.jboss.mx.util.MBeanProxyExt;
import org.jboss.system.Registry;
import org.jboss.web.WebClassLoader;
import org.jboss.web.WebServiceMBean;
import org.omg.CORBA.Any;
import org.omg.CORBA.InterfaceDef;
import org.omg.CORBA.InterfaceDefHelper;
import org.omg.CORBA.ORB;
import org.omg.CORBA.Policy;
import org.omg.CORBA.Repository;
import org.omg.CORBA.UserException;
import org.omg.CosNaming.NameComponent;
import org.omg.CosNaming.NamingContext;
import org.omg.CosNaming.NamingContextExt;
import org.omg.CosNaming.NamingContextExtHelper;
import org.omg.CosNaming.NamingContextHelper;
import org.omg.CosNaming.NamingContextPackage.AlreadyBound;
import org.omg.CosNaming.NamingContextPackage.CannotProceed;
import org.omg.CosNaming.NamingContextPackage.InvalidName;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.omg.PortableServer.Current;
import org.omg.PortableServer.CurrentHelper;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.Servant;
/**
* Comment
*
* @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
* @version $Revision: 1.1 $
*/
public class IORFactory
implements RemoteProxyFactory
{
private static final Logger log = Logger.getLogger(IORFactory.class);
private Container container;
private Advisor advisor;
private RemoteBinding binding;
private String webServiceName = "jboss:service=WebService"; // TODO: make webServiceName configurable
// after start available
private String beanRepositoryIds[];
private String homeRepositoryIds[];
// private InterfaceAnalysis interfaceAnalysis;
private ORB orb;
// private POA poa;
private POA irPoa;
private InterfaceRepository iri;
private ServantRegistry servantRegistry;
private ServantRegistry homeServantRegistry;
private WebClassLoader wcl;
private ReferenceFactory referenceFactory;
private ReferenceFactory homeReferenceFactory;
// TODO: create a default IIOP annotation
private static final IIOP defaultIIOP = new IIOP()
{
public boolean interfaceRepositorySupported()
{
return false;
}
public String poa()
{
return POA_PER_SERVANT;
}
public Class<? extends Annotation> annotationType()
{
return IIOP.class;
}
};
// TODO: do I really need this method
public EJBHome createHomeProxy()
{
try
{
org.omg.CORBA.Object corbaRef = homeReferenceFactory.createReference(homeRepositoryIds[0]);
EJBHome corbaObj = (EJBHome) PortableRemoteObject.narrow(corbaRef, EJBHome.class);
return corbaObj;
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
public EJBObject createProxy()
{
try
{
org.omg.CORBA.Object corbaRef = referenceFactory.createReference(beanRepositoryIds[0]);
EJBObject corbaObj = (EJBObject) PortableRemoteObject.narrow(corbaRef, EJBObject.class);
return corbaObj;
}
catch(Exception e)
{
throw new RuntimeException(e);
}
}
private IIOP getIIOP()
{
IIOP iiop = (IIOP) advisor.resolveAnnotation(IIOP.class);
if(iiop != null)
return iiop;
return defaultIIOP;
}
private String getJndiName()
{
return ProxyFactoryHelper.getDefaultRemoteJndiName(container);
}
private String getServantName()
{
// TODO: is "Servant/" a good prefix for servant name
return "Servant/" + getJndiName();
}
private WebServiceMBean getWebServer() throws MalformedObjectNameException
{
if(webServiceName == null)
throw new IllegalStateException("iiop is not going to work without a web service");
return (WebServiceMBean) MBeanProxyExt.create(WebServiceMBean.class, webServiceName);
}
/**
* Literal copy from org.jboss.proxy.ejb.IORFactory
*/
private void rebind(NamingContextExt ctx, String strName, org.omg.CORBA.Object obj) throws Exception
{
NameComponent[] name = ctx.to_name(strName);
NamingContext intermediateCtx = ctx;
for (int i = 0; i < name.length - 1; i++ ) {
NameComponent[] relativeName = new NameComponent[] { name[i] };
try {
intermediateCtx = NamingContextHelper.narrow(
intermediateCtx.resolve(relativeName));
}
catch (NotFound e) {
intermediateCtx = intermediateCtx.bind_new_context(relativeName);
}
}
intermediateCtx.rebind(new NameComponent[] { name[name.length - 1] }, obj);
}
private void removeWebClassLoader() throws MalformedObjectNameException
{
getWebServer().removeClassLoader(wcl);
}
public void setContainer(Container container)
{
this.container = container;
this.advisor = (Advisor) container; // TODO: why the cast?
}
public void setRemoteBinding(RemoteBinding binding)
{
this.binding = binding;
}
public void setWebServiceName(String name)
{
this.webServiceName = name;
}
public void start() throws Exception
{
// TODO: IORFactory only supports 1 remote interface
Class remoteInterfaces[] = ProxyFactoryHelper.getRemoteInterfaces(container);
if(remoteInterfaces.length > 1)
log.warn("IIOP binding only works on 1 interface, using: " + remoteInterfaces[0].getName());
InterfaceAnalysis interfaceAnalysis = InterfaceAnalysis.getInterfaceAnalysis(remoteInterfaces[0]);
this.beanRepositoryIds = interfaceAnalysis.getAllTypeIds();
InterfaceAnalysis homeInterfaceAnalysis = null;
Class homeInterface = ProxyFactoryHelper.getRemoteHomeInterface(container);
if(homeInterface != null)
{
homeInterfaceAnalysis = InterfaceAnalysis.getInterfaceAnalysis(homeInterface);
this.homeRepositoryIds = homeInterfaceAnalysis.getAllTypeIds();
}
// Get orb and irPoa references
try {
orb = (ORB)new InitialContext().lookup("java:/" + CorbaORBService.ORB_NAME);
}
catch (NamingException e) {
throw new Exception("Cannot lookup java:/" + CorbaORBService.ORB_NAME + ": " + e);
}
try {
irPoa = (POA)new InitialContext().lookup("java:/" + CorbaORBService.IR_POA_NAME);
}
catch (NamingException e) {
throw new Exception("Cannot lookup java:/" + CorbaORBService.IR_POA_NAME + ": " + e);
}
IIOP iiop = getIIOP();
if(iiop.interfaceRepositorySupported())
{
this.iri = new InterfaceRepository(orb, irPoa, getJndiName());
iri.mapClass(remoteInterfaces[0]);
if(homeInterface != null)
iri.mapClass(homeInterface);
iri.finishBuild();
}
// TODO: obtain the iiop invoker name properly
ObjectName invokerName = new ObjectName("jboss:service=invoker,type=iiop");
ServantRegistries servantRegistries = (ServantRegistries) Registry.lookup(invokerName);
if(servantRegistries == null)
throw new Exception("can't find iiop invoker");
ServantRegistryKind registryWithTransientPOA;
ServantRegistryKind registryWithPersistentPOA;
if(iiop.poa().equals(IIOP.POA_PER_SERVANT))
{
registryWithTransientPOA = ServantRegistryKind.TRANSIENT_POA_PER_SERVANT;
registryWithPersistentPOA = ServantRegistryKind.PERSISTENT_POA_PER_SERVANT;
}
else if(iiop.poa().equals(IIOP.POA_SHARED))
{
registryWithTransientPOA = ServantRegistryKind.SHARED_TRANSIENT_POA;
registryWithPersistentPOA = ServantRegistryKind.SHARED_PERSISTENT_POA;
}
else
throw new IllegalArgumentException("@IIOP.poa can only be 'per-servant' or 'shared'");
// Only works for session container
this.servantRegistry = servantRegistries.getServantRegistry(registryWithTransientPOA);
this.homeServantRegistry = servantRegistries.getServantRegistry(registryWithPersistentPOA); // TODO: why is home interface in persistent poa?
// Hack in a WebCL (from org.jboss.ejb.EjbModule.initializeContainer)
// TODO: seting up a WebClassLoader needs to be done somewhere where
ObjectName on = container.getObjectName();
this.wcl = new EJB3IIOPWebClassLoader(on, (RepositoryClassLoader) ((SessionContainer) container).getClassloader(), getJndiName());
WebServiceMBean webServer = getWebServer();
URL[] codebaseURLs = {webServer.addClassLoader(wcl)};
wcl.setWebURLs(codebaseURLs);
// setup a codebase policy, the CodebaseInterceptor will translate this to a TAG_JAVA_CODEBASE
String codebaseString = wcl.getCodebaseString();
log.info("codebase = " + codebaseString);
Any codebase = orb.create_any();
codebase.insert_string(codebaseString);
Policy codebasePolicy;
codebasePolicy = orb.create_policy(CodebasePolicy.TYPE, codebase);
// // Create csiv2Policy for both home and remote containing
// // IorSecurityConfigMetadata
// Any secPolicy = orb.create_any();
// IorSecurityConfigMetaData iorSecurityConfigMetaData =
// container.getBeanMetaData().getIorSecurityConfigMetaData();
// secPolicy.insert_Value(iorSecurityConfigMetaData);
// Policy csiv2Policy = orb.create_policy(CSIv2Policy.TYPE, secPolicy);
Policy policies[] = { codebasePolicy };
InterfaceDef interfaceDef = null;
if(iri != null)
{
Repository ir = iri.getReference();
interfaceDef = InterfaceDefHelper.narrow(ir.lookup_id(beanRepositoryIds[0]));
}
Current poaCurrent = CurrentHelper.narrow(orb.resolve_initial_references("POACurrent"));
NamingContextExt ctx = getNamingContextExt();
Servant servant = new BeanCorbaServant(poaCurrent, container, interfaceDef, interfaceAnalysis);
this.referenceFactory = servantRegistry.bind(getServantName(), servant, policies);
EJBObject corbaObj = createProxy();
rebind(ctx, getJndiName(), (org.omg.CORBA.Object) corbaObj);
// TODO: use iri
if(homeInterfaceAnalysis != null)
{
servant = new BeanCorbaServant(poaCurrent, container, null, homeInterfaceAnalysis);
this.homeReferenceFactory = homeServantRegistry.bind(getServantName() + "Home", servant, policies);
Object homeObject = createHomeProxy();
rebind(ctx, getJndiName() + "Home", (org.omg.CORBA.Object) homeObject);
}
}
public void stop() throws Exception
{
if(homeReferenceFactory != null)
{
unbind(getJndiName() + "Home");
unbindHomeServant();
}
unbind(getJndiName());
unbindServant();
removeWebClassLoader();
}
/**
* Unbind the bean from CosNaming
*/
private void unbind(String strName)
{
try
{
NamingContextExt corbaContext = getNamingContextExt();
NameComponent n[] = corbaContext.to_name(strName);
getNamingContextExt().unbind(n);
}
catch(Exception e)
{
log.warn("unable to unbind '" + strName + "'", e);
}
}
private void unbindHomeServant()
{
try
{
homeServantRegistry.unbind(getServantName() + "Home");
}
catch(Exception e)
{
log.warn("unable to unbind home servant", e);
}
}
private void unbindServant()
{
try
{
servantRegistry.unbind(getServantName());
}
catch(Exception e)
{
log.warn("unable to unbind servant", e);
}
}
private NamingContextExt getNamingContextExt() throws NamingException
{
Context initialContext = new InitialContext();
// NOTE: eclipse editor parser crashes silently on this line (because of org.jboss.iiop.CorbaNamingService) with unknown reason
// that's why this method is at the end
return NamingContextExtHelper.narrow((org.omg.CORBA.Object) initialContext.lookup("java:/" + org.jboss.iiop.CorbaNamingService.NAMING_NAME));
}
}
1.1 date: 2006/07/28 08:04:34; author: wolfc; state: Exp;jboss-ejb3/src/main/org/jboss/ejb3/iiop/BeanCorbaServant.java
Index: BeanCorbaServant.java
===================================================================
/*
* JBoss, Home of Professional Open Source
* Copyright 2005, JBoss Inc., and individual contributors as indicated
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.ejb3.iiop;
import java.lang.reflect.Method;
import java.util.HashMap;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.jboss.ejb3.Container;
import org.jboss.ejb3.stateful.StatefulContainer;
import org.jboss.ejb3.stateless.StatelessContainer;
import org.jboss.iiop.rmi.AttributeAnalysis;
import org.jboss.iiop.rmi.InterfaceAnalysis;
import org.jboss.iiop.rmi.OperationAnalysis;
import org.jboss.iiop.rmi.RmiIdlUtil;
import org.jboss.iiop.rmi.marshal.strategy.SkeletonStrategy;
import org.jboss.invocation.iiop.ReferenceData;
import org.jboss.logging.Logger;
import org.jboss.tm.TransactionManagerLocator;
import org.jboss.tm.iiop.TxServerInterceptor;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.InterfaceDef;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.InvokeHandler;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
import org.omg.PortableServer.Current;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.Servant;
/**
* Comment
*
* @author <a href="mailto:carlo.dewolf at jboss.com">Carlo de Wolf</a>
* @version $Revision: 1.1 $
*/
public class BeanCorbaServant extends Servant
implements InvokeHandler
{
private static final Logger log = Logger.getLogger(BeanCorbaServant.class);
private final Current poaCurrent;
private final Container container;
private final InterfaceDef interfaceDef;
private final String repositoryIds[];
private HashMap<String, SkeletonStrategy> methodMap;
protected BeanCorbaServant(Current poaCurrent, Container container, InterfaceDef interfaceDef, InterfaceAnalysis interfaceAnalysis)
{
this.poaCurrent = poaCurrent;
this.container = container;
this.interfaceDef = interfaceDef;
this.repositoryIds = interfaceAnalysis.getAllTypeIds();
this.methodMap = new HashMap<String, SkeletonStrategy>();
AttributeAnalysis[] attrs = interfaceAnalysis.getAttributes();
for (int i = 0; i < attrs.length; i++) {
OperationAnalysis op = attrs[i].getAccessorAnalysis();
log.debug(" " + op.getJavaName()
+ "\n " + op.getIDLName());
methodMap.put(op.getIDLName(),
new SkeletonStrategy(op.getMethod()));
op = attrs[i].getMutatorAnalysis();
if (op != null) {
log.debug(" " + op.getJavaName()
+ "\n " + op.getIDLName());
methodMap.put(op.getIDLName(),
new SkeletonStrategy(op.getMethod()));
}
}
OperationAnalysis[] ops = interfaceAnalysis.getOperations();
for (int i = 0; i < ops.length; i++) {
log.debug(" " + ops[i].getJavaName()
+ "\n " + ops[i].getIDLName());
methodMap.put(ops[i].getIDLName(),
new SkeletonStrategy(ops[i].getMethod()));
}
}
@Override
public String[] _all_interfaces(POA poa, byte[] objectId)
{
return (String[]) repositoryIds.clone();
}
/**
* Returns an IR object describing the bean's remote interface.
*/
@Override
public org.omg.CORBA.Object _get_interface_def()
{
if (interfaceDef != null)
return interfaceDef;
else
return super._get_interface_def();
}
public OutputStream _invoke(String opName, InputStream in, ResponseHandler handler) throws SystemException
{
log.info("invoke: " + opName);
SkeletonStrategy op = (SkeletonStrategy) methodMap.get(opName);
if (op == null)
{
log.debug("Unable to find opname '" + opName + "' valid operations:" + methodMap.keySet());
throw new BAD_OPERATION(opName);
}
org.omg.CORBA_2_3.portable.OutputStream out;
try
{
Object id = ReferenceData.extractObjectId(poaCurrent.get_object_id());
log.info("id = " + id);
Transaction tx = TxServerInterceptor.getCurrentTransaction();
log.info("tx = " + tx);
Object args[] = op.readParams((org.omg.CORBA_2_3.portable.InputStream) in);
Object retVal = invoke(tx, id, op.getMethod(), args);
out = (org.omg.CORBA_2_3.portable.OutputStream) handler.createReply();
if(op.isNonVoid())
op.writeRetval(out, retVal);
}
catch(Throwable t)
{
// TODO: check log level before stacktrace?
t.printStackTrace();
if(t instanceof Exception)
{
Exception e = (Exception) t;
RmiIdlUtil.rethrowIfCorbaSystemException(e);
out = (org.omg.CORBA_2_3.portable.OutputStream) handler.createExceptionReply();
op.writeException(out, e);
}
else
throw new RuntimeException("NYI");
}
return null;
}
private TransactionManager getTransactionManager()
{
//return TxUtil.getTransactionManager();
return TransactionManagerLocator.getInstance().locate();
}
private Object invoke(Object id, Method method, Object args[]) throws Throwable
{
// FIXME: Not hard coded on stateless container
if(container instanceof StatelessContainer)
return ((StatelessContainer) container).localInvoke(method, args);
else
return ((StatefulContainer) container).localInvoke(id, method, args);
}
private Object invoke(Transaction tx, Object id, Method method, Object args[]) throws Throwable
{
if(tx == null)
return invoke(id, method, args);
// FIXME: refactor TxServerInterceptor so that it pushed the tpc into the invocation like ClientTxPropegationInterceptor
// this would require the localInvoke to be also refactored, so that it uses invocation instead of localInvoke.
TransactionManager tm = getTransactionManager();
// see TxPropagationInterceptor
if(tm.getTransaction() != null)
throw new RuntimeException("cannot import a transaction context when a transaction is already associated with the thread");
tm.resume(tx);
try
{
log.info("currentThread = " + Thread.currentThread());
log.info("currentTransaction = " + tm.getTransaction());
log.info("tm = " + tm);
return invoke(id, method, args);
}
finally
{
tm.suspend();
}
}
}
More information about the jboss-cvs-commits
mailing list