KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb > EjbModule


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.ejb;
23  
24 import java.lang.reflect.Constructor JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.Collections JavaDoc;
30 import java.util.LinkedList JavaDoc;
31 import java.util.HashMap JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.Map JavaDoc;
34 import java.util.ListIterator JavaDoc;
35 import java.util.Set JavaDoc;
36 import java.util.HashSet JavaDoc;
37
38 import javax.ejb.EJBLocalHome JavaDoc;
39 import javax.management.ObjectName JavaDoc;
40 import javax.naming.InitialContext JavaDoc;
41 import javax.naming.NamingException JavaDoc;
42 import javax.security.jacc.PolicyConfiguration JavaDoc;
43 import javax.security.jacc.PolicyConfigurationFactory JavaDoc;
44 import javax.security.jacc.EJBMethodPermission JavaDoc;
45 import javax.security.jacc.PolicyContextException JavaDoc;
46 import javax.security.jacc.EJBRoleRefPermission JavaDoc;
47 import javax.transaction.TransactionManager JavaDoc;
48
49 import org.jboss.deployers.spi.deployer.DeploymentUnit;
50 import org.jboss.deployers.spi.structure.DeploymentContext;
51 import org.jboss.deployment.DeploymentException;
52 import org.jboss.deployment.DeploymentInfo;
53 import org.jboss.deployment.EARDeployerMBean;
54 import org.jboss.logging.Logger;
55 import org.jboss.metadata.ApplicationMetaData;
56 import org.jboss.metadata.BeanMetaData;
57 import org.jboss.metadata.ConfigurationMetaData;
58 import org.jboss.metadata.EntityMetaData;
59 import org.jboss.metadata.InvokerProxyBindingMetaData;
60 import org.jboss.metadata.MetaData;
61 import org.jboss.metadata.SessionMetaData;
62 import org.jboss.metadata.XmlLoadable;
63 import org.jboss.metadata.MethodMetaData;
64 import org.jboss.metadata.SecurityRoleRefMetaData;
65 import org.jboss.mx.loading.RepositoryClassLoader;
66 import org.jboss.ejb.deployers.EjbDeployer;
67 import org.jboss.ejb.plugins.SecurityProxyInterceptor;
68 import org.jboss.ejb.plugins.StatefulSessionInstancePool;
69 import org.jboss.security.AuthenticationManager;
70 import org.jboss.security.AuthorizationManager;
71 import org.jboss.security.RealmMapping;
72 import org.jboss.security.SecurityConstants;
73 import org.jboss.security.Util;
74 import org.jboss.security.authorization.PolicyRegistration;
75 import org.jboss.system.Registry;
76 import org.jboss.system.ServiceControllerMBean;
77 import org.jboss.system.ServiceMBeanSupport;
78 import org.jboss.mx.util.MBeanProxyExt;
79 import org.jboss.mx.util.ObjectNameFactory;
80 import org.jboss.util.loading.DelegatingClassLoader;
81 import org.jboss.virtual.VirtualFile;
82 import org.jboss.web.WebClassLoader;
83 import org.jboss.web.WebServiceMBean;
84 import org.jboss.invocation.InvocationType;
85 import org.jboss.tm.TransactionManagerFactory;
86
87 import org.w3c.dom.Element JavaDoc;
88
89 /**
90  * An EjbModule represents a collection of beans that are deployed as a
91  * unit.
92  *
93  * <p>The beans may use the EjbModule to access other beans within the same
94  * deployment unit.
95  *
96  * @see Container
97  * @see EJBDeployer
98  *
99  * @author <a HREF="mailto:rickard.oberg@telkel.com">Rickard Öberg</a>
100  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
101  * @author <a HREF="mailto:reverbel@ime.usp.br">Francisco Reverbel</a>
102  * @author <a HREF="mailto:Adrian.Brock@HappeningTimes.com">Adrian.Brock</a>
103  * @author <a HREF="mailto:Scott.Stark@jboss.org">Scott Stark</a>
104  * @author <a HREF="mailto:Anil.Saldhana@jboss.org">Anil Saldhana</a>
105  * @version $Revision: 58221 $
106  *
107  * @jmx:mbean extends="org.jboss.system.ServiceMBean"
108  */

109 public class EjbModule
110    extends ServiceMBeanSupport
111    implements EjbModuleMBean
112 {
113    public static final String JavaDoc BASE_EJB_MODULE_NAME = "jboss.j2ee:service=EjbModule";
114
115    public static final ObjectName JavaDoc EJB_MODULE_QUERY_NAME = ObjectNameFactory.create(BASE_EJB_MODULE_NAME + ",*");
116
117    public static String JavaDoc DEFAULT_STATELESS_CONFIGURATION = "Default Stateless SessionBean";
118    public static String JavaDoc DEFAULT_STATEFUL_CONFIGURATION = "Default Stateful SessionBean";
119    public static String JavaDoc DEFAULT_ENTITY_BMP_CONFIGURATION = "Default BMP EntityBean";
120    public static String JavaDoc DEFAULT_ENTITY_CMP_CONFIGURATION = "Default CMP EntityBean";
121    public static String JavaDoc DEFAULT_MESSAGEDRIVEN_CONFIGURATION = "Default MesageDriven Bean";
122
123    // Constants uses with container interceptor configurations
124
public static final int BMT = 1;
125    public static final int CMT = 2;
126    public static final int ANY = 3;
127
128    static final String JavaDoc BMT_VALUE = "Bean";
129    static final String JavaDoc CMT_VALUE = "Container";
130    static final String JavaDoc ANY_VALUE = "Both";
131
132    /** Class logger. */
133    private static final Logger log = Logger.getLogger(EjbModule.class);
134
135    // Constants -----------------------------------------------------
136

137    // Attributes ----------------------------------------------------
138

139    /** HashMap<ejbName, Container> the containers for this deployment unit. */
140    HashMap JavaDoc containers = new HashMap JavaDoc();
141    /** The containers in their ApplicationMetaData ordering */
142    LinkedList JavaDoc containerOrdering = new LinkedList JavaDoc();
143    /** HashMap<ejbName, EJBLocalHome> of local homes */
144    HashMap JavaDoc localHomes = new HashMap JavaDoc();
145
146    /** Class loader of this deployment unit. */
147    ClassLoader JavaDoc classLoader = null;
148
149    /** Name of this deployment unit, url it was deployed from */
150    final String JavaDoc name;
151
152    private DeploymentUnit deploymentUnit;
153
154    private ServiceControllerMBean serviceController;
155
156    private final Map JavaDoc moduleData =
157       Collections.synchronizedMap(new HashMap JavaDoc());
158
159    private ObjectName JavaDoc webServiceName;
160
161    private TransactionManagerFactory tmFactory;
162
163    /** Whether we are call by value */
164    private boolean callByValue;
165    private ApplicationMetaData appMetaData;
166
167    public EjbModule(final DeploymentUnit unit, ApplicationMetaData metaData)
168    {
169       this.appMetaData = metaData;
170       this.deploymentUnit = unit;
171       String JavaDoc name = deploymentUnit.getName();
172       if (name.endsWith("/"))
173       {
174          name = name.substring(0, name.length() - 1);
175       }
176       this.name = name;
177    }
178    /**
179     * @deprecated DeploymentInfo is obsolete
180     */

181    public EjbModule(final DeploymentInfo di, TransactionManager JavaDoc tm,
182          ObjectName JavaDoc webServiceName)
183    {
184       this.name = "deprecated";
185    }
186
187    public void setTransactionManagerFactory(TransactionManagerFactory tm)
188    {
189       this.tmFactory = tm;
190    }
191
192    public ObjectName JavaDoc getWebServiceName()
193    {
194       return webServiceName;
195    }
196    public void setWebServiceName(ObjectName JavaDoc webServiceName)
197    {
198       this.webServiceName = webServiceName;
199    }
200
201    public Map JavaDoc getModuleDataMap()
202    {
203       return moduleData;
204    }
205
206    public Object JavaDoc getModuleData(Object JavaDoc key)
207    {
208       return moduleData.get(key);
209    }
210
211    public void putModuleData(Object JavaDoc key, Object JavaDoc value)
212    {
213       moduleData.put(key, value);
214    }
215
216    public void removeModuleData(Object JavaDoc key)
217    {
218       moduleData.remove(key);
219    }
220
221    /**
222     * Add a container to this deployment unit.
223     *
224     * @param con
225     */

226    private void addContainer(Container con)
227       throws DeploymentException
228    {
229       String JavaDoc ejbName = con.getBeanMetaData().getEjbName();
230       if (containers.containsKey(ejbName))
231          throw new DeploymentException("Duplicate ejb-name. Container for "
232             + ejbName + " already exists.");
233       containers.put(ejbName, con);
234       containerOrdering.add(con);
235       con.setEjbModule(this);
236    }
237
238    /**
239     * Remove a container from this deployment unit.
240     *
241     * @param con
242     */

243    public void removeContainer(Container con)
244    {
245       containers.remove(con.getBeanMetaData().getEjbName());
246       containerOrdering.remove(con);
247    }
248
249    public void addLocalHome(Container con, EJBLocalHome JavaDoc localHome)
250    {
251       localHomes.put(con.getBeanMetaData().getEjbName(), localHome);
252    }
253
254    public void removeLocalHome(Container con)
255    {
256       localHomes.remove(con.getBeanMetaData().getEjbName());
257    }
258
259    public EJBLocalHome JavaDoc getLocalHome(Container con)
260    {
261       return (EJBLocalHome JavaDoc) localHomes.get(con.getBeanMetaData().getEjbName());
262    }
263
264    /**
265     * Whether the container is call by value
266     *
267     * @return true for call by value
268     */

269    public boolean isCallByValue()
270    {
271       return callByValue;
272    }
273    
274    /**
275     * Get a container from this deployment unit that corresponds to a given name
276     *
277     * @param name ejb-name name defined in ejb-jar.xml
278     *
279     * @return container for the named bean, or null if the container was
280     * not found
281     */

282    public Container getContainer(String JavaDoc name)
283    {
284       return (Container) containers.get(name);
285    }
286
287    /**
288     * Get all containers in this deployment unit.
289     *
290     * @return a collection of containers for each enterprise bean in this
291     * deployment unit.
292     * @jmx:managed-attribute
293     */

294    public Collection JavaDoc getContainers()
295    {
296       return containerOrdering;
297    }
298
299    /**
300     * Get the class loader of this deployment unit.
301     *
302     * @return
303     */

304    public ClassLoader JavaDoc getClassLoader()
305    {
306       return classLoader;
307    }
308
309    /**
310     * Set the class loader of this deployment unit
311     *
312     * @param cl
313     */

314    public void setClassLoader(ClassLoader JavaDoc cl)
315    {
316       this.classLoader = cl;
317    }
318
319    /**
320     * Get the URL from which this deployment unit was deployed
321     *
322     * @return The URL from which this Application was deployed.
323     */

324    public URL JavaDoc getURL()
325    {
326       return appMetaData.getUrl();
327    }
328
329    // Service implementation ----------------------------------------
330

331    protected void createService() throws Exception JavaDoc
332    {
333       serviceController = (ServiceControllerMBean)
334          MBeanProxyExt.create(ServiceControllerMBean.class,
335                               ServiceControllerMBean.OBJECT_NAME,
336                               server);
337
338       log.debug("createService, begin");
339
340       //Ask the ejb deployer whether we are call by value
341
try
342       {
343          if (((Boolean JavaDoc) server.getAttribute(EJBDeployerMBean.OBJECT_NAME, "CallByValue")).booleanValue())
344             callByValue = true;
345       }
346       catch (Exception JavaDoc ignored)
347       {
348          log.debug("Unable to ask the EJBDeployer whether we are call by value", ignored);
349       }
350
351       //Ask the ear deployer whether we are call by value
352
try
353       {
354          if (callByValue == false && ((Boolean JavaDoc) server.getAttribute(EARDeployerMBean.OBJECT_NAME, "CallByValue")).booleanValue())
355             callByValue = true;
356       }
357       catch (Exception JavaDoc ignored)
358       {
359          log.debug("Unable to ask the EARDeployer whether we are call by value", ignored);
360       }
361       
362       //Set up the beans in this module.
363
try
364       {
365          Iterator JavaDoc beans = appMetaData.getEnterpriseBeans();
366          String JavaDoc contextID = appMetaData.getJaccContextID();
367          if( contextID == null )
368             contextID = EjbDeployer.shortNameFromDeploymentName(deploymentUnit.getName());
369          appMetaData.setJaccContextID(contextID);
370          PolicyConfigurationFactory JavaDoc pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
371          PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(contextID, true);
372          while (beans.hasNext())
373          {
374             BeanMetaData bean = (BeanMetaData) beans.next();
375             log.info("Deploying " + bean.getEjbName());
376             Container con = createContainer(bean, deploymentUnit);
377             addContainer(con);
378             //@todo support overriding the context id via metadata is needed
379
con.setJaccContextID(contextID);
380             // Register the permissions with the JACC layer
381
createPermissions(bean, pc);
382             deploymentUnit.addAttachment(PolicyConfiguration JavaDoc.class, pc);
383             // Link this to the parent PC
384
DeploymentContext current = deploymentUnit.getDeploymentContext();
385             while (current.getParent() != null)
386                current = current.getParent();
387             PolicyConfiguration JavaDoc parentPC =
388                current.getTransientAttachments().getAttachment(PolicyConfiguration JavaDoc.class);
389             if (parentPC != null && parentPC != pc)
390                parentPC.linkConfiguration(pc);
391          }
392          pc.commit();
393
394          //only one iteration should be necessary, but we won't sweat it.
395
//2 iterations are needed by cmp...jdbc/bridge/JDBCCMRFieldBridge which
396
//assumes persistence managers are all set up for every
397
//bean in the relationship!
398
ListIterator JavaDoc iter = containerOrdering.listIterator();
399          while( iter.hasNext() )
400          {
401             Container con = (Container) iter.next();
402             ObjectName JavaDoc jmxName = con.getJmxName();
403             /* Add the container mbean to the deployment mbeans so the state
404                of the deployment can be tracked.
405             */

406             server.registerMBean(con, jmxName);
407             //deploymentUnit.mbeans.add(jmxName);
408
BeanMetaData metaData = con.getBeanMetaData();
409             Collection JavaDoc depends = metaData.getDepends();
410             serviceController.create(jmxName, depends);
411             // We keep the hashCode around for fast creation of proxies
412
int jmxHash = jmxName.hashCode();
413             Registry.bind(new Integer JavaDoc(jmxHash), jmxName);
414             log.debug("Bound jmxName=" + jmxName + ", hash=" + jmxHash + "into Registry");
415          }
416
417          //Register any available XACML Policies
418
String JavaDoc securityDomain = Util.unprefixSecurityDomain(appMetaData.getSecurityDomain());
419          if(securityDomain == null)
420             securityDomain = SecurityConstants.DEFAULT_EJB_APPLICATION_POLICY; //Fallback
421
VirtualFile xacmlFile = deploymentUnit.getMetaDataFile("jboss-xacml-policy.xml");
422          if(xacmlFile != null)
423          {
424             AuthorizationManager authzmgr = Util.getAuthorizationManager(securityDomain);
425             if(authzmgr instanceof PolicyRegistration)
426             {
427                PolicyRegistration xam = (PolicyRegistration)authzmgr;
428                xam.registerPolicy(contextID, xacmlFile.toURL());
429             }
430          }
431       }
432       catch (Exception JavaDoc e)
433       {
434          destroyService();
435          throw e;
436       } // end of try-catch
437

438    }
439
440    /**
441     * The mbean Service interface <code>start</code> method calls
442     * the start method on each contatiner, then the init method on each
443     * container. Conversion to a different registration system with one-phase
444     * startup is conceivable.
445     *
446     * @exception Exception if an error occurs
447     */

448    protected void startService() throws Exception JavaDoc
449    {
450       // before EntityContainer returns from the startService, its PM should be usable
451
ListIterator JavaDoc iter = containerOrdering.listIterator();
452       while( iter.hasNext() )
453       {
454          Container con = (Container) iter.next();
455          if(con.getBeanMetaData().isEntity())
456          {
457             ClassLoader JavaDoc oldCl = SecurityActions.getContextClassLoader();
458             SecurityActions.setContextClassLoader(con.getClassLoader());
459
460             try
461             {
462                ((EntityContainer)con).getPersistenceManager().start();
463             }
464             finally
465             {
466                // Reset classloader
467
SecurityActions.setContextClassLoader(oldCl);
468             }
469          }
470       }
471
472       iter = containerOrdering.listIterator();
473       while( iter.hasNext() )
474       {
475          Container con = (Container) iter.next();
476          log.debug("startService, starting container: " + con.getBeanMetaData().getEjbName());
477          serviceController.start(con.getJmxName());
478       }
479    }
480
481    /**
482     * Stops all the containers of this application.
483     */

484    protected void stopService() throws Exception JavaDoc
485    {
486       ListIterator JavaDoc iter = containerOrdering.listIterator(containerOrdering.size());
487       while( iter.hasPrevious() )
488       {
489          Container con = (Container) iter.previous();
490          try
491          {
492             ObjectName JavaDoc jmxName = con.getJmxName();
493             // The container may already be destroyed so validate metaData
494
BeanMetaData metaData = con.getBeanMetaData();
495             String JavaDoc ejbName = metaData != null ? metaData.getEjbName() : "Unknown";
496             log.debug("stopService, stopping container: " + ejbName);
497
498             serviceController.stop(jmxName);
499          }
500          catch (Exception JavaDoc e)
501          {
502             log.error("unexpected exception stopping Container: " + con.getJmxName(), e);
503          } // end of try-catch
504
}
505    }
506
507    protected void destroyService() throws Exception JavaDoc
508    {
509       WebServiceMBean webServer = null;
510       if (webServiceName != null)
511       {
512          webServer =
513             (WebServiceMBean) MBeanProxyExt.create(WebServiceMBean.class,
514                                                    webServiceName);
515       }
516       ListIterator JavaDoc iter = containerOrdering.listIterator(containerOrdering.size());
517       // Unegister the permissions with the JACC layer
518
String JavaDoc contextID = appMetaData.getJaccContextID();
519       PolicyConfigurationFactory JavaDoc pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
520       PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(contextID, true);
521       pc.delete();
522       //Unregister any xacml policies
523
String JavaDoc securityDomain = Util.unprefixSecurityDomain(appMetaData.getSecurityDomain());
524       if(securityDomain != null)
525       {
526          AuthorizationManager authzmgr = Util.getAuthorizationManager(securityDomain);
527          if(authzmgr instanceof PolicyRegistration)
528          {
529             PolicyRegistration xam = (PolicyRegistration)authzmgr;
530             xam.deRegisterPolicy(contextID);
531          }
532       }
533       
534       while ( iter.hasPrevious() )
535       {
536          Container con = (Container) iter.previous();
537          ObjectName JavaDoc jmxName = con.getJmxName();
538          int conState = con.getState();
539          boolean destroyContainer = true;
540          log.debug("Looking to destroy container: " + jmxName
541             + ", state: " + con.getStateString() + ", destroy: " + destroyContainer);
542
543          // always unregister from Registry
544
int jmxHash = jmxName.hashCode();
545          Registry.unbind(new Integer JavaDoc(jmxHash));
546          
547          // Unregister the web classloader
548
//Removing the wcl should probably be done in stop of the container,
549
// but I don't want to look for errors today.
550
if (webServer != null)
551          {
552             ClassLoader JavaDoc wcl = con.getWebClassLoader();
553             if (wcl != null)
554             {
555                try
556                {
557                   webServer.removeClassLoader(wcl);
558                }
559                catch (Throwable JavaDoc e)
560                {
561                   log.warn("Failed to unregister webClassLoader", e);
562                }
563             }
564          }
565
566          // Only destroy containers that have been created or started
567
if( destroyContainer )
568          {
569             try
570             {
571                 serviceController.destroy(jmxName);
572                 serviceController.remove(jmxName);
573                log.info("Undeployed " + con.getBeanMetaData().getEjbName());
574                if( server.isRegistered(jmxName) )
575                 server.unregisterMBean(jmxName);
576             }
577             catch (Throwable JavaDoc e)
578             {
579                log.error("unexpected exception destroying Container: " + jmxName, e);
580             } // end of try-catch
581
}
582
583
584          // cleanup container
585
con.setBeanMetaData(null);
586          con.setWebClassLoader(null);
587          con.setClassLoader(null);
588          con.setEjbModule(null);
589          con.setDeploymentInfo(null);
590          con.setTransactionManager(null);
591          con.setSecurityManager(null);
592          con.setRealmMapping(null);
593          con.setSecurityProxy(null);
594          con.setAuthorizationManager(null);
595          con.proxyFactories.clear();
596       }
597
598       this.containers.clear();
599       this.localHomes.clear();
600       this.containerOrdering.clear();
601       this.moduleData.clear();
602       this.serviceController = null;
603    }
604
605    // ******************
606
// Container Creation
607
// ******************
608

609    private Container createContainer(BeanMetaData bean, DeploymentUnit unit)
610       throws Exception JavaDoc
611    {
612       Container container = null;
613       // Added message driven deployment
614
if (bean.isMessageDriven())
615       {
616          container = createMessageDrivenContainer(bean, unit);
617       }
618       else if (bean.isSession()) // Is session?
619
{
620          if (((SessionMetaData) bean).isStateless()) // Is stateless?
621
{
622             container = createStatelessSessionContainer((SessionMetaData) bean, unit);
623          }
624          else // Stateful
625
{
626             container = createStatefulSessionContainer((SessionMetaData) bean, unit);
627          }
628       }
629       else // Entity
630
{
631          container = createEntityContainer(bean, unit);
632       }
633
634       container.setDeploymentUnit(unit);
635
636       return container;
637    }
638
639    private MessageDrivenContainer createMessageDrivenContainer(BeanMetaData bean,
640                                                                DeploymentUnit unit)
641       throws Exception JavaDoc
642    {
643       // get the container configuration for this bean
644
// a default configuration is now always provided
645
ConfigurationMetaData conf = bean.getContainerConfiguration();
646       // Stolen from Stateless deploy
647
// Create container
648
MessageDrivenContainer container = new MessageDrivenContainer();
649       int transType = bean.isContainerManagedTx() ? CMT : BMT;
650
651       initializeContainer(container, conf, bean, transType, unit);
652       createProxyFactories(bean, container);
653       container.setInstancePool(createInstancePool(conf, unit.getClassLoader()));
654
655       return container;
656    }
657
658    private StatelessSessionContainer createStatelessSessionContainer(SessionMetaData bean,
659                                                                      DeploymentUnit unit)
660       throws Exception JavaDoc
661    {
662       // get the container configuration for this bean
663
// a default configuration is now always provided
664
ConfigurationMetaData conf = bean.getContainerConfiguration();
665       // Create container
666
StatelessSessionContainer container = new StatelessSessionContainer();
667       int transType = bean.isContainerManagedTx() ? CMT : BMT;
668       initializeContainer(container, conf, bean, transType, unit);
669       if (bean.getHome() != null || bean.getServiceEndpoint()!=null)
670       {
671          createProxyFactories(bean, container);
672       }
673       container.setInstancePool(createInstancePool(conf, unit.getClassLoader()));
674
675       return container;
676    }
677
678    private StatefulSessionContainer createStatefulSessionContainer(SessionMetaData bean,
679                                                                    DeploymentUnit unit)
680       throws Exception JavaDoc
681    {
682       // get the container configuration for this bean
683
// a default configuration is now always provided
684
ConfigurationMetaData conf = bean.getContainerConfiguration();
685       // Create container
686
StatefulSessionContainer container = new StatefulSessionContainer();
687       int transType = bean.isContainerManagedTx() ? CMT : BMT;
688       initializeContainer(container, conf, bean, transType, unit);
689       if (bean.getHome() != null || bean.getServiceEndpoint()!=null)
690       {
691          createProxyFactories(bean, container);
692       }
693
694       ClassLoader JavaDoc cl = unit.getClassLoader();
695       container.setInstanceCache(createInstanceCache(conf, cl));
696       // No real instance pool, use the shadow class
697
StatefulSessionInstancePool ip = new StatefulSessionInstancePool();
698       ip.importXml(conf.getContainerPoolConf());
699       container.setInstancePool(ip);
700       // Set persistence manager
701
container.setPersistenceManager((StatefulSessionPersistenceManager) cl.loadClass(conf.getPersistenceManager()).newInstance());
702       //Set the bean Lock Manager
703
container.setLockManager(createBeanLockManager(container, false, conf.getLockClass(), cl));
704
705       return container;
706    }
707
708    private EntityContainer createEntityContainer(BeanMetaData bean,
709                                                  DeploymentUnit unit)
710       throws Exception JavaDoc
711    {
712       // get the container configuration for this bean
713
// a default configuration is now always provided
714
ConfigurationMetaData conf = bean.getContainerConfiguration();
715       // Create container
716
EntityContainer container = new EntityContainer();
717       int transType = CMT;
718       initializeContainer(container, conf, bean, transType, unit);
719       if (bean.getHome() != null)
720       {
721          createProxyFactories(bean, container);
722       }
723
724       ClassLoader JavaDoc cl = unit.getClassLoader();
725       container.setInstanceCache(createInstanceCache(conf, cl));
726       container.setInstancePool(createInstancePool(conf, cl));
727       //Set the bean Lock Manager
728
boolean reentrant = ((EntityMetaData) bean).isReentrant();
729       BeanLockManager lockMgr = createBeanLockManager(container, reentrant, conf.getLockClass(), cl);
730       container.setLockManager(lockMgr);
731
732       // Set persistence manager
733
if (((EntityMetaData) bean).isBMP())
734       {
735          Class JavaDoc pmClass = cl.loadClass(conf.getPersistenceManager());
736          EntityPersistenceManager pm = (EntityPersistenceManager) pmClass.newInstance();
737          container.setPersistenceManager(pm);
738       }
739       else
740       {
741          // CMP takes a manager and a store
742
org.jboss.ejb.plugins.CMPPersistenceManager persistenceManager =
743             new org.jboss.ejb.plugins.CMPPersistenceManager();
744
745          //Load the store from configuration
746
Class JavaDoc pmClass = cl.loadClass(conf.getPersistenceManager());
747          EntityPersistenceStore pm = (EntityPersistenceStore) pmClass.newInstance();
748          persistenceManager.setPersistenceStore(pm);
749          // Set the manager on the container
750
container.setPersistenceManager(persistenceManager);
751       }
752
753       return container;
754    }
755
756    // **************
757
// Helper Methods
758
// **************
759

760    /**
761     * Perform the common steps to initializing a container.
762     */

763    private void initializeContainer(Container container,
764                                     ConfigurationMetaData conf,
765                                     BeanMetaData bean,
766                                     int transType,
767                                     DeploymentUnit unit)
768       throws NamingException JavaDoc, DeploymentException
769    {
770       // Create local classloader for this container
771
// For loading resources that must come from the local jar. Not for loading classes!
772
// The VFS should be used for this
773
// container.setLocalClassLoader(new URLClassLoader(new URL[0], localCl));
774
// Set metadata (do it *before* creating the container's WebClassLoader)
775
container.setEjbModule(this);
776       container.setBeanMetaData(bean);
777
778       ClassLoader JavaDoc unitCl = unit.getClassLoader();
779       // Create the container's WebClassLoader
780
// and register it with the web service.
781
String JavaDoc webClassLoaderName = getWebClassLoader(conf, bean);
782       log.debug("Creating WebClassLoader of class " + webClassLoaderName);
783       WebClassLoader wcl = null;
784       try
785       {
786          Class JavaDoc clazz = unitCl.loadClass(webClassLoaderName);
787          Constructor JavaDoc constructor = clazz.getConstructor(
788             new Class JavaDoc[]{ObjectName JavaDoc.class, RepositoryClassLoader.class});
789          wcl = (WebClassLoader) constructor.newInstance(
790             new Object JavaDoc[]{container.getJmxName(), unitCl});
791       }
792       catch (Exception JavaDoc e)
793       {
794          throw new DeploymentException(
795             "Failed to create WebClassLoader of class "
796             + webClassLoaderName + ": ", e);
797       }
798
799       if (webServiceName != null)
800       {
801          WebServiceMBean webServer =
802             (WebServiceMBean) MBeanProxyExt.create(WebServiceMBean.class,
803                                                    webServiceName);
804          URL JavaDoc[] codebase = {webServer.addClassLoader(wcl)};
805
806
807          wcl.setWebURLs(codebase);
808       } // end of if ()
809

810       container.setWebClassLoader(wcl);
811       // Create classloader for this container
812
// Only used to unique the bean ENC and does not augment class loading
813
container.setClassLoader(new DelegatingClassLoader(wcl));
814
815       // Set transaction manager
816
InitialContext JavaDoc iniCtx = new InitialContext JavaDoc();
817       container.setTransactionManager(tmFactory.getTransactionManager());
818
819       // Set security domain manager
820
String JavaDoc securityDomain = bean.getApplicationMetaData().getSecurityDomain();
821       String JavaDoc confSecurityDomain = conf.getSecurityDomain();
822       // Default the config security to the application security manager
823
if (confSecurityDomain == null)
824          confSecurityDomain = securityDomain;
825
826       // Check for an empty confSecurityDomain which signifies to disable security
827
if (confSecurityDomain != null && confSecurityDomain.length() == 0)
828          confSecurityDomain = null;
829
830       if (confSecurityDomain != null)
831       { // Either the application has a security domain or the container has security setup
832
try
833          {
834             log.debug("Setting security domain from: " + confSecurityDomain);
835             Object JavaDoc securityMgr = iniCtx.lookup(confSecurityDomain);
836             AuthenticationManager ejbS = (AuthenticationManager) securityMgr;
837             RealmMapping rM = (RealmMapping) securityMgr;
838             container.setSecurityManager(ejbS);
839             container.setRealmMapping(rM);
840             container.setAuthorizationManager(Util.getAuthorizationManager(confSecurityDomain));
841          }
842          catch (NamingException JavaDoc e)
843          {
844             throw new DeploymentException("Could not find the security-domain, name=" + confSecurityDomain, e);
845          }
846          catch (Exception JavaDoc e)
847          {
848             throw new DeploymentException("Invalid security-domain specified, name=" + confSecurityDomain, e);
849          }
850       }
851
852       // Load the security proxy instance if one was configured
853
String JavaDoc securityProxyClassName = bean.getSecurityProxy();
854       if (securityProxyClassName != null)
855       {
856          try
857          {
858             Class JavaDoc proxyClass = unitCl.loadClass(securityProxyClassName);
859             Object JavaDoc proxy = proxyClass.newInstance();
860             container.setSecurityProxy(proxy);
861             log.debug("setSecurityProxy, " + proxy);
862          }
863          catch (Exception JavaDoc e)
864          {
865             throw new DeploymentException("Failed to create SecurityProxy of type: " +
866                                           securityProxyClassName, e);
867          }
868       }
869
870       // Install the container interceptors based on the configuration
871
addInterceptors(container, transType, conf.getContainerInterceptorsConf());
872    }
873
874    /**
875     * Return the name of the WebClassLoader class for this ejb.
876     */

877    private static String JavaDoc getWebClassLoader(ConfigurationMetaData conf,
878                                            BeanMetaData bmd)
879       throws DeploymentException
880    {
881       String JavaDoc webClassLoader = null;
882       Iterator JavaDoc it = bmd.getInvokerBindings();
883       int count = 0;
884       while (it.hasNext())
885       {
886          String JavaDoc invoker = (String JavaDoc) it.next();
887          ApplicationMetaData amd = bmd.getApplicationMetaData();
888          InvokerProxyBindingMetaData imd =
889             amd.getInvokerProxyBindingMetaDataByName(invoker);
890          if (imd == null)
891          {
892             String JavaDoc msg = "Failed to find InvokerProxyBindingMetaData for: '"
893                + invoker + "'. Check the invoker-proxy-binding-name to "
894                + "invoker-proxy-binding/name mappings in jboss.xml";
895             throw new DeploymentException(msg);
896          }
897
898          Element JavaDoc proxyFactoryConfig = imd.getProxyFactoryConfig();
899          String JavaDoc webCL = MetaData.getOptionalChildContent(proxyFactoryConfig,
900                                                          "web-class-loader");
901          if (webCL != null)
902          {
903             log.debug("Invoker " + invoker
904                       + " specified WebClassLoader class" + webCL);
905             webClassLoader = webCL;
906             count++;
907          }
908       }
909       if (count > 1)
910       {
911          log.warn(count + " invokers have WebClassLoader specifications.");
912          log.warn("Using the last specification seen ("
913                   + webClassLoader + ").");
914       }
915       else if (count == 0)
916       {
917          webClassLoader = conf.getWebClassLoader();
918       }
919       return webClassLoader;
920    }
921
922    /**
923     * Given a container-interceptors element of a container-configuration,
924     * add the indicated interceptors to the container depending on the container
925     * transcation type and metricsEnabled flag.
926     *
927     *
928     * @todo marcf: frankly the transaction type stuff makes no sense to me, we have externalized
929     * the container stack construction in jbossxml and I don't see why or why there would be a
930     * type missmatch on the transaction
931     *
932     * @param container the container instance to setup.
933     * @param transType one of the BMT, CMT or ANY constants.
934     * @param element the container-interceptors element from the
935     * container-configuration.
936     */

937    private void addInterceptors(Container container,
938                                 int transType,
939                                 Element JavaDoc element)
940       throws DeploymentException
941    {
942       // Get the interceptor stack(either jboss.xml or standardjboss.xml)
943
Iterator JavaDoc interceptorElements = MetaData.getChildrenByTagName(element, "interceptor");
944       String JavaDoc transTypeString = stringTransactionValue(transType);
945       ClassLoader JavaDoc loader = container.getClassLoader();
946       /* First build the container interceptor stack from interceptorElements
947          match transType and metricsEnabled values
948       */

949       ArrayList JavaDoc istack = new ArrayList JavaDoc();
950       while (interceptorElements != null && interceptorElements.hasNext())
951       {
952          Element JavaDoc ielement = (Element JavaDoc) interceptorElements.next();
953          /* Check that the interceptor is configured for the transaction mode of the bean
954             by comparing its 'transaction' attribute to the string representation
955             of transType
956             FIXME: marcf, WHY???????
957          */

958          String JavaDoc transAttr = ielement.getAttribute("transaction");
959          if (transAttr == null || transAttr.length() == 0)
960             transAttr = ANY_VALUE;
961          if (transAttr.equalsIgnoreCase(ANY_VALUE) || transAttr.equalsIgnoreCase(transTypeString))
962          { // The transaction type matches the container bean trans type, check the metricsEnabled
963
String JavaDoc metricsAttr = ielement.getAttribute("metricsEnabled");
964             boolean metricsInterceptor = metricsAttr.equalsIgnoreCase("true");
965             try
966             {
967                boolean metricsEnabled = ((Boolean JavaDoc) server.getAttribute(EJBDeployerMBean.OBJECT_NAME,
968                                                                        "MetricsEnabled")).booleanValue();
969                if (metricsEnabled == false && metricsInterceptor == true)
970                {
971                   continue;
972                }
973             }
974             catch (Exception JavaDoc e)
975             {
976                //throw new DeploymentException("couldn't contace EJBDeployer!", e);
977
log.debug("Couldn't get MetricsEnabled from EJBDeployer: " + e.getMessage());
978             } // end of try-catch
979

980
981             String JavaDoc className = null;
982             try
983             {
984                className = MetaData.getFirstElementContent(ielement, null);
985                Class JavaDoc clazz = loader.loadClass(className);
986                Interceptor interceptor = (Interceptor) clazz.newInstance();
987                if (interceptor instanceof XmlLoadable)
988                {
989                   ((XmlLoadable)interceptor).importXml(ielement);
990                }
991                istack.add(interceptor);
992             }
993             catch (ClassNotFoundException JavaDoc e)
994             {
995                log.warn("Could not load the " + className + " interceptor", e);
996             }
997             catch (Exception JavaDoc e)
998             {
999                log.warn("Could not load the " + className + " interceptor for this container", e);
1000            }
1001         }
1002      }
1003
1004      if (istack.size() == 0)
1005         log.warn("There are no interceptors configured. Check the standardjboss.xml file");
1006
1007      // Now add the interceptors to the container
1008
for (int i = 0; i < istack.size(); i++)
1009      {
1010         Interceptor interceptor = (Interceptor) istack.get(i);
1011         container.addInterceptor(interceptor);
1012      }
1013
1014      /* If there is a security proxy associated with the container add its
1015         interceptor just before the container interceptor
1016      */

1017      if (container.getSecurityProxy() != null)
1018         container.addInterceptor(new SecurityProxyInterceptor());
1019
1020      // Finally we add the last interceptor from the container
1021
container.addInterceptor(container.createContainerInterceptor());
1022   }
1023
1024   private void createPermissions(BeanMetaData bean, PolicyConfiguration JavaDoc pc)
1025      throws PolicyContextException JavaDoc
1026   {
1027      // Process the method-permission MethodMetaData
1028
Iterator JavaDoc iter = bean.getPermissionMethods();
1029      while( iter.hasNext() )
1030      {
1031         MethodMetaData mmd = (MethodMetaData) iter.next();
1032         String JavaDoc[] params = null;
1033         if( mmd.isParamGiven() )
1034            params = mmd.getMethodParams();
1035         String JavaDoc methodName = mmd.getMethodName();
1036         if( methodName != null && methodName.equals("*") )
1037            methodName = null;
1038         EJBMethodPermission JavaDoc p = new EJBMethodPermission JavaDoc(mmd.getEjbName(),
1039            methodName, mmd.getInterfaceType(), params);
1040         if( mmd.isUnchecked() )
1041         {
1042            pc.addToUncheckedPolicy(p);
1043         }
1044         else
1045         {
1046            Set JavaDoc roles = mmd.getRoles();
1047            Iterator JavaDoc riter = roles.iterator();
1048            while( riter.hasNext() )
1049            {
1050               String JavaDoc role = (String JavaDoc) riter.next();
1051               pc.addToRole(role, p);
1052            }
1053         }
1054      }
1055      // Process the exclude-list MethodMetaData
1056
iter = bean.getExcludedMethods();
1057      while( iter.hasNext() )
1058      {
1059         MethodMetaData mmd = (MethodMetaData) iter.next();
1060         String JavaDoc[] params = null;
1061         if( mmd.isParamGiven() )
1062            params = mmd.getMethodParams();
1063         EJBMethodPermission JavaDoc p = new EJBMethodPermission JavaDoc(mmd.getEjbName(),
1064            mmd.getMethodName(), mmd.getInterfaceType(), params);
1065         pc.addToExcludedPolicy(p);
1066      }
1067      // Process the security-role-ref SecurityRoleRefMetaData
1068
iter = bean.getSecurityRoleReferences();
1069      while( iter.hasNext() )
1070      {
1071         SecurityRoleRefMetaData srrmd = (SecurityRoleRefMetaData) iter.next();
1072         EJBRoleRefPermission JavaDoc p = new EJBRoleRefPermission JavaDoc(bean.getEjbName(), srrmd.getName());
1073         pc.addToRole(srrmd.getLink(), p);
1074      }
1075      /* Special handling of stateful session bean getEJBObject due how the
1076      stateful session handles acquire the proxy by sending an invocation to
1077      the ejb container.
1078      */

1079      if( bean instanceof SessionMetaData )
1080      {
1081         SessionMetaData smd = (SessionMetaData) bean;
1082         if( smd.isStateful() )
1083         {
1084            EJBMethodPermission JavaDoc p = new EJBMethodPermission JavaDoc(bean.getEjbName(),
1085               "getEJBObject", "Home", null);
1086            pc.addToUncheckedPolicy(p);
1087         }
1088      }
1089   }
1090
1091   /** Create any JACC permissions for the ejb methods that were not explicitly
1092    * assigned method-permission or exclude-list mappings.
1093    * @param con - the ejb container
1094    * @param bean - the bean metadata
1095    * @throws ClassNotFoundException
1096    * @throws PolicyContextException
1097    */

1098   void createMissingPermissions(Container con, BeanMetaData bean)
1099      throws ClassNotFoundException JavaDoc, PolicyContextException JavaDoc
1100   {
1101      String JavaDoc contextID = con.getJaccContextID();
1102      PolicyConfigurationFactory JavaDoc pcFactory = PolicyConfigurationFactory.getPolicyConfigurationFactory();
1103      PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(contextID, false);
1104      Class JavaDoc clazz = con.getHomeClass();
1105      // If there is no security domain mark all methods as unchecked
1106
boolean hasSecurityDomain = con.getSecurityManager() != null;
1107      boolean exclude = hasSecurityDomain ? bean.isExcludeMissingMethods() : false;
1108      
1109      if( clazz != null )
1110      {
1111         addMissingMethodPermissions(bean, exclude, clazz, InvocationType.HOME, pc);
1112      }
1113      clazz = con.getLocalHomeClass();
1114      if( clazz != null )
1115      {
1116         addMissingMethodPermissions(bean, exclude, clazz, InvocationType.LOCALHOME, pc);
1117      }
1118      clazz = con.getLocalClass();
1119      if( clazz != null )
1120      {
1121         addMissingMethodPermissions(bean, exclude, clazz, InvocationType.LOCAL, pc);
1122      }
1123      clazz = con.getRemoteClass();
1124      if( clazz != null )
1125      {
1126         addMissingMethodPermissions(bean, exclude, clazz, InvocationType.REMOTE, pc);
1127      }
1128      pc.commit();
1129   }
1130
1131   private void getInterfaces(Class JavaDoc iface, HashSet JavaDoc tmp)
1132   {
1133      tmp.add(iface);
1134      Class JavaDoc[] ifaces = iface.getInterfaces();
1135      for(int n = 0; n < ifaces.length; n ++)
1136      {
1137         Class JavaDoc iface2 = ifaces[n];
1138         tmp.add(iface2);
1139         getInterfaces(iface2, tmp);
1140      }
1141   }
1142   private void addMissingMethodPermissions(BeanMetaData bean, boolean exclude,
1143      Class JavaDoc iface, InvocationType type, PolicyConfiguration JavaDoc pc)
1144      throws PolicyContextException JavaDoc
1145   {
1146      String JavaDoc ejbName = bean.getEjbName();
1147      HashSet JavaDoc tmp = new HashSet JavaDoc();
1148      getInterfaces(iface, tmp);
1149      Class JavaDoc[] ifaces = new Class JavaDoc[tmp.size()];
1150      tmp.toArray(ifaces);
1151      for(int n = 0; n < ifaces.length; n ++)
1152      {
1153         Class JavaDoc c = ifaces[n];
1154         Method JavaDoc[] methods = c.getDeclaredMethods();
1155         for(int m = 0; m < methods.length; m ++)
1156         {
1157            String JavaDoc methodName = methods[m].getName();
1158            Class JavaDoc[] params = methods[m].getParameterTypes();
1159            // See if there is a method-permission
1160
if( bean.hasMethodPermission(methodName, params, type) )
1161               continue;
1162            // Create a permission for the missing method-permission
1163
EJBMethodPermission JavaDoc p = new EJBMethodPermission JavaDoc(ejbName,
1164               type.toInterfaceString(), methods[m]);
1165            if( exclude )
1166               pc.addToExcludedPolicy(p);
1167            else
1168               pc.addToUncheckedPolicy(p);
1169         }
1170      }
1171   }
1172
1173   private static String JavaDoc stringTransactionValue(int transType)
1174   {
1175      String JavaDoc transaction = ANY_VALUE;
1176      switch (transType)
1177      {
1178      case BMT:
1179         transaction = BMT_VALUE;
1180         break;
1181      case CMT:
1182         transaction = CMT_VALUE;
1183         break;
1184      }
1185      return transaction;
1186   }
1187
1188   /**
1189    * Create all proxy factories for this ejb
1190    */

1191   private static void createProxyFactories(BeanMetaData conf, Container container)
1192      throws Exception JavaDoc
1193   {
1194      ClassLoader JavaDoc cl = container.getClassLoader();
1195      Iterator JavaDoc it = conf.getInvokerBindings();
1196      boolean foundOne=false;
1197      while (it.hasNext())
1198      {
1199         String JavaDoc invoker = (String JavaDoc) it.next();
1200         String JavaDoc jndiBinding = conf.getInvokerBinding(invoker);
1201         log.debug("creating binding for " + jndiBinding + ":" + invoker);
1202         InvokerProxyBindingMetaData imd = conf.getApplicationMetaData().getInvokerProxyBindingMetaDataByName(invoker);
1203         EJBProxyFactory ci = null;
1204
1205         // create a ProxyFactory instance
1206
try
1207         {
1208            ci = (EJBProxyFactory) cl.loadClass(imd.getProxyFactory()).newInstance();
1209            ci.setContainer(container);
1210            ci.setInvokerMetaData(imd);
1211            ci.setInvokerBinding(jndiBinding);
1212            if (ci instanceof XmlLoadable)
1213            {
1214               // the container invoker can load its configuration from the jboss.xml element
1215
((XmlLoadable) ci).importXml(imd.getProxyFactoryConfig());
1216            }
1217            container.addProxyFactory(invoker, ci);
1218            foundOne=true;
1219         }
1220         catch (Exception JavaDoc e)
1221         {
1222            log.warn("The Container Invoker "+invoker+" (in jboss.xml or standardjboss.xml) could not be created because of "+e+
1223               " We will ignore this error, but you may miss a transport for this bean.");
1224         }
1225      }
1226      if(!foundOne) {
1227         throw new DeploymentException("Missing or invalid Container Invokers (in jboss.xml or standardjboss.xml).");
1228      }
1229   }
1230
1231
1232   private static BeanLockManager createBeanLockManager(Container container, boolean reentrant, String JavaDoc beanLock,
1233                                                        ClassLoader JavaDoc cl)
1234      throws Exception JavaDoc
1235   {
1236      // The bean lock manager
1237
BeanLockManager lockManager = new BeanLockManager(container);
1238
1239      Class JavaDoc lockClass = null;
1240      try
1241      {
1242         lockClass = cl.loadClass(beanLock);
1243      }
1244      catch (Exception JavaDoc e)
1245      {
1246         throw new DeploymentException("Missing or invalid lock class (in jboss.xml or standardjboss.xml): " + beanLock + " - " + e);
1247      }
1248
1249      lockManager.setLockCLass(lockClass);
1250      lockManager.setReentrant(reentrant);
1251
1252      return lockManager;
1253   }
1254
1255   private static InstancePool createInstancePool(ConfigurationMetaData conf,
1256                                                  ClassLoader JavaDoc cl)
1257      throws Exception JavaDoc
1258   {
1259      // Set instance pool
1260
InstancePool ip = null;
1261
1262      try
1263      {
1264         ip = (InstancePool) cl.loadClass(conf.getInstancePool()).newInstance();
1265      }
1266      catch (Exception JavaDoc e)
1267      {
1268         throw new DeploymentException("Missing or invalid Instance Pool (in jboss.xml or standardjboss.xml)", e);
1269      }
1270
1271      if (ip instanceof XmlLoadable)
1272         ((XmlLoadable) ip).importXml(conf.getContainerPoolConf());
1273
1274      return ip;
1275   }
1276
1277   private static InstanceCache createInstanceCache(ConfigurationMetaData conf,
1278                                                    ClassLoader JavaDoc cl)
1279      throws Exception JavaDoc
1280   {
1281      // Set instance cache
1282
InstanceCache ic = null;
1283
1284      try
1285      {
1286         ic = (InstanceCache) cl.loadClass(conf.getInstanceCache()).newInstance();
1287      }
1288      catch (Exception JavaDoc e)
1289      {
1290         throw new DeploymentException("Missing or invalid Instance Cache (in jboss.xml or standardjboss.xml)", e);
1291      }
1292
1293      if (ic instanceof XmlLoadable)
1294         ((XmlLoadable) ic).importXml(conf.getContainerCacheConf());
1295
1296      return ic;
1297   }
1298}
1299/*
1300vim:ts=3:sw=3:et
1301*/

1302
Popular Tags