001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.geronimo.tomcat.deployment; 020 021 import java.io.File; 022 import java.io.FileNotFoundException; 023 import java.io.IOException; 024 import java.net.URL; 025 import java.security.Permission; 026 import java.security.PermissionCollection; 027 import java.security.Permissions; 028 import java.util.Collection; 029 import java.util.Enumeration; 030 import java.util.HashMap; 031 import java.util.Iterator; 032 import java.util.Map; 033 import java.util.Set; 034 import java.util.jar.JarFile; 035 036 import javax.servlet.Servlet; 037 038 import org.apache.commons.logging.Log; 039 import org.apache.commons.logging.LogFactory; 040 import org.apache.geronimo.common.DeploymentException; 041 import org.apache.geronimo.deployment.ModuleIDBuilder; 042 import org.apache.geronimo.deployment.NamespaceDrivenBuilder; 043 import org.apache.geronimo.deployment.service.EnvironmentBuilder; 044 import org.apache.geronimo.deployment.util.DeploymentUtil; 045 import org.apache.geronimo.deployment.xbeans.EnvironmentType; 046 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil; 047 import org.apache.geronimo.gbean.AbstractName; 048 import org.apache.geronimo.gbean.AbstractNameQuery; 049 import org.apache.geronimo.gbean.GBeanData; 050 import org.apache.geronimo.gbean.GBeanInfo; 051 import org.apache.geronimo.gbean.GBeanInfoBuilder; 052 import org.apache.geronimo.gbean.SingleElementCollection; 053 import org.apache.geronimo.gbean.ReferencePatterns; 054 import org.apache.geronimo.j2ee.deployment.EARContext; 055 import org.apache.geronimo.j2ee.deployment.Module; 056 import org.apache.geronimo.j2ee.deployment.ModuleBuilder; 057 import org.apache.geronimo.j2ee.deployment.NamingBuilder; 058 import org.apache.geronimo.j2ee.deployment.WebModule; 059 import org.apache.geronimo.j2ee.deployment.WebServiceBuilder; 060 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 061 import org.apache.geronimo.kernel.Kernel; 062 import org.apache.geronimo.kernel.Naming; 063 import org.apache.geronimo.kernel.config.Configuration; 064 import org.apache.geronimo.kernel.config.ConfigurationData; 065 import org.apache.geronimo.kernel.repository.Environment; 066 import org.apache.geronimo.naming.deployment.ENCConfigBuilder; 067 import org.apache.geronimo.naming.deployment.GBeanResourceEnvironmentBuilder; 068 import org.apache.geronimo.naming.deployment.ResourceEnvironmentSetter; 069 import org.apache.geronimo.security.deploy.DefaultPrincipal; 070 import org.apache.geronimo.security.deployment.SecurityConfiguration; 071 import org.apache.geronimo.security.jacc.ComponentPermissions; 072 import org.apache.geronimo.tomcat.ManagerGBean; 073 import org.apache.geronimo.tomcat.RealmGBean; 074 import org.apache.geronimo.tomcat.TomcatWebAppContext; 075 import org.apache.geronimo.tomcat.ValveGBean; 076 import org.apache.geronimo.tomcat.cluster.CatalinaClusterGBean; 077 import org.apache.geronimo.tomcat.util.SecurityHolder; 078 import org.apache.geronimo.web.deployment.AbstractWebModuleBuilder; 079 import org.apache.geronimo.web.deployment.GenericToSpecificPlanConverter; 080 import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppDocument; 081 import org.apache.geronimo.xbeans.geronimo.web.tomcat.TomcatWebAppType; 082 import org.apache.geronimo.xbeans.geronimo.web.tomcat.config.GerTomcatDocument; 083 import org.apache.geronimo.xbeans.j2ee.ServletType; 084 import org.apache.geronimo.xbeans.j2ee.WebAppDocument; 085 import org.apache.geronimo.xbeans.j2ee.WebAppType; 086 import org.apache.xmlbeans.XmlException; 087 import org.apache.xmlbeans.XmlObject; 088 089 090 /** 091 * @version $Rev:385659 $ $Date: 2006-11-02 15:30:55 -0800 (Thu, 02 Nov 2006) $ 092 */ 093 public class TomcatModuleBuilder extends AbstractWebModuleBuilder { 094 095 private static final Log log = LogFactory.getLog(TomcatModuleBuilder.class); 096 097 private final Environment defaultEnvironment; 098 private final AbstractNameQuery tomcatContainerName; 099 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 }