User: stark
Date: 01/02/12 01:21:25
Added: security/src/main/org/jboss/ejb Container.java
ContainerFactory.java
Log:
Patches to the ejb container layer to suppor the security proxy model
Revision Changes Path
1.1 contrib/security/src/main/org/jboss/ejb/Container.java
Index: Container.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.MalformedURLException;
import java.security.Principal;
import java.util.Map;
import java.util.Iterator;
import java.util.Hashtable;
import java.util.HashMap;
import java.util.Set;
import java.util.HashSet;
import java.util.Collection;
import java.util.Enumeration;
import javax.ejb.Handle;
import javax.ejb.HomeHandle;
import javax.ejb.EJBObject;
import javax.ejb.EJBMetaData;
import javax.ejb.CreateException;
import javax.ejb.RemoveException;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.InitialContext;
import javax.naming.LinkRef;
import javax.naming.Reference;
import javax.naming.NamingEnumeration;
import javax.naming.NameClassPair;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.NameNotFoundException;
import javax.naming.spi.ObjectFactory;
import javax.transaction.TransactionManager;
import javax.sql.DataSource;
import org.jboss.logging.Logger;
import org.jboss.security.EJBSecurityManager;
import org.jboss.security.RealmMapping;
import org.jboss.metadata.BeanMetaData;
import org.jboss.metadata.EnvEntryMetaData;
import org.jboss.metadata.EjbRefMetaData;
import org.jboss.metadata.ResourceRefMetaData;
import org.jboss.metadata.ApplicationMetaData;
import org.jnp.interfaces.Naming;
import org.jnp.interfaces.java.javaURLContextFactory;
import org.jnp.server.NamingServer;
/**
* This is the base class for all EJB-containers in JBoss. A Container
* functions as the central hub of all metadata and plugins. Through this
* the container plugins can get hold of the other plugins and any metadata they
need.
*
* The ContainerFactory creates instances of subclasses of this class and calls
the appropriate
* initialization methods.
*
* A Container does not perform any significant work, but instead delegates to
the plugins to provide for
* all kinds of algorithmic functionality.
*
* @see ContainerFactory
* @author Rickard �berg ([EMAIL PROTECTED])
* @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
* @version $Revision: 1.1 $
*/
public abstract class Container
{
// Constants -----------------------------------------------------
// Attributes ----------------------------------------------------
// This is the application that this container is a part of
protected Application application;
// This is the classloader of this container. All classes and resources that
// the bean uses will be loaded from here. By doing this we make the bean
re-deployable
protected ClassLoader classLoader;
// This is the new metadata. it includes information from both ejb-jar and
jboss.xml
// the metadata for the application can be accessed trough
metaData.getApplicationMetaData()
protected BeanMetaData metaData;
// This is the EnterpriseBean class
protected Class beanClass;
// This is the TransactionManager
protected TransactionManager tm;
// This is the SecurityManager
protected EJBSecurityManager sm;
// This is the realm mapping
protected RealmMapping rm;
protected Object statelessSecurityProxy;
protected Object statefulSecurityProxy;
// This is a cache for method permissions
private HashMap methodPermissionsCache = new HashMap();
// Public --------------------------------------------------------
/**
* Sets a transaction manager for this container.
*
* @see javax.transaction.TransactionManager
*
* @param tm
*/
public void setTransactionManager(TransactionManager tm)
{
this.tm = tm;
}
/**
* Returns this container's transaction manager.
*
* @return a concrete instance of javax.transaction.TransactionManager
*/
public TransactionManager getTransactionManager()
{
return tm;
}
public void setSecurityManager(EJBSecurityManager sm)
{
this.sm = sm;
}
public EJBSecurityManager getSecurityManager()
{
return sm;
}
public void setRealmMapping(RealmMapping rm)
{
this.rm = rm;
}
public RealmMapping getRealmMapping()
{
return rm;
}
public void setStatelessSecurityProxy(Object proxy)
{
this.statelessSecurityProxy = proxy;
}
public Object getStatelessSecurityProxy()
{
return statelessSecurityProxy;
}
public void setStatefulSecurityProxy(Object proxy)
{
this.statefulSecurityProxy = proxy;
}
public Object getStatefulSecurityProxy()
{
return statefulSecurityProxy;
}
/**
* Sets the application deployment unit for this container. All the bean
* containers within the same application unit share the same instance.
*
* @param app application for this container
*/
public void setApplication(Application app)
{
if (app == null)
throw new IllegalArgumentException("Null application");
application = app;
}
/**
* Returns the application for this container.
*
* @return
*/
public Application getApplication()
{
return application;
}
/**
* Sets the class loader for this container. All the classes and resources
* used by the bean in this container will use this classloader.
*
* @param cl
*/
public void setClassLoader(ClassLoader cl)
{
this.classLoader = cl;
}
/**
* Returns the classloader for this container.
*
* @return
*/
public ClassLoader getClassLoader()
{
return classLoader;
}
/**
* Sets the meta data for this container. The meta data consists of the
* properties found in the XML descriptors.
*
* @param metaData
*/
public void setBeanMetaData(BeanMetaData metaData)
{
this.metaData = metaData;
}
/**
* Returns the metadata of this container.
*
* @return metaData;
*/
public BeanMetaData getBeanMetaData()
{
return metaData;
}
/**
* Returns the permissions for a method. (a set of roles)
*
* @return assemblyDescriptor;
*/
public Set getMethodPermissions( Method m, boolean home )
{
Set permissions;
if (methodPermissionsCache.containsKey(m)) {
permissions = (Set) methodPermissionsCache.get( m );
} else {
permissions = getBeanMetaData().getMethodPermissions(m.getName(),
m.getParameterTypes(), !home);
methodPermissionsCache.put(m, permissions);
}
return permissions;
}
/**
* Returns the bean class instance of this container.
*
* @return instance of the Enterprise bean class
*/
public Class getBeanClass()
{
return beanClass;
}
/**
* The ContainerFactory calls this method. The ContainerFactory has set all the
* plugins and interceptors that this bean requires and now proceeds to initialize
* the chain. The method looks for the standard classes in the URL, sets up
* the naming environment of the bean. The concrete container classes should
* override this method to introduce implementation specific initialization
behaviour.
*
* @exception Exception if loading the bean class failed
(ClassNotFoundException)
* or setting up "java:" naming environment failed
(DeploymentException)
*/
public void init()
throws Exception
{
// Acquire classes from CL
beanClass = classLoader.loadClass(metaData.getEjbClass());
// Setup "java:" namespace
setupEnvironment();
}
/**
* A default implementation of starting the container service (no-op). The concrete
* container classes should override this method to introduce implementation
specific
* start behaviour.
*
* @exception Exception an exception that occured during start
*/
public void start()
throws Exception
{
}
/**
* A default implementation of stopping the container service (no-op). The concrete
* container classes should override this method to introduce implementation
specific
* stop behaviour.
*/
public void stop()
{
}
/**
* A default implementation of destroying the container service (no-op). The
concrete
* container classes should override this method to introduce implementation
specific
* destroy behaviour.
*/
public void destroy()
{
}
/**
* This method is called by the ContainerInvoker when a method call comes in on
the Home object.
*
* The Container forwards this call to the interceptor chain for further
processing.
*
* @param mi the object holding all info about this invocation
* @return the result of the home invocation
* @exception Exception
*/
public abstract Object invokeHome(MethodInvocation mi)
throws Exception;
/**
* This method is called by the ContainerInvoker when a method call comes in on
an EJBObject.
*
* The Container forwards this call to the interceptor chain for further
processing.
*
* @param id the id of the object being invoked. May be null if
stateless
* @param method the method being invoked
* @param args the parameters
* @return the result of the invocation
* @exception Exception
*/
public abstract Object invoke(MethodInvocation mi)
throws Exception;
// Protected -----------------------------------------------------
abstract Interceptor createContainerInterceptor();
public abstract void addInterceptor(Interceptor in);
// Private -------------------------------------------------------
/*
* setupEnvironment
*
* This method sets up the naming environment of the bean.
* We create the java: namespace with properties, EJB-References, and
* DataSource ressources.
*
*/
private void setupEnvironment()
throws DeploymentException
{
try
{
// Since the BCL is already associated with this thread we can start using
the java: namespace directly
Context ctx = (Context) new InitialContext().lookup("java:comp");
ctx = ctx.createSubcontext("env");
// Bind environment properties
{
Iterator enum = getBeanMetaData().getEnvironmentEntries();
while(enum.hasNext())
{
EnvEntryMetaData entry = (EnvEntryMetaData)enum.next();
if (entry.getType().equals("java.lang.Integer"))
{
bind(ctx, entry.getName(), new Integer(entry.getValue()));
}
else if (entry.getType().equals("java.lang.Long"))
{
bind(ctx, entry.getName(), new Long(entry.getValue()));
}
else if (entry.getType().equals("java.lang.Double"))
{
bind(ctx, entry.getName(), new Double(entry.getValue()));
}
else if (entry.getType().equals("java.lang.Float"))
{
bind(ctx, entry.getName(), new Float(entry.getValue()));
}
else if (entry.getType().equals("java.lang.Byte"))
{
bind(ctx, entry.getName(), new Byte(entry.getValue()));
}
else if (entry.getType().equals("java.lang.Short"))
{
bind(ctx, entry.getName(), new Short(entry.getValue()));
}
else if (entry.getType().equals("java.lang.Boolean"))
{
bind(ctx, entry.getName(), new Boolean(entry.getValue()));
}
else
{
// Unknown type
// Default is string
bind(ctx, entry.getName(), entry.getValue());
}
}
}
// Bind EJB references
{
Iterator enum = getBeanMetaData().getEjbReferences();
while(enum.hasNext())
{
EjbRefMetaData ref = (EjbRefMetaData)enum.next();
Logger.debug("Binding an EJBReference "+ref.getName());
if (ref.getLink() != null)
{
// Internal link
Logger.debug("Binding "+ref.getName()+" to internal JNDI source:
"+ref.getLink());
if (getApplication().getContainer(ref.getLink()) == null)
throw new DeploymentException ("Bean "+ref.getLink()+" not
found within this application.");
bind(ctx, ref.getName(), new
LinkRef(getApplication().getContainer(ref.getLink()).getBeanMetaData().getJndiName()));
// bind(ctx, ref.getName(), new
Reference(ref.getHome(), new StringRefAddr("Container",ref.getLink()),
getClass().getName()+".EjbReferenceFactory", null));
// bind(ctx, ref.getName(), new
LinkRef(ref.getLink()));
}
else
{
// External link
if (ref.getJndiName() == null)
{
throw new DeploymentException("ejb-ref "+ref.getName()+",
expected either ejb-link in ejb-jar.xml or jndi-name in jboss.xml");
}
Logger.debug("Binding "+ref.getName()+" to external JNDI source:
"+ref.getJndiName());
bind(ctx, ref.getName(), new LinkRef(ref.getJndiName()));
}
}
}
// Bind resource references
{
Iterator enum = getBeanMetaData().getResourceReferences();
// let's play guess the cast game ;) New metadata should fix this.
ApplicationMetaData application =
getBeanMetaData().getApplicationMetaData();
while(enum.hasNext())
{
ResourceRefMetaData ref = (ResourceRefMetaData)enum.next();
String resourceName = ref.getResourceName();
String finalName = application.getResourceByName(resourceName);
if (finalName == null)
{
// the application assembler did not provide a resource manager
// if the type is javax.sql.Datasoure use the default one
if (ref.getType().equals("javax.sql.DataSource"))
{
// Go through JNDI and look for DataSource - use the first one
Context dsCtx = new InitialContext();
try
{
// Check if it is available in JNDI
dsCtx.lookup("java:/DefaultDS");
finalName = "java:/DefaultDS";
} catch (Exception e)
{
Logger.debug(e);
}
}
// Default failed? Warn user and move on
// POTENTIALLY DANGEROUS: should this be a critical error?
if (finalName == null)
{
Logger.warning("No resource manager found for
"+ref.getResourceName());
continue;
}
}
if (ref.getType().equals("javax.sql.DataSource"))
{
// Datasource bindings
bind(ctx, ref.getRefName(), new LinkRef(finalName));
}
else if (ref.getType().equals("java.net.URL"))
{
// URL bindings
try
{
bind(ctx, ref.getRefName(), new URL(finalName));
} catch (MalformedURLException e)
{
throw new NamingException("Malformed URL:"+e.getMessage());
}
}
else
{
// Resource Manager bindings
Logger.debug("Binding resource manager "+finalName+ " with JDNI
ENC " +ref.getRefName());
bind(ctx, ref.getRefName(), new LinkRef(finalName));
}
}
}
} catch (NamingException e)
{
Logger.exception(e);
e.getRootCause().printStackTrace();
throw new DeploymentException("Could not set up environment", e);
}
}
/**
* Bind a value to a name in a JNDI-context, and create any missing subcontexts
*
* @param ctx
* @param name
* @param val
* @exception NamingException
*/
private void bind(Context ctx, String name, Object val)
throws NamingException
{
// Bind val to name in ctx, and make sure that all intermediate contexts exist
Name n = ctx.getNameParser("").parse(name);
while (n.size() > 1)
{
String ctxName = n.get(0);
try
{
ctx = (Context)ctx.lookup(ctxName);
} catch (NameNotFoundException e)
{
ctx = ctx.createSubcontext(ctxName);
}
n = n.getSuffix(1);
}
ctx.bind(n.get(0), val);
}
}
1.1 contrib/security/src/main/org/jboss/ejb/ContainerFactory.java
Index: ContainerFactory.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.ejb;
import java.beans.Beans;
import java.beans.beancontext.BeanContextServicesSupport;
import java.net.URL;
import java.net.URLClassLoader;
import java.net.MalformedURLException;
import java.io.File;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Properties;
import java.util.Iterator;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.jar.Attributes;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.Name;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.management.MBeanServer;
import javax.management.MBeanRegistration;
import javax.management.ObjectName;
import javax.transaction.TransactionManager;
import org.jboss.logging.Log;
import org.jboss.logging.ConsoleLogging;
import org.jboss.logging.ConsoleLoggingMBean;
import org.jboss.util.MBeanProxy;
import org.jboss.web.WebServiceMBean;
import org.jboss.ejb.plugins.*;
import org.jboss.verifier.BeanVerifier;
import org.jboss.verifier.event.VerificationEvent;
import org.jboss.verifier.event.VerificationListener;
import org.jboss.security.EJBSecurityManager;
import org.jboss.security.RealmMapping;
import org.jboss.metadata.ApplicationMetaData;
import org.jboss.metadata.BeanMetaData;
import org.jboss.metadata.SessionMetaData;
import org.jboss.metadata.EntityMetaData;
import org.jboss.metadata.MessageDrivenMetaData;
import org.jboss.metadata.ConfigurationMetaData;
import org.jboss.metadata.XmlLoadable;
import org.jboss.metadata.XmlFileLoader;
import org.jboss.logging.Logger;
/**
* A ContainerFactory is used to deploy EJB applications. It can be given a URL to
* an EJB-jar or EJB-JAR XML file, which will be used to instantiate containers and
make
* them available for invocation.
*
* Now also works with message driven beans
* @see Container
* @author Rickard �berg ([EMAIL PROTECTED])
* @author <a href="mailto:[EMAIL PROTECTED]">Marc Fleury</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Juha Lindfors</a>
* @author <a href="mailto:[EMAIL PROTECTED]">Sebastien Alborini</a>
* @author Peter Antman ([EMAIL PROTECTED])
*
* @version $Revision: 1.1 $
*/
public class ContainerFactory
extends org.jboss.util.ServiceMBeanSupport
implements ContainerFactoryMBean
{
// Constants -----------------------------------------------------
public static String DEFAULT_STATELESS_CONFIGURATION = "Default Stateless
SessionBean";
public static String DEFAULT_STATEFUL_CONFIGURATION = "Default Stateful
SessionBean";
public static String DEFAULT_ENTITY_BMP_CONFIGURATION = "Default BMP EntityBean";
public static String DEFAULT_ENTITY_CMP_CONFIGURATION = "Default CMP EntityBean";
public static String DEFAULT_MESSAGEDRIVEN_CONFIGURATION = "Default MesageDriven
Bean";
// Attributes ----------------------------------------------------
// Temp directory where deployed jars are stored
File tmpDir;
// The logger of this service
Log log = Log.createLog(getName());
// A map of current deployments. If a deployment is made and it is already in
this map,
// then undeploy it first (i.e. make it a re-deploy).
HashMap deployments = new HashMap();
// Verify EJB-jar contents on deployments
boolean verifyDeployments = false;
boolean verifierVerbose = false;
// Enable metrics interceptor
boolean metricsEnabled = false;
/* Enable JMS monitoring of the bean cache */
private boolean m_beanCacheJMSMonitoring;
// Public --------------------------------------------------------
/**
* Returns the deployed applications.
*/
public java.util.Iterator getDeployedApplications() {return
deployments.values().iterator();}
/**
* Implements the abstract <code>getObjectName()</code> method in superclass
* to return this service's name.
*
* @param server
* @param name
*
* @exception MalformedObjectNameException
* @return
*/
public ObjectName getObjectName(MBeanServer server, ObjectName name)
throws javax.management.MalformedObjectNameException
{
return new ObjectName(OBJECT_NAME);
}
/**
* Implements the abstract <code>getName()</code> method in superclass to
* return the name of this object.
*
* @return <tt>'Container factory'</code>
*/
public String getName()
{
return "Container factory[patch]";
}
/**
* Implements the template method in superclass. This method stops all the
* applications in this server.
*/
public void stopService()
{
Iterator apps = deployments.values().iterator();
while (apps.hasNext())
{
Application app = (Application)apps.next();
app.stop();
}
}
/**
* Implements the template method in superclass. This method destroys all
* the applications in this server and clears the deployments list.
*/
public void destroyService()
{
Iterator apps = deployments.values().iterator();
while (apps.hasNext())
{
Application app = (Application)apps.next();
app.destroy();
}
deployments.clear();
}
/**
* Enables/disables the application bean verification upon deployment.
*
* @param verify true to enable; false to disable
*/
public void setVerifyDeployments(boolean verify)
{
verifyDeployments = verify;
}
/**
* Returns the state of bean verifier (on/off)
*
* @return true if enabled; false otherwise
*/
public boolean getVerifyDeployments()
{
return verifyDeployments;
}
/**
* Enables/disables the verbose mode on the verifier.
*
* @param verbose true to enable; false to disable
*/
public void setVerifierVerbose(boolean verbose)
{
verifierVerbose = verbose;
}
/**
* Returns the state of the bean verifier (verbose/non-verbose mode)
*
* @return true if enabled; false otherwise
*/
public boolean getVerifierVerbose()
{
return verifierVerbose;
}
/**
* Enables/disables the metrics interceptor for containers.
*
* @param enable true to enable; false to disable
*/
public void setMetricsEnabled(boolean enable)
{
metricsEnabled = enable;
}
/**
* Checks if this container factory initializes the metrics interceptor.
*
* @return true if metrics are enabled; false otherwise
*/
public boolean isMetricsEnabled()
{
return metricsEnabled;
}
/**
* Set JMS monitoring of the bean cache.
*/
public void setBeanCacheJMSMonitoringEnabled(boolean enable)
{
m_beanCacheJMSMonitoring = enable;
}
/**
* Deploy the file at this URL. This method is typically called from remote
administration
* tools that cannot handle java.net.URL's as parameters to methods
*
* @param url
* @exception MalformedURLException
* @exception DeploymentException
*/
public void deploy(String url)
throws MalformedURLException, DeploymentException
{
// Delegate to "real" deployment
deploy(new URL(url));
}
/**
* Undeploy the file at this URL. This method is typically called from remote
administration
* tools that cannot handle java.net.URL's as parameters to methods
*
* @param url
* @exception MalformedURLException
* @exception DeploymentException
*/
public void undeploy(String url)
throws MalformedURLException, DeploymentException
{
// Delegate to "real" undeployment
undeploy(new URL(url));
}
/**
* Deploy EJBs pointed to by an URL.
* The URL may point to an EJB-JAR, an EAR-JAR, or an codebase
* whose structure resembles that of an EJB-JAR. <p>
*
* The latter is useful for development since no packaging is required.
*
* @param url URL where EJB deployment information is contained
*
* @exception DeploymentException
*/
public synchronized void deploy(URL url)
throws DeploymentException
{
// Create application
Application app = new Application();
try
{
Log.setLog(log);
// Check if already deployed -> undeploy first, this is re-deploy
if (deployments.containsKey(url))
undeploy(url);
app.setURL(url);
log.log("Deploying:"+url);
// URL's to put in classloader
URL[] urls = new URL[] { url };
// save the name of the jar before copying -> undeploy with the same name
URL origUrl = url;
// create a classloader that to access the metadata
// this one dont has the contextclassloader as parent
// in case of the contextclassloader has a ejb package in its
//classpath the metadata of this package would be used.
ClassLoader cl = new URLClassLoader(urls);
// Create a file loader with which to load the files
XmlFileLoader efm = new XmlFileLoader();
// the file manager gets its file from the classloader
efm.setClassLoader(cl);
// Load XML
ApplicationMetaData metaData = efm.load();
// create the _real_ classloader for this app
cl = new URLClassLoader(urls, Thread.currentThread().getContextClassLoader
());
// Check validity
Log.setLog(Log.createLog("Verifier"));
// wrapping this into a try - catch block to prevent errors in
// verifier from stopping the deployment
try
{
if (verifyDeployments)
{
BeanVerifier verifier = new BeanVerifier();
verifier.addVerificationListener(new VerificationListener()
{
public void beanChecked(VerificationEvent event)
{
Logger.debug(event.getMessage());
}
public void specViolation(VerificationEvent event)
{
if (verifierVerbose)
Logger.log(event.getVerbose());
else
Logger.log(event.getMessage());
}
});
Logger.log("Verifying " + url);
verifier.verify(url, metaData, cl);
}
}
catch (Throwable t)
{
Logger.exception(t);
}
// unset verifier log
Log.unsetLog();
// Get list of beans for which we will create containers
Iterator beans = metaData.getEnterpriseBeans();
// Deploy beans
Context ctx = new InitialContext();
while(beans.hasNext())
{
BeanMetaData bean = (BeanMetaData)beans.next();
ConfigurationMetaData conf = bean.getContainerConfiguration();
log.log("Deploying "+bean.getEjbName());
// Added message driven deployment
if (bean.isMessageDriven())
{
// Stolen from Stateless deploy
// Create container
MessageDrivenContainer container = new MessageDrivenContainer();
int transType = ((MessageDrivenMetaData)bean).isContainerManagedTx()
? ContainerInterceptors.CMT : ContainerInterceptors.BMT;
commonContainerSetup(container, cl, bean, transType);
// Set instance pool
InstancePool ip = null;
try
{
ip =
(InstancePool)cl.loadClass(conf.getInstancePool()).newInstance();
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Instance Pool
(in jboss.xml or standardjboss.xml)");
}
if (ip instanceof XmlLoadable)
{
((XmlLoadable)ip).importXml(conf.getContainerPoolConf());
}
container.setInstancePool(ip);
// Set container invoker
ContainerInvoker ci = null;
try
{
ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Container
Invoker (in jboss.xml or standardjboss.xml): " + conf.getContainerInvoker() +" - " +
e);
}
if (ci instanceof XmlLoadable)
{
// the container invoker can load its configuration from the
jboss.xml element
((XmlLoadable)ci).importXml(conf.getContainerInvokerConf());
}
container.setContainerInvoker(ci);
// Add container to application
app.addContainer(container);
}
else if (bean.isSession()) // Is session?
{
if (((SessionMetaData)bean).isStateless()) // Is stateless?
{
// Create container
StatelessSessionContainer container = new
StatelessSessionContainer();
int transType = ((SessionMetaData)bean).isContainerManagedTx() ?
ContainerInterceptors.CMT : ContainerInterceptors.BMT;
commonContainerSetup(container, cl, bean, transType);
// Set container invoker
ContainerInvoker ci = null;
try
{
ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Container
Invoker (in jboss.xml or standardjboss.xml): " + conf.getContainerInvoker() +" - " +
e);
}
if (ci instanceof XmlLoadable)
{
// the container invoker can load its configuration from the
jboss.xml element
((XmlLoadable)ci).importXml(conf.getContainerInvokerConf());
}
container.setContainerInvoker(ci);
// Set instance pool
InstancePool ip = null;
try
{
ip =
(InstancePool)cl.loadClass(conf.getInstancePool()).newInstance();
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Instance
Pool (in jboss.xml or standardjboss.xml)");
}
if (ip instanceof XmlLoadable)
{
((XmlLoadable)ip).importXml(conf.getContainerPoolConf());
}
container.setInstancePool(ip);
// Add container to application
app.addContainer(container);
}
else // Stateful
{
// Create container
StatefulSessionContainer container = new
StatefulSessionContainer();
int transType = ((SessionMetaData)bean).isContainerManagedTx() ?
ContainerInterceptors.CMT : ContainerInterceptors.BMT;
commonContainerSetup(container, cl, bean, transType);
// Set container invoker
ContainerInvoker ci = null;
try
{
ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Container
Invoker (in jboss.xml or standardjboss.xml): " + conf.getContainerInvoker() +" - " +
e);
}
if (ci instanceof XmlLoadable)
{
// the container invoker can load its configuration from the
jboss.xml element
((XmlLoadable)ci).importXml(conf.getContainerInvokerConf());
}
container.setContainerInvoker(ci);
// Set instance cache
InstanceCache ic = null;
try
{
ic =
(InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance();
if (ic instanceof AbstractInstanceCache)
{
((AbstractInstanceCache)ic).setJMSMonitoringEnabled(m_beanCacheJMSMonitoring);
}
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Instance Cache
(in jboss.xml or standardjboss.xml)");
}
if (ic instanceof XmlLoadable)
{
((XmlLoadable)ic).importXml(conf.getContainerCacheConf());
}
container.setInstanceCache(ic);
// No real instance pool, use the shadow class
container.setInstancePool(new StatefulSessionInstancePool());
// Set persistence manager
container.setPersistenceManager((StatefulSessionPersistenceManager)cl.loadClass(conf.getPersistenceManager()).newInstance());
// Add container to application
app.addContainer(container);
}
}
else // Entity
{
// Create container
EntityContainer container = new EntityContainer();
int transType = ContainerInterceptors.CMT;
commonContainerSetup(container, cl, bean, transType);
// Set container invoker
ContainerInvoker ci = null;
try
{
ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Container
Invoker (in jboss.xml or standardjboss.xml): " + conf.getContainerInvoker() +" - " +
e);
}
if (ci instanceof XmlLoadable)
{
// the container invoker can load its configuration from the
jboss.xml element
((XmlLoadable)ci).importXml(conf.getContainerInvokerConf());
}
container.setContainerInvoker(ci);
// Set instance cache
InstanceCache ic = null;
try
{
ic =
(InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance();
if (ic instanceof AbstractInstanceCache)
{
((AbstractInstanceCache)ic).setJMSMonitoringEnabled(m_beanCacheJMSMonitoring);
}
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Instance Cache
(in jboss.xml or standardjboss.xml)");
}
if (ic instanceof XmlLoadable)
{
((XmlLoadable)ic).importXml(conf.getContainerCacheConf());
}
container.setInstanceCache(ic);
// Set instance pool
InstancePool ip = null;
try
{
ip =
(InstancePool)cl.loadClass(conf.getInstancePool()).newInstance();
}
catch(Exception e)
{
throw new DeploymentException("Missing or invalid Instance Pool (in
jboss.xml or standardjboss.xml)");
}
if (ip instanceof XmlLoadable)
{
((XmlLoadable)ip).importXml(conf.getContainerPoolConf());
}
container.setInstancePool(ip);
// Set persistence manager
if (((EntityMetaData) bean).isBMP())
{
//Should be BMPPersistenceManager
container.setPersistenceManager((EntityPersistenceManager)cl.loadClass(conf.getPersistenceManager()).newInstance());
}
else
{
// CMP takes a manager and a store
org.jboss.ejb.plugins.CMPPersistenceManager persistenceManager =
new org.jboss.ejb.plugins.CMPPersistenceManager();
//Load the store from configuration
persistenceManager.setPersistenceStore((EntityPersistenceStore)cl.loadClass(conf.getPersistenceManager()).newInstance());
// Set the manager on the container
container.setPersistenceManager(persistenceManager);
}
// Add container to application
app.addContainer(container);
}
}
// Init application
app.init();
// Start application
app.start();
// Add to webserver so client can access classes through dynamic class
downloading
WebServiceMBean webServer =
(WebServiceMBean)MBeanProxy.create(WebServiceMBean.class, WebServiceMBean.OBJECT_NAME);
webServer.addClassLoader(cl);
// Done
log.log("Deployed application: "+app.getName());
// Register deployment. Use the original name in the hashtable
deployments.put(origUrl, app);
}
catch (Exception e)
{
if (e instanceof NullPointerException)
{
// Avoids useless 'null' messages on a server trace.
// Let's be honest and spam them with a stack trace.
// NPE should be considered an internal server error anyways.
Logger.exception(e);
}
Logger.exception(e);
//Logger.debug(e.getMessage());
app.stop();
app.destroy();
throw new DeploymentException("Could not deploy "+url.toString(), e);
} finally
{
Log.unsetLog();
}
}
/**
* Remove previously deployed EJBs.
*
* @param url
* @exception DeploymentException
*/
public void undeploy(URL url)
throws DeploymentException
{
// Get application from table
Application app = (Application)deployments.get(url);
// Check if deployed
if (app == null)
{
throw new DeploymentException("URL not deployed");
}
// Undeploy application
Log.setLog(log);
log.log("Undeploying:"+url);
app.stop();
app.destroy();
// Remove deployment
deployments.remove(url);
// Done
log.log("Undeployed application: "+app.getName());
Log.unsetLog();
}
/**
* is the aplication with this url deployed
*
* @param url
* @exception MalformedURLException
*/
public boolean isDeployed(String url)
throws MalformedURLException
{
return isDeployed (new URL (url));
}
/**
* check if the application with this url is deployed
*
* @param url
* @return true if deployed
*/
public boolean isDeployed (URL url)
{
return (deployments.get(url) != null);
}
/** Container setup logic that is not a function of the container type is
*performed by this method.
*/
private void commonContainerSetup(Container container, ClassLoader cl,
BeanMetaData bean, int transType) throws Exception
{
// Create classloader for this container
// Only used to identify bean. Not really used for class loading!
container.setClassLoader(new URLClassLoader(new URL[0], cl));
// Set metadata
container.setBeanMetaData(bean);
// get the container configuration for this bean
// a default configuration is now always provided
ConfigurationMetaData conf = bean.getContainerConfiguration();
// Set transaction manager
InitialContext iniCtx = new InitialContext();
container.setTransactionManager((TransactionManager)iniCtx.lookup("java:/TransactionManager"));
// Set security manager & role mapping manager
String securityDomain = bean.getApplicationMetaData().getSecurityDomain();
String securityManagerJNDIName = conf.getAuthenticationModule();
String roleMappingManagerJNDIName = conf.getRoleMappingManager();
if( securityDomain != null && securityDomain.startsWith("java:/jaas") ==
false )
securityDomain = "java:/jaas/" + securityDomain;
if( securityDomain != null || ((securityManagerJNDIName != null) &&
(roleMappingManagerJNDIName != null)) )
{ // Either the application has a security domain or the container has
security setup
try
{
if( securityManagerJNDIName == null )
securityManagerJNDIName = securityDomain;
System.out.println("lookup securityManager name:
"+securityManagerJNDIName);
EJBSecurityManager ejbS =
(EJBSecurityManager)iniCtx.lookup(securityManagerJNDIName);
container.setSecurityManager( ejbS );
}
catch (NamingException ne)
{
throw new DeploymentException( "Could not find the Security Manager
specified for this container, name="+securityManagerJNDIName, ne);
}
try
{
if( roleMappingManagerJNDIName == null )
roleMappingManagerJNDIName = securityDomain;
RealmMapping rM =
(RealmMapping)iniCtx.lookup(roleMappingManagerJNDIName);
container.setRealmMapping( rM );
}
catch (NamingException ne)
{
throw new DeploymentException( "Could not find the Role Mapping
Manager specified for this container", ne );
}
}
// Set security proxies
String statelessProxyClassName = bean.getStatelessSecurityProxy();
String statefulProxyClassName = bean.getStatefulSecurityProxy();
if( statelessProxyClassName != null )
{
try
{
Class proxyClass = cl.loadClass(statelessProxyClassName);
Object proxy = proxyClass.newInstance();
container.setStatelessSecurityProxy(proxy);
System.out.println("setStatelessSecurityProxy, "+proxy);
}
catch(Exception e)
{
throw new DeploymentException("Missing StatelessSecurityProxy (in
jboss.xml or standardjboss.xml): " + conf.getContainerInvoker() +" - " + e);
}
}
if( statefulProxyClassName != null )
{
try
{
Class proxyClass = cl.loadClass(statefulProxyClassName);
Object proxy = proxyClass.newInstance();
container.setStatefulSecurityProxy(proxy);
System.out.println("setStatefulSecurityProxy, "+proxy);
}
catch(Exception e)
{
throw new DeploymentException("Missing StatefulSecurityProxy (in
jboss.xml or standardjboss.xml): " + conf.getContainerInvoker() +" - " + e);
}
}
// Create interceptors
ContainerInterceptors.addInterceptors(container, transType, metricsEnabled,
conf.getContainerInterceptorsConf());
}
}