View Javadoc

1   /**
2    *
3    *  Licensed to the Apache Software Foundation (ASF) under one or more
4    *  contributor license agreements.  See the NOTICE file distributed with
5    *  this work for additional information regarding copyright ownership.
6    *  The ASF licenses this file to You under the Apache License, Version 2.0
7    *  (the "License"); you may not use this file except in compliance with
8    *  the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing, software
13   *  distributed under the License is distributed on an "AS IS" BASIS,
14   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *  See the License for the specific language governing permissions and
16   *  limitations under the License.
17   */
18  
19  package org.apache.geronimo.tomcat.deployment;
20  
21  import java.io.File;
22  import java.io.FileNotFoundException;
23  import java.io.IOException;
24  import java.net.URL;
25  import java.security.Permission;
26  import java.security.PermissionCollection;
27  import java.security.Permissions;
28  import java.util.Collection;
29  import java.util.Enumeration;
30  import java.util.HashMap;
31  import java.util.Iterator;
32  import java.util.Map;
33  import java.util.Set;
34  import java.util.jar.JarFile;
35  
36  import javax.servlet.Servlet;
37  
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.apache.geronimo.common.DeploymentException;
41  import org.apache.geronimo.deployment.ModuleIDBuilder;
42  import org.apache.geronimo.deployment.NamespaceDrivenBuilder;
43  import org.apache.geronimo.deployment.service.EnvironmentBuilder;
44  import org.apache.geronimo.deployment.util.DeploymentUtil;
45  import org.apache.geronimo.deployment.xbeans.EnvironmentType;
46  import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil;
47  import org.apache.geronimo.gbean.AbstractName;
48  import org.apache.geronimo.gbean.AbstractNameQuery;
49  import org.apache.geronimo.gbean.GBeanData;
50  import org.apache.geronimo.gbean.GBeanInfo;
51  import org.apache.geronimo.gbean.GBeanInfoBuilder;
52  import org.apache.geronimo.gbean.SingleElementCollection;
53  import org.apache.geronimo.gbean.ReferencePatterns;
54  import org.apache.geronimo.j2ee.deployment.EARContext;
55  import org.apache.geronimo.j2ee.deployment.Module;
56  import org.apache.geronimo.j2ee.deployment.ModuleBuilder;
57  import org.apache.geronimo.j2ee.deployment.NamingBuilder;
58  import org.apache.geronimo.j2ee.deployment.WebModule;
59  import org.apache.geronimo.j2ee.deployment.WebServiceBuilder;
60  import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory;
61  import org.apache.geronimo.kernel.Kernel;
62  import org.apache.geronimo.kernel.Naming;
63  import org.apache.geronimo.kernel.config.Configuration;
64  import org.apache.geronimo.kernel.config.ConfigurationData;
65  import org.apache.geronimo.kernel.repository.Environment;
66  import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
67  import org.apache.geronimo.naming.deployment.GBeanResourceEnvironmentBuilder;
68  import org.apache.geronimo.naming.deployment.ResourceEnvironmentSetter;
69  import org.apache.geronimo.security.deploy.DefaultPrincipal;
70  import org.apache.geronimo.security.deployment.SecurityConfiguration;
71  import org.apache.geronimo.security.jacc.ComponentPermissions;
72  import org.apache.geronimo.tomcat.ManagerGBean;
73  import org.apache.geronimo.tomcat.RealmGBean;
74  import org.apache.geronimo.tomcat.TomcatWebAppContext;
75  import org.apache.geronimo.tomcat.ValveGBean;
76  import org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean;
77  import org.apache.geronimo.tomcat.util.SecurityHolder;
78  import org.apache.geronimo.web.deployment.AbstractWebModuleBuilder;
79  import org.apache.geronimo.web.deployment.GenericToSpecificPlanConverter;
80  import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppDocument;
81  import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppType;
82  import org.apache.geronimo.xbeans.geronimo.web.tomcat.config.GerTomcatDocument;
83  import org.apache.geronimo.xbeans.j2ee.ServletType;
84  import org.apache.geronimo.xbeans.j2ee.WebAppDocument;
85  import org.apache.geronimo.xbeans.j2ee.WebAppType;
86  import org.apache.xmlbeans.XmlException;
87  import org.apache.xmlbeans.XmlObject;
88  
89  
90  /**
91   * @version $Rev:385659 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $
92   */
93  public class TomcatModuleBuilder extends AbstractWebModuleBuilder {
94  
95      private static final Log log = LogFactory.getLog(TomcatModuleBuilder.class);
96  
97      private final Environment defaultEnvironment;
98      private final AbstractNameQuery tomcatContainerName;
99  
100     private final SingleElementCollection webServiceBuilder;
101 
102     private static final String TOMCAT_NAMESPACE = TomcatWebAppDocument.type.getDocumentElementName().getNamespaceURI();
103 
104     public TomcatModuleBuilder(Environment defaultEnvironment,
105             AbstractNameQuery tomcatContainerName,
106             Collection webServiceBuilder,
107             Collection securityBuilders,
108             Collection serviceBuilders,
109             NamingBuilder namingBuilders,
110             ResourceEnvironmentSetter resourceEnvironmentSetter,
111             Kernel kernel) {
112         super(kernel, securityBuilders, serviceBuilders, namingBuilders, resourceEnvironmentSetter);
113         this.defaultEnvironment = defaultEnvironment;
114 
115         this.tomcatContainerName = tomcatContainerName;
116         this.webServiceBuilder = new SingleElementCollection(webServiceBuilder);
117     }
118 
119     private WebServiceBuilder getWebServiceBuilder() {
120         return (WebServiceBuilder) webServiceBuilder.getElement();
121     }
122 
123     protected Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, boolean standAlone, String contextRoot, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException {
124         assert moduleFile != null: "moduleFile is null";
125         assert targetPath != null: "targetPath is null";
126         assert !targetPath.endsWith("/"): "targetPath must not end with a '/'";
127 
128         // parse the spec dd
129         String specDD;
130         WebAppType webApp;
131         try {
132             if (specDDUrl == null) {
133                 specDDUrl = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/web.xml");
134             }
135 
136             // read in the entire specDD as a string, we need this for getDeploymentDescriptor
137             // on the J2ee management object
138             specDD = DeploymentUtil.readAll(specDDUrl);
139         } catch (Exception e) {
140             //no web.xml, not for us
141             return null;
142         }
143         //we found web.xml, if it won't parse that's an error.
144         try {
145             // parse it
146             XmlObject parsed = XmlBeansUtil.parse(specDD);
147             WebAppDocument webAppDoc = convertToServletSchema(parsed);
148             webApp = webAppDoc.getWebApp();
149         } catch (XmlException xmle) {
150             // Output the target path in the error to make it clearer to the user which webapp
151             // has the problem.  The targetPath is used, as moduleFile may have an unhelpful
152             // value such as C:\geronimo-1.1\var\temp\geronimo-deploymentUtil22826.tmpdir
153             throw new DeploymentException("Error parsing web.xml for " + targetPath, xmle);
154         }
155         check(webApp);
156 
157         // parse vendor dd
158         TomcatWebAppType tomcatWebApp = getTomcatWebApp(plan, moduleFile, standAlone, targetPath, webApp);
159 
160         if (contextRoot == null || contextRoot.trim().equals("")) {
161             if (tomcatWebApp.isSetContextRoot()) {
162                 contextRoot = tomcatWebApp.getContextRoot();
163             } else {
164                 contextRoot = determineDefaultContextRoot(webApp, standAlone, moduleFile, targetPath);
165             }
166         }
167 
168         contextRoot = contextRoot.trim();
169 
170         EnvironmentType environmentType = tomcatWebApp.getEnvironment();
171         Environment environment = EnvironmentBuilder.buildEnvironment(environmentType, defaultEnvironment);
172 
173         getNamingBuilders().buildEnvironment(webApp, tomcatWebApp, environment);
174 
175         // Note: logic elsewhere depends on the default artifact ID being the file name less extension (ConfigIDExtractor)
176         String warName = new File(moduleFile.getName()).getName();
177         if (warName.lastIndexOf('.') > -1) {
178             warName = warName.substring(0, warName.lastIndexOf('.'));
179         }
180         idBuilder.resolve(environment, warName, "war");
181 
182         Map servletNameToPathMap = buildServletNameToPathMap(webApp, contextRoot);
183 
184         Map portMap = getWebServiceBuilder().findWebServices(moduleFile, false, servletNameToPathMap, environment);
185         AbstractName moduleName;
186         if (earName == null) {
187             earName = naming.createRootName(environment.getConfigId(), NameFactory.NULL, NameFactory.J2EE_APPLICATION);
188             moduleName = naming.createChildName(earName, environment.getConfigId().toString(), NameFactory.WEB_MODULE);
189         } else {
190             moduleName = naming.createChildName(earName, targetPath, NameFactory.WEB_MODULE);
191         }
192 
193         return new WebModule(standAlone, moduleName, environment, moduleFile, targetPath, webApp, tomcatWebApp, specDD, contextRoot, portMap, TOMCAT_NAMESPACE);
194     }
195 
196 
197     TomcatWebAppType getTomcatWebApp(Object plan, JarFile moduleFile, boolean standAlone, String targetPath, WebAppType webApp) throws DeploymentException {
198         XmlObject rawPlan = null;
199         try {
200             // load the geronimo-web.xml from either the supplied plan or from the earFile
201             try {
202                 if (plan instanceof XmlObject) {
203                     rawPlan = (XmlObject) plan;
204                 } else {
205                     if (plan != null) {
206                         rawPlan = XmlBeansUtil.parse(((File) plan).toURL(), getClass().getClassLoader());
207                     } else {
208                         URL path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-web.xml");
209                         try {
210                             rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
211                         } catch (FileNotFoundException e) {
212                             path = DeploymentUtil.createJarURL(moduleFile, "WEB-INF/geronimo-tomcat.xml");
213                             try {
214                                 rawPlan = XmlBeansUtil.parse(path, getClass().getClassLoader());
215                             } catch (FileNotFoundException e1) {
216                                 log.warn("Web application " + targetPath + " does not contain a WEB-INF/geronimo-web.xml deployment plan.  This may or may not be a problem, depending on whether you have things like resource references that need to be resolved.  You can also give the deployer a separate deployment plan file on the command line.");
217                             }
218                         }
219                     }
220                 }
221             } catch (IOException e) {
222                 log.warn(e);
223             }
224 
225             TomcatWebAppType tomcatWebApp;
226             if (rawPlan != null) {
227                 XmlObject webPlan = new GenericToSpecificPlanConverter(GerTomcatDocument.type.getDocumentElementName().getNamespaceURI(),
228                         TomcatWebAppDocument.type.getDocumentElementName().getNamespaceURI(), "tomcat").convertToSpecificPlan(rawPlan);
229                 tomcatWebApp = (TomcatWebAppType) webPlan.changeType(TomcatWebAppType.type);
230                 XmlBeansUtil.validateDD(tomcatWebApp);
231             } else {
232                 String defaultContextRoot = determineDefaultContextRoot(webApp, standAlone, moduleFile, targetPath);
233                 tomcatWebApp = createDefaultPlan(defaultContextRoot);
234             }
235             return tomcatWebApp;
236         } catch (XmlException e) {
237             throw new DeploymentException("xml problem for web app " + targetPath, e);
238         }
239     }
240 
241     private TomcatWebAppType createDefaultPlan(String path) {
242         TomcatWebAppType tomcatWebApp = TomcatWebAppType.Factory.newInstance();
243         tomcatWebApp.setContextRoot("/" + path);
244         return tomcatWebApp;
245     }
246 
247 
248     public void initContext(EARContext earContext, Module module, ClassLoader cl) throws DeploymentException {
249         WebAppType webApp = (WebAppType) module.getSpecDD();
250 //        MessageDestinationType[] messageDestinations = webApp.getMessageDestinationArray();
251         TomcatWebAppType gerWebApp = (TomcatWebAppType) module.getVendorDD();
252 //        GerMessageDestinationType[] gerMessageDestinations = gerWebApp.getMessageDestinationArray();
253 
254 //        ENCConfigBuilder.registerMessageDestinations(earContext, module.getName(), messageDestinations, gerMessageDestinations);
255         getNamingBuilders().initContext(webApp, gerWebApp, module.getEarContext().getConfiguration(), earContext.getConfiguration(), module);
256         if ((webApp.getSecurityConstraintArray().length > 0 || webApp.getSecurityRoleArray().length > 0) &&
257                 !gerWebApp.isSetSecurityRealmName()) {
258             throw new DeploymentException("web.xml for web app " + module.getName() + " includes security elements but Geronimo deployment plan is not provided or does not contain <security-realm-name> element necessary to configure security accordingly.");
259         }
260         boolean hasSecurityRealmName = gerWebApp.isSetSecurityRealmName();
261         buildSubstitutionGroups(gerWebApp, hasSecurityRealmName, module, earContext);
262     }
263 
264     public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repository) throws DeploymentException {
265         EARContext moduleContext = module.getEarContext();
266         ClassLoader webClassLoader = moduleContext.getClassLoader();
267         AbstractName moduleName = moduleContext.getModuleName();
268         WebModule webModule = (WebModule) module;
269 
270         WebAppType webApp = (WebAppType) webModule.getSpecDD();
271         TomcatWebAppType tomcatWebApp = (TomcatWebAppType) webModule.getVendorDD();
272 
273         GBeanData webModuleData = new GBeanData(moduleName, TomcatWebAppContext.GBEAN_INFO);
274         try {
275             webModuleData.setReferencePattern("J2EEServer", moduleContext.getServerName());
276             if (!module.isStandAlone()) {
277                 webModuleData.setReferencePattern("J2EEApplication", earContext.getModuleName());
278             }
279 
280             webModuleData.setAttribute("deploymentDescriptor", module.getOriginalSpecDD());
281             Set securityRoles = collectRoleNames(webApp);
282             Map rolePermissions = new HashMap();
283 
284             webModuleData.setAttribute("contextPath", webModule.getContextRoot());
285 
286             //Add dependencies on managed connection factories and ejbs in this app
287             //This is overkill, but allows for people not using java:comp context (even though we don't support it)
288             //and sidesteps the problem of circular references between ejbs.
289             Set dependencies = findGBeanDependencies(earContext);
290             webModuleData.addDependencies(dependencies);
291 
292             //N.B. we use the ear context which has all the gbeans we could possibly be looking up from this ear.
293             Map buildingContext = new HashMap();
294             buildingContext.put(NamingBuilder.JNDI_KEY, new HashMap());
295             buildingContext.put(NamingBuilder.GBEAN_NAME_KEY, moduleName);
296             Configuration earConfiguration = earContext.getConfiguration();
297             getNamingBuilders().buildNaming(webApp, tomcatWebApp, earConfiguration, earConfiguration, webModule, buildingContext);
298             Map compContext = (Map) buildingContext.get(NamingBuilder.JNDI_KEY);
299 
300             webModuleData.setAttribute("componentContext", compContext);
301             // unsharableResources, applicationManagedSecurityResources
302             GBeanResourceEnvironmentBuilder rebuilder = new GBeanResourceEnvironmentBuilder(webModuleData);
303             //N.B. use earContext not moduleContext
304             resourceEnvironmentSetter.setResourceEnvironment(rebuilder, webApp.getResourceRefArray(), tomcatWebApp.getResourceRefArray());
305 
306             webModuleData.setReferencePattern("TransactionManager", earContext.getTransactionManagerName());
307             webModuleData.setReferencePattern("TrackedConnectionAssociator", earContext.getConnectionTrackerName());
308 
309             if (tomcatWebApp.isSetWebContainer()) {
310                 AbstractNameQuery webContainerName = ENCConfigBuilder.getGBeanQuery(NameFactory.GERONIMO_SERVICE, tomcatWebApp.getWebContainer());
311                 webModuleData.setReferencePattern("Container", webContainerName);
312             } else {
313                 webModuleData.setReferencePattern("Container", tomcatContainerName);
314             }
315             // Process the Tomcat container-config elements
316             if (tomcatWebApp.isSetHost()) {
317                 String virtualServer = tomcatWebApp.getHost().trim();
318                 webModuleData.setAttribute("virtualServer", virtualServer);
319             }
320             if (tomcatWebApp.isSetCrossContext()) {
321                 webModuleData.setAttribute("crossContext", Boolean.TRUE);
322             }
323             if (tomcatWebApp.isSetDisableCookies()) {
324                 webModuleData.setAttribute("disableCookies", Boolean.TRUE);
325             }
326             if (tomcatWebApp.isSetTomcatRealm()) {
327                 String tomcatRealm = tomcatWebApp.getTomcatRealm().trim();
328                 AbstractName realmName = earContext.getNaming().createChildName(moduleName, tomcatRealm, RealmGBean.GBEAN_INFO.getJ2eeType());
329                 webModuleData.setReferencePattern("TomcatRealm", realmName);
330             }
331             if (tomcatWebApp.isSetValveChain()) {
332                 String valveChain = tomcatWebApp.getValveChain().trim();
333                 AbstractName valveName = earContext.getNaming().createChildName(moduleName, valveChain, ValveGBean.J2EE_TYPE);
334                 webModuleData.setReferencePattern("TomcatValveChain", valveName);
335             }
336 
337             if (tomcatWebApp.isSetCluster()) {
338                 String cluster = tomcatWebApp.getCluster().trim();
339                 AbstractName clusterName = earContext.getNaming().createChildName(moduleName, cluster, CatalinaClusterGBean.J2EE_TYPE);
340                 webModuleData.setReferencePattern("Cluster", clusterName);
341             }
342 
343             if (tomcatWebApp.isSetManager()) {
344                 String manager = tomcatWebApp.getManager().trim();
345                 AbstractName managerName = earContext.getNaming().createChildName(moduleName, manager, ManagerGBean.J2EE_TYPE);
346                 webModuleData.setReferencePattern("Manager", managerName);
347             }
348             Map portMap = webModule.getPortMap();
349 
350             //Handle the role permissions and webservices on the servlets.
351             ServletType[] servletTypes = webApp.getServletArray();
352             Map webServices = new HashMap();
353             Class baseServletClass;
354             try {
355                 baseServletClass = webClassLoader.loadClass(Servlet.class.getName());
356             } catch (ClassNotFoundException e) {
357                 throw new DeploymentException("Could not load javax.servlet.Servlet in web classloader", e); // TODO identify web app in message
358             }
359             for (int i = 0; i < servletTypes.length; i++) {
360                 ServletType servletType = servletTypes[i];
361 
362                 //Handle the Role Ref Permissions
363                 processRoleRefPermissions(servletType, securityRoles, rolePermissions);
364 
365                 if (servletType.isSetServletClass()) {
366                     String servletName = servletType.getServletName().getStringValue().trim();
367                     String servletClassName = servletType.getServletClass().getStringValue().trim();
368                     Class servletClass;
369                     try {
370                         servletClass = webClassLoader.loadClass(servletClassName);
371                     } catch (ClassNotFoundException e) {
372                         throw new DeploymentException("Could not load servlet class " + servletClassName, e); // TODO identify web app in message
373                     }
374                     if (!baseServletClass.isAssignableFrom(servletClass)) {
375                         //fake servletData
376                         AbstractName servletAbstractName = moduleContext.getNaming().createChildName(moduleName, servletName, NameFactory.SERVLET);
377                         GBeanData servletData = new GBeanData();
378                         servletData.setAbstractName(servletAbstractName);
379                         //let the web service builder deal with configuring the gbean with the web service stack
380                         //Here we just extract the factory reference
381                         Object portInfo = portMap.get(servletName);
382                         getWebServiceBuilder().configurePOJO(servletData, module, portInfo, servletClassName, moduleContext);
383                         ReferencePatterns patterns = servletData.getReferencePatterns("WebServiceContainerFactory");
384                         AbstractName wsContainerFactoryName = patterns.getAbstractName();
385                         webServices.put(servletName, wsContainerFactoryName);
386                         //force all the factories to start before the web app that needs them.
387                         webModuleData.addDependency(wsContainerFactoryName);
388                     }
389                 }
390             }
391 
392             // JACC v1.0 secion B.19
393             addUnmappedJSPPermissions(securityRoles, rolePermissions);
394 
395             webModuleData.setAttribute("webServices", webServices);
396 
397             if (tomcatWebApp.isSetSecurityRealmName()) {
398                 if (earContext.getSecurityConfiguration() == null) {
399                     throw new DeploymentException("You have specified a <security-realm-name> for the webapp " + moduleName + " but no <security> configuration (role mapping) is supplied in the Geronimo plan for the web application (or the Geronimo plan for the EAR if the web app is in an EAR)");
400                 }
401 
402                 SecurityHolder securityHolder = new SecurityHolder();
403                 securityHolder.setSecurityRealm(tomcatWebApp.getSecurityRealmName().trim());
404 
405                 /**
406                  * TODO - go back to commented version when possible.
407                  */
408                 String policyContextID = moduleName.toString().replaceAll("[, :]", "_");
409                 securityHolder.setPolicyContextID(policyContextID);
410 
411                 ComponentPermissions componentPermissions = buildSpecSecurityConfig(webApp, securityRoles, rolePermissions);
412                 securityHolder.setExcluded(componentPermissions.getExcludedPermissions());
413                 PermissionCollection checkedPermissions = new Permissions();
414                 for (Iterator iterator = rolePermissions.values().iterator(); iterator.hasNext();) {
415                     PermissionCollection permissionsForRole = (PermissionCollection) iterator.next();
416                     for (Enumeration iterator2 = permissionsForRole.elements(); iterator2.hasMoreElements();) {
417                         Permission permission = (Permission) iterator2.nextElement();
418                         checkedPermissions.add(permission);
419                     }
420                 }
421                 securityHolder.setChecked(checkedPermissions);
422                 earContext.addSecurityContext(policyContextID, componentPermissions);
423                 DefaultPrincipal defaultPrincipal = ((SecurityConfiguration) earContext.getSecurityConfiguration()).getDefaultPrincipal();
424                 securityHolder.setDefaultPrincipal(defaultPrincipal);
425                 if (defaultPrincipal != null) {
426                     securityHolder.setSecurity(true);
427                 }
428 
429                 webModuleData.setAttribute("securityHolder", securityHolder);
430             }
431 
432             moduleContext.addGBean(webModuleData);
433 
434             if (!module.isStandAlone()) {
435                 ConfigurationData moduleConfigurationData = moduleContext.getConfigurationData();
436                 earContext.addChildConfiguration(module.getTargetPath(), moduleConfigurationData);
437             }
438         } catch (DeploymentException de) {
439             throw de;
440         } catch (Exception e) {
441             throw new DeploymentException("Unable to initialize GBean for web app " + module.getName(), e);
442         }
443     }
444 
445     public String getSchemaNamespace() {
446         return TOMCAT_NAMESPACE;
447     }
448 
449 
450     public static final GBeanInfo GBEAN_INFO;
451 
452     static {
453         GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(TomcatModuleBuilder.class, NameFactory.MODULE_BUILDER);
454         infoBuilder.addAttribute("defaultEnvironment", Environment.class, true, true);
455         infoBuilder.addAttribute("tomcatContainerName", AbstractNameQuery.class, true, true);
456         infoBuilder.addReference("WebServiceBuilder", WebServiceBuilder.class, NameFactory.MODULE_BUILDER);
457         infoBuilder.addReference("SecurityBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
458         infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER);
459         infoBuilder.addReference("NamingBuilders", NamingBuilder.class, NameFactory.MODULE_BUILDER);
460         infoBuilder.addReference("ResourceEnvironmentSetter", ResourceEnvironmentSetter.class, NameFactory.MODULE_BUILDER);
461         infoBuilder.addAttribute("kernel", Kernel.class, false);
462         infoBuilder.addInterface(ModuleBuilder.class);
463 
464         infoBuilder.setConstructor(new String[]{
465                 "defaultEnvironment",
466                 "tomcatContainerName",
467                 "WebServiceBuilder",
468                 "SecurityBuilders",
469                 "ServiceBuilders",
470                 "NamingBuilders",
471                 "ResourceEnvironmentSetter",
472                 "kernel"});
473         GBEAN_INFO = infoBuilder.getBeanInfo();
474     }
475 
476     public static GBeanInfo getGBeanInfo() {
477         return GBEAN_INFO;
478     }
479 
480 }