User: fleury
Date: 00/09/26 10:41:24
Modified: src/main/org/jboss/ejb ContainerFactory.java
Log:
The new container factory puts the the interceptors in the right order
Revision Changes Path
1.40 +686 -664 jboss/src/main/org/jboss/ejb/ContainerFactory.java
Index: ContainerFactory.java
===================================================================
RCS file: /products/cvs/ejboss/jboss/src/main/org/jboss/ejb/ContainerFactory.java,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -r1.39 -r1.40
--- ContainerFactory.java 2000/09/08 22:25:54 1.39
+++ ContainerFactory.java 2000/09/26 17:41:23 1.40
@@ -1,664 +1,686 @@
-/*
-* jBoss, the OpenSource EJB server
-*
-* Distributable under GPL 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.system.EJBSecurityManager;
-import org.jboss.system.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.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.
-*
-* @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>
-*
-* @version $Revision: 1.39 $
-*/
-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";
-
- // Attributes ----------------------------------------------------
- // Temp directory where deployed jars are stored
- File tmpDir;
-
- // The logger of this service
- Log log = new Log(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;
-
- // Public --------------------------------------------------------
-
- /**
- * 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";
- }
-
- /**
- * Implements the template method in superclass. This method inits the factory
- */
- public void initService()
- {
- URL tmpFile = getClass().getResource("/tmp.properties");
- if (tmpFile != null)
- {
- tmpDir = new File(new File(tmpFile.getFile()).getParent(),"deploy/");
- tmpDir.mkdirs();
-
- log.log("Temporary directory set to:"+tmpDir);
-
- // Clear tmp directory of previously deployed files
- // This is to clear up if jBoss previously crashed, hence not removing
files properly
- File[] files = tmpDir.listFiles();
- for (int i = 0; i < files.length; i++)
- {
- files[i].delete();
- }
-
- if (files.length > 0)
- {
- log.log("Previous deployments removed");
- }
- } else
- {
- log.log("Using the systems temporary directory");
- }
- }
-
- /**
- * 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)
- *
- * @param true if enabled; false otherwise
- */
- public boolean getVerifyDeployments()
- {
- return verifyDeployments;
- }
-
- /**
- * 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;
-
- // save the name of the jar before copying -> undeploy with the same name
- URL origUrl = url;
-
- // copy the jar file to prevent locking - redeploy failure
- if (url.getProtocol().startsWith("file") && !url.getFile().endsWith("/"))
- {
- System.out.println(tmpDir);
-
- File jarFile = new File(url.getFile());
- File tmp;
- if (tmpDir == null)
- {
- tmp = File.createTempFile("tmpejbjar",".jar");
- } else
- {
- tmp = File.createTempFile("tmpejbjar",".jar", tmpDir);
- }
- tmp.deleteOnExit();
- FileInputStream fin = new FileInputStream(jarFile);
- byte[] bytes = new byte[(int)jarFile.length()];
- fin.read(bytes);
- FileOutputStream fout = new FileOutputStream(tmp);
- fout.write(bytes);
- fin.close();
- fout.close();
-
- // Get the URL's from the deployments Class-Path: manifest file.
- // These should be added to the classloader
- JarFile jar = new JarFile(tmp);
- Manifest mf = jar.getManifest();
- ArrayList urlList = new ArrayList();
- if (mf != null)
- {
- Attributes attributes = mf.getMainAttributes();
- String classPath = attributes.getValue(Attributes.Name.CLASS_PATH);
- if (classPath != null)
- {
- StringTokenizer classPathTokens = new StringTokenizer(classPath,
" ");
- while (classPathTokens.hasMoreTokens())
- {
- String classPathEntry = classPathTokens.nextToken();
- try
- {
- urlList.add(new URL(url, classPathEntry));
- log.log("Added "+ classPathEntry);
- } catch (MalformedURLException e)
- {
- log.error("Could not add " + classPathEntry);
- }
- }
- }
- }
-
- // Add URL to tmp file
- url = tmp.toURL();
- urlList.add(url);
-
- urls = new URL[urlList.size()];
- urls = (URL[])urlList.toArray(urls);
- } else
- {
- urls = new URL[] { url };
- }
-
- // Create the ClassLoader for this application
- // TODO : the ClassLoader should come from the JMX manager if we want to
be able to share it (tomcat)
- ClassLoader cl = new URLClassLoader(urls,
Thread.currentThread().getContextClassLoader());
-
- // 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();
-
-
-
- // Check validity
- Log.setLog(new Log("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.log(event.getName() + ": " + event.getMessage());
- }
-
- public void specViolation(VerificationEvent event)
- {
- Logger.log(event.getName() + ": " + event.getMessage());
- }
- });
-
-
- Logger.log("Verifying " + url);
-
- verifier.verify(url, metaData);
- }
- }
- 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();
-
- log.log("Deploying "+bean.getEjbName());
-
- if (bean.isSession()) // Is session?
- {
- if (((SessionMetaData)bean).isStateless()) // Is stateless?
- {
- // Create container
- StatelessSessionContainer container = new
StatelessSessionContainer();
-
- // Create classloader for this container
- container.setClassLoader(new BeanClassLoader(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
- container.setTransactionManager((TransactionManager)new
InitialContext().lookup("TransactionManager"));
-
- // Set security manager (should be chosen based on container
config)
- container.setSecurityManager((EJBSecurityManager)new
InitialContext().lookup("EJBSecurityManager"));
-
- // Set realm mapping (should be chosen based on container
config)
- container.setRealmMapping( (RealmMapping)new
InitialContext().lookup("SimpleRealmMapping"));
-
- // Set container invoker
- ContainerInvoker ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
- 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 =
(InstancePool)cl.loadClass(conf.getInstancePool()).newInstance();
- if (ip instanceof XmlLoadable) {
- ((XmlLoadable)ip).importXml(conf.getContainerPoolConf());
- }
- container.setInstancePool(ip);
-
- // Create interceptors
-
- container.addInterceptor(new LogInterceptor());
- container.addInterceptor(new SecurityInterceptor());
- container.addInterceptor(new TxInterceptor());
- container.addInterceptor(new
StatelessSessionInstanceInterceptor());
-
- // Finally we add the last interceptor from the container
- container.addInterceptor(container.createContainerInterceptor());
-
- // Add container to application
- app.addContainer(container);
- } else // Stateful
- {
- // Create container
- StatefulSessionContainer container = new
StatefulSessionContainer();
-
- // Create classloader for this container
- container.setClassLoader(new BeanClassLoader(cl));
-
- // Set metadata
- container.setBeanMetaData(bean);
-
- // Set transaction manager
- container.setTransactionManager((TransactionManager)new
InitialContext().lookup("TransactionManager"));
-
- // Set security manager (should be chosen based on container
config)
- container.setSecurityManager((EJBSecurityManager)new
InitialContext().lookup("EJBSecurityManager"));
-
- // Set realm mapping (should be chosen based on container
config)
- container.setRealmMapping( (RealmMapping)new
InitialContext().lookup("SimpleRealmMapping"));
-
- // Get container configuration
- ConfigurationMetaData conf = bean.getContainerConfiguration();
-
- // Set container invoker
- ContainerInvoker ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
- 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 =
(InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance();
- 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());
-
- // Create interceptors
- container.addInterceptor(new LogInterceptor());
- container.addInterceptor(new TxInterceptor());
- container.addInterceptor(new StatefulSessionInstanceInterceptor());
- container.addInterceptor(new SecurityInterceptor());
-
- container.addInterceptor(container.createContainerInterceptor());
-
- // Add container to application
- app.addContainer(container);
- }
- } else // Entity
- {
- // Create container
- EntityContainer container = new EntityContainer();
-
- // Create classloader for this container
- container.setClassLoader(new BeanClassLoader(cl));
-
- // Set metadata
- container.setBeanMetaData(bean);
-
- // Set transaction manager
- container.setTransactionManager((TransactionManager)new
InitialContext().lookup("TransactionManager"));
-
- // Set security manager (should be chosen based on container config)
- container.setSecurityManager((EJBSecurityManager)new
InitialContext().lookup("EJBSecurityManager"));
-
- // Set realm mapping (should be chosen based on container config)
- container.setRealmMapping( (RealmMapping)new
InitialContext().lookup("SimpleRealmMapping"));
-
- // Get container configuration
- ConfigurationMetaData conf = bean.getContainerConfiguration();
-
- // Set container invoker
- ContainerInvoker ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
- 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 =
(InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance();
- if (ic instanceof XmlLoadable) {
- ((XmlLoadable)ic).importXml(conf.getContainerCacheConf());
- }
- container.setInstanceCache(ic);
-
- // Set instance pool
- InstancePool ip =
(InstancePool)cl.loadClass(conf.getInstancePool()).newInstance();
- 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);
- }
-
- // Create interceptors
- container.addInterceptor(new LogInterceptor());
- container.addInterceptor(new SecurityInterceptor());
- container.addInterceptor(new TxInterceptor());
- container.addInterceptor(new EntityInstanceInterceptor());
- container.addInterceptor(new EntitySynchronizationInterceptor());
-
- container.addInterceptor(container.createContainerInterceptor());
-
- // 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 (Throwable 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());
- } 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();
- }
-
- // Protected -----------------------------------------------------
-}
+/*
+* jBoss, the OpenSource EJB server
+*
+* Distributable under GPL 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.system.EJBSecurityManager;
+import org.jboss.system.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.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.
+*
+* @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>
+*
+* @version $Revision: 1.40 $
+*/
+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";
+
+ // Attributes ----------------------------------------------------
+ // Temp directory where deployed jars are stored
+ File tmpDir;
+
+ // The logger of this service
+ Log log = new Log(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;
+
+ // Public --------------------------------------------------------
+
+ /**
+ * 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";
+ }
+
+ /**
+ * Implements the template method in superclass. This method inits the factory
+ */
+ public void initService()
+ {
+ URL tmpFile = getClass().getResource("/tmp.properties");
+ if (tmpFile != null)
+ {
+ tmpDir = new File(new File(tmpFile.getFile()).getParent(),"deploy/");
+ tmpDir.mkdirs();
+
+ log.log("Temporary directory set to:"+tmpDir);
+
+ // Clear tmp directory of previously deployed files
+ // This is to clear up if jBoss previously crashed, hence not removing
files properly
+ File[] files = tmpDir.listFiles();
+ for (int i = 0; i < files.length; i++)
+ {
+ files[i].delete();
+ }
+
+ if (files.length > 0)
+ {
+ log.log("Previous deployments removed");
+ }
+ } else
+ {
+ log.log("Using the systems temporary directory");
+ }
+ }
+
+ /**
+ * 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)
+ *
+ * @param true if enabled; false otherwise
+ */
+ public boolean getVerifyDeployments()
+ {
+ return verifyDeployments;
+ }
+
+ /**
+ * 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;
+
+ // save the name of the jar before copying -> undeploy with the same name
+ URL origUrl = url;
+
+ // copy the jar file to prevent locking - redeploy failure
+ if (url.getProtocol().startsWith("file") && !url.getFile().endsWith("/"))
+ {
+ System.out.println(tmpDir);
+
+ File jarFile = new File(url.getFile());
+ File tmp;
+ if (tmpDir == null)
+ {
+ tmp = File.createTempFile("tmpejbjar",".jar");
+ } else
+ {
+ tmp = File.createTempFile("tmpejbjar",".jar", tmpDir);
+ }
+ tmp.deleteOnExit();
+ FileInputStream fin = new FileInputStream(jarFile);
+ byte[] bytes = new byte[(int)jarFile.length()];
+ fin.read(bytes);
+ FileOutputStream fout = new FileOutputStream(tmp);
+ fout.write(bytes);
+ fin.close();
+ fout.close();
+
+ // Get the URL's from the deployments Class-Path: manifest file.
+ // These should be added to the classloader
+ JarFile jar = new JarFile(tmp);
+ Manifest mf = jar.getManifest();
+ ArrayList urlList = new ArrayList();
+ if (mf != null)
+ {
+ Attributes attributes = mf.getMainAttributes();
+ String classPath = attributes.getValue(Attributes.Name.CLASS_PATH);
+ if (classPath != null)
+ {
+ StringTokenizer classPathTokens = new StringTokenizer(classPath,
" ");
+ while (classPathTokens.hasMoreTokens())
+ {
+ String classPathEntry = classPathTokens.nextToken();
+ try
+ {
+ urlList.add(new URL(url, classPathEntry));
+ log.log("Added "+ classPathEntry);
+ } catch (MalformedURLException e)
+ {
+ log.error("Could not add " + classPathEntry);
+ }
+ }
+ }
+ }
+
+ // Add URL to tmp file
+ url = tmp.toURL();
+ urlList.add(url);
+
+ urls = new URL[urlList.size()];
+ urls = (URL[])urlList.toArray(urls);
+ } else
+ {
+ urls = new URL[] { url };
+ }
+
+ // Create the ClassLoader for this application
+ // TODO : the ClassLoader should come from the JMX manager if we want to
be able to share it (tomcat)
+ ClassLoader cl = new URLClassLoader(urls,
Thread.currentThread().getContextClassLoader());
+
+ // 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();
+
+
+
+ // Check validity
+ Log.setLog(new Log("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.log(event.getName() + ": " + event.getMessage());
+ }
+
+ public void specViolation(VerificationEvent event)
+ {
+ Logger.log(event.getName() + ": " + event.getMessage());
+ }
+ });
+
+
+ Logger.log("Verifying " + url);
+
+ verifier.verify(url, metaData);
+ }
+ }
+ 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();
+
+ log.log("Deploying "+bean.getEjbName());
+
+ if (bean.isSession()) // Is session?
+ {
+ if (((SessionMetaData)bean).isStateless()) // Is stateless?
+ {
+ // Create container
+ StatelessSessionContainer container = new
StatelessSessionContainer();
+
+ // Create classloader for this container
+ container.setClassLoader(new BeanClassLoader(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
+ container.setTransactionManager((TransactionManager)new
InitialContext().lookup("TransactionManager"));
+
+ // Set security manager (should be chosen based on container
config)
+ container.setSecurityManager((EJBSecurityManager)new
InitialContext().lookup("EJBSecurityManager"));
+
+ // Set realm mapping (should be chosen based on container
config)
+ container.setRealmMapping( (RealmMapping)new
InitialContext().lookup("SimpleRealmMapping"));
+
+ // Set container invoker
+ ContainerInvoker ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
+ 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 =
(InstancePool)cl.loadClass(conf.getInstancePool()).newInstance();
+ if (ip instanceof XmlLoadable) {
+ ((XmlLoadable)ip).importXml(conf.getContainerPoolConf());
+ }
+ container.setInstancePool(ip);
+
+ // Create interceptors
+
+ container.addInterceptor(new LogInterceptor());
+ container.addInterceptor(new SecurityInterceptor());
+
+ if (((SessionMetaData)bean).isContainerManagedTx()) {
+ // CMT
+ container.addInterceptor(new TxInterceptorCMT());
+ container.addInterceptor(new
StatelessSessionInstanceInterceptor());
+
+ } else {
+ // BMT
+ container.addInterceptor(new StatelessSessionInstanceInterceptor());
+ container.addInterceptor(new TxInterceptorBMT());
+ }
+
+ // Finally we add the last interceptor from the container
+ container.addInterceptor(container.createContainerInterceptor());
+
+ // Add container to application
+ app.addContainer(container);
+ } else // Stateful
+ {
+ // Create container
+ StatefulSessionContainer container = new
StatefulSessionContainer();
+
+ // Create classloader for this container
+ container.setClassLoader(new BeanClassLoader(cl));
+
+ // Set metadata
+ container.setBeanMetaData(bean);
+
+ // Set transaction manager
+ container.setTransactionManager((TransactionManager)new
InitialContext().lookup("TransactionManager"));
+
+ // Set security manager (should be chosen based on container
config)
+ container.setSecurityManager((EJBSecurityManager)new
InitialContext().lookup("EJBSecurityManager"));
+
+ // Set realm mapping (should be chosen based on container
config)
+ container.setRealmMapping( (RealmMapping)new
InitialContext().lookup("SimpleRealmMapping"));
+
+ // Get container configuration
+ ConfigurationMetaData conf = bean.getContainerConfiguration();
+
+ // Set container invoker
+ ContainerInvoker ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
+ 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 =
(InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance();
+ 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());
+
+ // Create interceptors
+ container.addInterceptor(new LogInterceptor());
+
+ if (((SessionMetaData)bean).isContainerManagedTx()) {
+ // CMT
+ container.addInterceptor(new TxInterceptorCMT());
+ container.addInterceptor(new
StatefulSessionInstanceInterceptor());
+
+ } else {
+ // BMT : the tx interceptor needs the context from the instance
interceptor
+ container.addInterceptor(new StatefulSessionInstanceInterceptor());
+ container.addInterceptor(new TxInterceptorBMT());
+ }
+
+ container.addInterceptor(new SecurityInterceptor());
+
+ container.addInterceptor(container.createContainerInterceptor());
+
+ // Add container to application
+ app.addContainer(container);
+ }
+ } else // Entity
+ {
+ // Create container
+ EntityContainer container = new EntityContainer();
+
+ // Create classloader for this container
+ container.setClassLoader(new BeanClassLoader(cl));
+
+ // Set metadata
+ container.setBeanMetaData(bean);
+
+ // Set transaction manager
+ container.setTransactionManager((TransactionManager)new
InitialContext().lookup("TransactionManager"));
+
+ // Set security manager (should be chosen based on container config)
+ container.setSecurityManager((EJBSecurityManager)new
InitialContext().lookup("EJBSecurityManager"));
+
+ // Set realm mapping (should be chosen based on container config)
+ container.setRealmMapping( (RealmMapping)new
InitialContext().lookup("SimpleRealmMapping"));
+
+ // Get container configuration
+ ConfigurationMetaData conf = bean.getContainerConfiguration();
+
+ // Set container invoker
+ ContainerInvoker ci =
(ContainerInvoker)cl.loadClass(conf.getContainerInvoker()).newInstance();
+ 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 =
(InstanceCache)cl.loadClass(conf.getInstanceCache()).newInstance();
+ if (ic instanceof XmlLoadable) {
+ ((XmlLoadable)ic).importXml(conf.getContainerCacheConf());
+ }
+ container.setInstanceCache(ic);
+
+ // Set instance pool
+ InstancePool ip =
(InstancePool)cl.loadClass(conf.getInstancePool()).newInstance();
+ 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);
+ }
+
+ // Create interceptors
+ container.addInterceptor(new LogInterceptor());
+ container.addInterceptor(new SecurityInterceptor());
+
+ // entity beans are always CMT
+ container.addInterceptor(new TxInterceptorCMT());
+
+ container.addInterceptor(new EntityInstanceInterceptor());
+ container.addInterceptor(new EntitySynchronizationInterceptor());
+
+ container.addInterceptor(container.createContainerInterceptor());
+
+ // 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 (Throwable 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());
+ } 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();
+ }
+
+ // Protected -----------------------------------------------------
+}