001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.geronimo.openejb.deployment; 018 019 import java.io.File; 020 import java.io.IOException; 021 import java.net.URI; 022 import java.net.URL; 023 import java.util.Collection; 024 import java.util.Collections; 025 import java.util.HashMap; 026 import java.util.Iterator; 027 import java.util.LinkedHashSet; 028 import java.util.LinkedList; 029 import java.util.Map; 030 import java.util.Properties; 031 import java.util.Set; 032 import java.util.TreeMap; 033 import java.util.TreeSet; 034 import java.util.jar.JarFile; 035 036 import javax.ejb.EntityContext; 037 import javax.ejb.MessageDrivenContext; 038 import javax.ejb.SessionContext; 039 import javax.ejb.TimerService; 040 import javax.xml.namespace.QName; 041 import javax.xml.ws.WebServiceContext; 042 043 import org.apache.commons.logging.Log; 044 import org.apache.commons.logging.LogFactory; 045 import org.apache.geronimo.common.DeploymentException; 046 import org.apache.geronimo.connector.ResourceAdapterWrapperGBean; 047 import org.apache.geronimo.deployment.ClassPathList; 048 import org.apache.geronimo.deployment.ModuleIDBuilder; 049 import org.apache.geronimo.deployment.ModuleList; 050 import org.apache.geronimo.deployment.NamespaceDrivenBuilder; 051 import org.apache.geronimo.deployment.NamespaceDrivenBuilderCollection; 052 import org.apache.geronimo.deployment.service.EnvironmentBuilder; 053 import org.apache.geronimo.deployment.service.GBeanBuilder; 054 import org.apache.geronimo.deployment.util.DeploymentUtil; 055 import org.apache.geronimo.deployment.xmlbeans.XmlBeansUtil; 056 import org.apache.geronimo.gbean.AbstractName; 057 import org.apache.geronimo.gbean.AbstractNameQuery; 058 import org.apache.geronimo.gbean.GBeanData; 059 import org.apache.geronimo.gbean.GBeanInfo; 060 import org.apache.geronimo.gbean.GBeanInfoBuilder; 061 import org.apache.geronimo.gbean.ReferencePatterns; 062 import org.apache.geronimo.gbean.GBeanLifecycle; 063 import org.apache.geronimo.j2ee.deployment.EARContext; 064 import org.apache.geronimo.j2ee.deployment.Module; 065 import org.apache.geronimo.j2ee.deployment.ModuleBuilder; 066 import org.apache.geronimo.j2ee.deployment.ModuleBuilderExtension; 067 import org.apache.geronimo.j2ee.deployment.NamingBuilder; 068 import org.apache.geronimo.j2ee.deployment.annotation.AnnotatedEjbJar; 069 import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; 070 import org.apache.geronimo.kernel.GBeanNotFoundException; 071 import org.apache.geronimo.kernel.Naming; 072 import org.apache.geronimo.kernel.classloader.TemporaryClassLoader; 073 import org.apache.geronimo.kernel.config.Configuration; 074 import org.apache.geronimo.kernel.config.ConfigurationModuleType; 075 import org.apache.geronimo.kernel.config.ConfigurationStore; 076 import org.apache.geronimo.kernel.repository.Artifact; 077 import org.apache.geronimo.kernel.repository.Environment; 078 import org.apache.geronimo.naming.deployment.ResourceEnvironmentSetter; 079 import org.apache.geronimo.openejb.EjbContainer; 080 import org.apache.geronimo.openejb.EjbDeployment; 081 import org.apache.geronimo.openejb.EjbModuleImplGBean; 082 import org.apache.geronimo.openejb.OpenEjbSystem; 083 import org.apache.geronimo.openejb.xbeans.ejbjar.OpenejbGeronimoEjbJarType; 084 import org.apache.geronimo.security.jacc.ComponentPermissions; 085 import org.apache.geronimo.xbeans.geronimo.j2ee.GerSecurityDocument; 086 import org.apache.geronimo.xbeans.javaee.EjbJarType; 087 import org.apache.geronimo.persistence.PersistenceUnitGBean; 088 import org.apache.openejb.OpenEJBException; 089 import org.apache.openejb.util.LinkResolver; 090 import org.apache.openejb.assembler.classic.AppInfo; 091 import org.apache.openejb.assembler.classic.CmpJarBuilder; 092 import org.apache.openejb.assembler.classic.ContainerInfo; 093 import org.apache.openejb.assembler.classic.ContainerSystemInfo; 094 import org.apache.openejb.assembler.classic.EjbJarInfo; 095 import org.apache.openejb.assembler.classic.EnterpriseBeanInfo; 096 import org.apache.openejb.assembler.classic.FacilitiesInfo; 097 import org.apache.openejb.assembler.classic.MdbContainerInfo; 098 import org.apache.openejb.assembler.classic.MessageDrivenBeanInfo; 099 import org.apache.openejb.assembler.classic.OpenEjbConfiguration; 100 import org.apache.openejb.assembler.classic.StatefulBeanInfo; 101 import org.apache.openejb.assembler.classic.PersistenceContextReferenceInfo; 102 import org.apache.openejb.util.UniqueDefaultLinkResolver; 103 import org.apache.openejb.config.AppModule; 104 import org.apache.openejb.config.ConfigurationFactory; 105 import org.apache.openejb.config.DeploymentLoader; 106 import org.apache.openejb.config.ReadDescriptors; 107 import org.apache.openejb.config.UnknownModuleTypeException; 108 import org.apache.openejb.config.UnsupportedModuleTypeException; 109 import org.apache.openejb.config.ValidationError; 110 import org.apache.openejb.config.ValidationFailedException; 111 import org.apache.openejb.config.ValidationFailure; 112 import org.apache.openejb.jee.EjbJar; 113 import org.apache.openejb.jee.EjbRef; 114 import org.apache.openejb.jee.EnterpriseBean; 115 import org.apache.openejb.jee.MessageDestinationRef; 116 import org.apache.openejb.jee.PersistenceContextRef; 117 import org.apache.openejb.jee.PersistenceUnitRef; 118 import org.apache.openejb.jee.ResourceEnvRef; 119 import org.apache.openejb.jee.ResourceRef; 120 import org.apache.openejb.jee.ServiceRef; 121 import org.apache.openejb.jee.jpa.unit.Persistence; 122 import org.apache.openejb.jee.jpa.unit.PersistenceUnit; 123 import org.apache.openejb.jee.jpa.unit.TransactionType; 124 import org.apache.openejb.jee.oejb2.EjbRefType; 125 import org.apache.openejb.jee.oejb2.GeronimoEjbJarType; 126 import org.apache.openejb.jee.oejb2.MessageDrivenBeanType; 127 import org.apache.openejb.jee.oejb2.OpenejbJarType; 128 import org.apache.openejb.jee.oejb2.PatternType; 129 import org.apache.openejb.jee.oejb2.ResourceLocatorType; 130 import org.apache.openejb.loader.SystemInstance; 131 import org.apache.xmlbeans.XmlCursor; 132 import org.apache.xmlbeans.XmlObject; 133 134 /** 135 * Master builder for processing EJB JAR deployments and creating the 136 * correspinding runtime objects (GBeans, etc.). 137 * 138 * @version $Revision: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $ 139 */ 140 public class EjbModuleBuilder implements ModuleBuilder, GBeanLifecycle { 141 private static final Log log = LogFactory.getLog(EjbModuleBuilder.class); 142 143 private static final String OPENEJBJAR_NAMESPACE = XmlUtil.OPENEJBJAR_QNAME.getNamespaceURI(); 144 private static final Map<String, String> NAMESPACE_UPDATES = new HashMap<String, String>(); 145 static { 146 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar", "http://openejb.apache.org/xml/ns/openejb-jar-2.3"); 147 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar-2.1", "http://openejb.apache.org/xml/ns/openejb-jar-2.3"); 148 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar-2.2", "http://openejb.apache.org/xml/ns/openejb-jar-2.3"); 149 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/openejb-jar-2.3", "http://openejb.apache.org/xml/ns/openejb-jar-2.3"); 150 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/pkgen", "http://openejb.apache.org/xml/ns/pkgen-2.1"); 151 NAMESPACE_UPDATES.put("http://www.openejb.org/xml/ns/pkgen-2.0", "http://openejb.apache.org/xml/ns/pkgen-2.1"); 152 } 153 154 private final Environment defaultEnvironment; 155 private final String defaultCmpJTADataSource; 156 private final String defaultCmpNonJTADataSource; 157 private final NamespaceDrivenBuilderCollection securityBuilders; 158 private final NamespaceDrivenBuilderCollection serviceBuilders; 159 private final NamingBuilder namingBuilder; 160 private final ResourceEnvironmentSetter resourceEnvironmentSetter; 161 private final Collection<ModuleBuilderExtension> moduleBuilderExtensions; 162 163 public EjbModuleBuilder(Environment defaultEnvironment, 164 165 String defaultCmpJTADataSource, String defaultCmpNonJTADataSource, 166 Collection<ModuleBuilderExtension> moduleBuilderExtensions, 167 Collection securityBuilders, 168 Collection serviceBuilders, 169 NamingBuilder namingBuilders, 170 ResourceEnvironmentSetter resourceEnvironmentSetter) { 171 172 this.defaultEnvironment = defaultEnvironment; 173 this.defaultCmpJTADataSource = defaultCmpJTADataSource; 174 this.defaultCmpNonJTADataSource = defaultCmpNonJTADataSource; 175 this.securityBuilders = new NamespaceDrivenBuilderCollection(securityBuilders, GerSecurityDocument.type.getDocumentElementName()); 176 this.serviceBuilders = new NamespaceDrivenBuilderCollection(serviceBuilders, GBeanBuilder.SERVICE_QNAME); 177 this.namingBuilder = namingBuilders; 178 this.resourceEnvironmentSetter = resourceEnvironmentSetter; 179 180 if (moduleBuilderExtensions == null) { 181 moduleBuilderExtensions = Collections.emptyList(); 182 } 183 this.moduleBuilderExtensions = moduleBuilderExtensions; 184 185 //duplicate of stuff in OpenEjbSystemGBean, may not be essential 186 System.setProperty("duct tape", ""); 187 System.setProperty("admin.disabled", "true"); 188 System.setProperty("openejb.logger.external", "true"); 189 190 setDefaultProperty("openejb.deploymentId.format", "{moduleId}/{ejbName}"); 191 setDefaultProperty("openejb.jndiname.strategy.class", "org.apache.openejb.assembler.classic.JndiBuilder$TemplatedStrategy"); 192 setDefaultProperty("openejb.jndiname.format", "{ejbName}{interfaceType.annotationName}"); 193 setDefaultProperty("openejb.jndiname.failoncollision", "false"); 194 195 System.setProperty("openejb.naming", "xbean"); 196 197 } 198 199 public void doStart() throws Exception { 200 XmlBeansUtil.registerNamespaceUpdates(NAMESPACE_UPDATES); 201 } 202 203 public void doStop() { 204 XmlBeansUtil.unregisterNamespaceUpdates(NAMESPACE_UPDATES); 205 } 206 207 public void doFail() { 208 doStop(); 209 } 210 211 private void setDefaultProperty(String key, String value) { 212 SystemInstance systemInstance = SystemInstance.get(); 213 String format = systemInstance.getProperty(key); 214 if (format == null) { 215 systemInstance.setProperty(key, value); 216 } 217 } 218 219 220 public String getSchemaNamespace() { 221 return EjbModuleBuilder.OPENEJBJAR_NAMESPACE; 222 } 223 224 public Module createModule(File plan, JarFile moduleFile, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException { 225 return createModule(plan, moduleFile, "ejb.jar", null, null, null, naming, idBuilder); 226 } 227 228 public Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment environment, Object moduleContextInfo, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException { 229 return createModule(plan, moduleFile, targetPath, specDDUrl, environment, earName, naming, idBuilder); 230 } 231 232 private Module createModule(Object plan, JarFile moduleFile, String targetPath, URL specDDUrl, Environment earEnvironment, AbstractName earName, Naming naming, ModuleIDBuilder idBuilder) throws DeploymentException { 233 if (moduleFile == null) throw new NullPointerException("moduleFile is null"); 234 if (targetPath == null) throw new NullPointerException("targetPath is null"); 235 if (targetPath.endsWith("/")) throw new IllegalArgumentException("targetPath must not end with a '/'"); 236 237 // Load the module file 238 DeploymentLoader loader = new DeploymentLoader(); 239 AppModule appModule; 240 try { 241 appModule = loader.load(new File(moduleFile.getName())); 242 } catch (UnknownModuleTypeException e) { 243 return null; 244 } catch (UnsupportedModuleTypeException e) { 245 return null; 246 } catch (OpenEJBException e) { 247 Throwable t = e.getCause(); 248 if (t instanceof UnknownModuleTypeException || t instanceof UnsupportedModuleTypeException) { 249 return null; 250 } 251 throw new DeploymentException(e); 252 } 253 254 // did we find a ejb jar? 255 if (appModule.getEjbModules().size() == 0) { 256 return null; 257 } 258 259 // get the module 260 org.apache.openejb.config.EjbModule ejbModule = appModule.getEjbModules().get(0); 261 262 // add the ejb-jar.xml altDD plan 263 if (specDDUrl != null) { 264 ejbModule.setEjbJar(null); 265 ejbModule.getAltDDs().put("ejb-jar.xml", specDDUrl); 266 } 267 268 // convert the vendor plan object to the ejbModule altDD map 269 XmlObject unknownXmlObject = null; 270 if (plan instanceof XmlObject) { 271 unknownXmlObject = (XmlObject) plan; 272 } else if (plan != null) { 273 try { 274 unknownXmlObject = XmlBeansUtil.parse(((File) plan).toURL(), XmlUtil.class.getClassLoader()); 275 } catch (Exception e) { 276 throw new DeploymentException(e); 277 } 278 } 279 280 if (unknownXmlObject != null) { 281 XmlCursor xmlCursor = unknownXmlObject.newCursor(); 282 // 283 QName qname = xmlCursor.getName(); 284 if (qname == null) { 285 xmlCursor.toFirstChild(); 286 qname = xmlCursor.getName(); 287 } 288 if (qname.getLocalPart().equals("openejb-jar")) { 289 ejbModule.getAltDDs().put("openejb-jar.xml", xmlCursor.xmlText()); 290 } else if (qname.getLocalPart().equals("ejb-jar") && qname.getNamespaceURI().equals("http://geronimo.apache.org/xml/ns/j2ee/ejb/openejb-2.0")) { 291 ejbModule.getAltDDs().put("geronimo-openejb.xml", xmlCursor.xmlText()); 292 } 293 } 294 295 // Read in the deploument desiptor files 296 ReadDescriptors readDescriptors = new ReadDescriptors(); 297 try { 298 readDescriptors.deploy(appModule); 299 } catch (OpenEJBException e) { 300 throw new DeploymentException("Failed parsing descriptors for module: " + moduleFile.getName(), e); 301 } 302 303 // Get the geronimo-openejb.xml tree 304 boolean standAlone = earEnvironment == null; 305 GeronimoEjbJarType geronimoEjbJarType = (GeronimoEjbJarType) ejbModule.getAltDDs().get("geronimo-openejb.xml"); 306 if (geronimoEjbJarType == null) { 307 // create default plan 308 String path = (standAlone) ? new File(moduleFile.getName()).getName() : targetPath; 309 geronimoEjbJarType = XmlUtil.createDefaultPlan(path, ejbModule.getEjbJar()); 310 ejbModule.getAltDDs().put("geronimo-openejb.xml", geronimoEjbJarType); 311 } 312 313 // create the geronimo environment object 314 Environment environment = XmlUtil.buildEnvironment(geronimoEjbJarType.getEnvironment(), defaultEnvironment); 315 if (earEnvironment != null) { 316 EnvironmentBuilder.mergeEnvironments(earEnvironment, environment); 317 environment = earEnvironment; 318 if (!environment.getConfigId().isResolved()) { 319 throw new IllegalStateException("EJB module ID should be fully resolved (not " + environment.getConfigId() + ")"); 320 } 321 } else { 322 idBuilder.resolve(environment, new File(moduleFile.getName()).getName(), "jar"); 323 } 324 325 326 AbstractName moduleName; 327 if (earName == null) { 328 earName = naming.createRootName(environment.getConfigId(), NameFactory.NULL, NameFactory.J2EE_APPLICATION); 329 moduleName = naming.createChildName(earName, environment.getConfigId().toString(), NameFactory.EJB_MODULE); 330 ejbModule.setModuleId(environment.getConfigId().getArtifactId()); 331 } else { 332 moduleName = naming.createChildName(earName, targetPath, NameFactory.EJB_MODULE); 333 ejbModule.setModuleId(targetPath); 334 } 335 336 // Create XMLBeans version of EjbJarType for the AnnotatedApp interface 337 EjbJar ejbJar = ejbModule.getEjbJar(); 338 EjbJarType ejbJarType = XmlUtil.convertToXmlbeans(ejbJar); 339 AnnotatedEjbJar annotatedEjbJar = new AnnotatedEjbJar(ejbJarType); 340 341 EjbModule module = new EjbModule(ejbModule, standAlone, moduleName, environment, moduleFile, targetPath, "", annotatedEjbJar); 342 343 for (ModuleBuilderExtension builder : moduleBuilderExtensions) { 344 try { 345 builder.createModule(module, plan, moduleFile, targetPath, specDDUrl, environment, null, earName, naming, idBuilder); 346 } catch (Throwable t) { 347 String builderName = builder.getClass().getSimpleName(); 348 log.error(builderName + ".createModule() failed: " + t.getMessage(), t); 349 350 } 351 } 352 return module; 353 } 354 355 protected static void unmapReferences(EjbJar ejbJar, GeronimoEjbJarType geronimoEjbJarType) { 356 Set<String> corbaEjbRefs = new TreeSet<String>(); 357 for (EjbRefType ejbRef : geronimoEjbJarType.getEjbRef()) { 358 if (ejbRef.getNsCorbaloc() != null) { 359 corbaEjbRefs.add(ejbRef.getRefName()); 360 } 361 } 362 363 for (EnterpriseBean enterpriseBean : ejbJar.getEnterpriseBeans()) { 364 enterpriseBean.getEnvEntry().clear(); 365 enterpriseBean.getEjbLocalRef().clear(); 366 367 for (Iterator<EjbRef> iterator = enterpriseBean.getEjbRef().iterator(); iterator.hasNext();) { 368 EjbRef ref = iterator.next(); 369 if (!corbaEjbRefs.contains(ref.getEjbRefName())) { 370 // remove all non corba refs to avoid overwriting normal ejb refs 371 iterator.remove(); 372 } else { 373 // clear mapped named data from corba refs 374 ref.setMappedName(null); 375 ref.getInjectionTarget().clear(); 376 } 377 } 378 379 for (MessageDestinationRef ref : enterpriseBean.getMessageDestinationRef()) { 380 ref.setMappedName(null); 381 ref.getInjectionTarget().clear(); 382 } 383 for (PersistenceContextRef ref : enterpriseBean.getPersistenceContextRef()) { 384 ref.setMappedName(null); 385 ref.getInjectionTarget().clear(); 386 } 387 for (PersistenceUnitRef ref : enterpriseBean.getPersistenceUnitRef()) { 388 ref.setMappedName(null); 389 ref.getInjectionTarget().clear(); 390 } 391 for (ResourceRef ref : enterpriseBean.getResourceRef()) { 392 ref.setMappedName(null); 393 ref.getInjectionTarget().clear(); 394 } 395 for (Iterator<ResourceEnvRef> iterator = enterpriseBean.getResourceEnvRef().iterator(); iterator.hasNext();) { 396 ResourceEnvRef ref = iterator.next(); 397 if (ref.getType().equals(SessionContext.class.getName())) { 398 iterator.remove(); 399 } else if (ref.getType().equals(EntityContext.class.getName())) { 400 iterator.remove(); 401 } else if (ref.getType().equals(MessageDrivenContext.class.getName())) { 402 iterator.remove(); 403 } else if (ref.getType().equals(TimerService.class.getName())) { 404 iterator.remove(); 405 } else if (ref.getType().equals(WebServiceContext.class.getName())) { 406 iterator.remove(); 407 } else { 408 ref.setMappedName(null); 409 } 410 ref.getInjectionTarget().clear(); 411 412 } 413 for (ServiceRef ref : enterpriseBean.getServiceRef()) { 414 ref.setMappedName(null); 415 ref.getInjectionTarget().clear(); 416 } 417 } 418 } 419 420 421 public void installModule(JarFile earFile, EARContext earContext, Module module, Collection configurationStores, ConfigurationStore targetConfigurationStore, Collection repository) throws DeploymentException { 422 installModule(module, earContext); 423 EARContext moduleContext; 424 if (module.isStandAlone()) { 425 moduleContext = earContext; 426 } else { 427 Environment environment = earContext.getConfiguration().getEnvironment(); 428 File configurationDir = new File(earContext.getBaseDir(), module.getTargetPath()); 429 // configurationDir.mkdirs(); 430 431 // construct the ejb app deployment context... this is the same class used by the ear context 432 try { 433 File inPlaceConfigurationDir = null; 434 if (null != earContext.getInPlaceConfigurationDir()) { 435 inPlaceConfigurationDir = new File(earContext.getInPlaceConfigurationDir(), module.getTargetPath()); 436 } 437 moduleContext = new EARContext(configurationDir, 438 inPlaceConfigurationDir, 439 environment, 440 ConfigurationModuleType.EJB, 441 module.getModuleName(), 442 earContext); 443 } catch (DeploymentException e) { 444 cleanupConfigurationDir(configurationDir); 445 throw e; 446 } 447 } 448 module.setEarContext(moduleContext); 449 module.setRootEarContext(earContext); 450 if (((EjbModule) module).getEjbJar().getAssemblyDescriptor() != null) { 451 namingBuilder.buildEnvironment(null, null, module.getEnvironment()); 452 } 453 for (ModuleBuilderExtension builder : moduleBuilderExtensions) { 454 try { 455 builder.installModule(earFile, earContext, module, configurationStores, targetConfigurationStore, repository); 456 } catch (Throwable t) { 457 String builderName = builder.getClass().getSimpleName(); 458 log.error(builderName + ".installModule() failed: " + t.getMessage(), t); 459 } 460 } 461 } 462 463 private void installModule(Module module, EARContext earContext) throws DeploymentException { 464 EarData earData = (EarData) earContext.getGeneralData().get(EarData.class); 465 if (earData == null) { 466 earData = new EarData(); 467 earContext.getGeneralData().put(EarData.class, earData); 468 } 469 earData.addEjbModule((EjbModule) module); 470 471 JarFile moduleFile = module.getModuleFile(); 472 try { 473 // extract the ejbJar file into a standalone packed jar file and add the contents to the output 474 earContext.addIncludeAsPackedJar(URI.create(module.getTargetPath()), moduleFile); 475 } catch (IOException e) { 476 throw new DeploymentException("Unable to copy ejb module jar into configuration: " + moduleFile.getName(), e); 477 } 478 } 479 480 private static final String LINE_SEP = System.getProperty("line.separator"); 481 482 private boolean cleanupConfigurationDir(File configurationDir) { 483 LinkedList<String> cannotBeDeletedList = new LinkedList<String>(); 484 485 if (!DeploymentUtil.recursiveDelete(configurationDir, cannotBeDeletedList)) { 486 // Output a message to help user track down file problem 487 log.warn("Unable to delete " + cannotBeDeletedList.size() + 488 " files while recursively deleting directory " 489 + configurationDir.getAbsolutePath() + LINE_SEP + 490 "The first file that could not be deleted was:" + LINE_SEP + " " + 491 (!cannotBeDeletedList.isEmpty() ? cannotBeDeletedList.getFirst() : "")); 492 return false; 493 } 494 return true; 495 } 496 497 public void initContext(EARContext earContext, Module module, ClassLoader classLoader) throws DeploymentException { 498 EjbModule ejbModule = (EjbModule) module; 499 500 EjbJarInfo ejbJarInfo = getEjbJarInfo(earContext, ejbModule, classLoader); 501 502 ejbModule.setEjbJarInfo(ejbJarInfo); 503 504 // update the original spec dd with the metadata complete dd 505 EjbJar ejbJar = ejbModule.getEjbJar(); 506 ejbModule.setOriginalSpecDD(XmlUtil.marshal(ejbModule.getEjbJar())); 507 508 // Get the geronimo-openejb plan 509 GeronimoEjbJarType geronimoEjbJarType = (GeronimoEjbJarType) ejbModule.getEjbModule().getAltDDs().get("geronimo-openejb.xml"); 510 511 // We must set all mapped name references back to null or Geronimo will blow up 512 unmapReferences(ejbJar, geronimoEjbJarType); 513 514 // create a xmlbeans version of the ejb-jar.xml file, because the jndi code is coupled based on xmlbeans objects 515 EjbJarType ejbJarType = XmlUtil.convertToXmlbeans(ejbJar); 516 ejbModule.setSpecDD(ejbJarType); 517 518 // convert the plan to xmlbeans since geronimo naming is coupled on xmlbeans objects 519 OpenejbGeronimoEjbJarType geronimoOpenejb = XmlUtil.convertToXmlbeans(geronimoEjbJarType); 520 ejbModule.setVendorDD(geronimoOpenejb); 521 522 // todo move namingBuilders.buildEnvironment() here when geronimo naming supports it 523 524 // initialize the naming builders 525 if (ejbJarType.getAssemblyDescriptor() != null) { 526 namingBuilder.initContext(ejbJarType.getAssemblyDescriptor(), 527 geronimoOpenejb, 528 ejbModule); 529 } 530 531 EjbDeploymentBuilder ejbDeploymentBuilder = new EjbDeploymentBuilder(earContext, ejbModule, namingBuilder, resourceEnvironmentSetter); 532 ejbModule.setEjbBuilder(ejbDeploymentBuilder); 533 ejbDeploymentBuilder.initContext(); 534 535 // Build the security configuration. 536 securityBuilders.build(geronimoOpenejb, earContext, ejbModule.isStandAlone() ? ejbModule.getEarContext() : null); 537 538 // Add extra gbean declared in the geronimo-openejb.xml file 539 serviceBuilders.build(geronimoOpenejb, earContext, ejbModule.getEarContext()); 540 541 ClassPathList manifestcp = new ClassPathList(); 542 manifestcp.add(module.getTargetPath()); 543 EARContext moduleContext = module.getEarContext(); 544 ModuleList moduleLocations = (ModuleList) module.getRootEarContext().getGeneralData().get(ModuleList.class); 545 URI baseUri = URI.create(module.getTargetPath()); 546 moduleContext.getCompleteManifestClassPath(module.getModuleFile(), baseUri, URI.create("."), manifestcp, moduleLocations); 547 moduleContext.getGeneralData().put(ClassPathList.class, manifestcp); 548 549 for (ModuleBuilderExtension builder : moduleBuilderExtensions) { 550 try { 551 builder.initContext(earContext, module, classLoader); 552 } catch (Throwable t) { 553 String builderName = builder.getClass().getSimpleName(); 554 log.error(builderName + ".initContext() failed: " + t.getMessage(), t); 555 } 556 } 557 } 558 559 private EjbJarInfo getEjbJarInfo(EARContext earContext, EjbModule ejbModule, ClassLoader classLoader) throws DeploymentException { 560 EarData earData = (EarData) earContext.getGeneralData().get(EarData.class); 561 if (earData.getEjbJars().isEmpty()) { 562 563 // temporary classloader is used for processing ejb annotations and byte code manipulation during ejb load 564 TemporaryClassLoader temporaryClassLoader = new TemporaryClassLoader(new URL[0], classLoader); 565 566 // create an openejb app module for the ear containing all ejb modules 567 AppModule appModule = new AppModule(classLoader, earContext.getConfigID().toString()); 568 for (EjbModule module : earData.getEjbModuels()) { 569 module.setClassLoader(temporaryClassLoader); 570 appModule.getEjbModules().add(module.getEjbModule()); 571 } 572 573 // build the config info tree 574 // this method fills in the ejbJar jaxb tree based on the annotations 575 // (metadata complete) and it run the openejb verifier 576 AppInfo appInfo; 577 try { 578 appInfo = configureApplication(appModule, earContext.getConfiguration()); 579 } catch (ValidationFailedException set) { 580 StringBuilder sb = new StringBuilder(); 581 sb.append("Jar failed validation: ").append(appModule.getModuleId()); 582 583 for (ValidationError e : set.getErrors()) { 584 sb.append(e.getPrefix()).append(" ... ").append(e.getComponentName()).append(":\t").append(e.getMessage(2)); 585 } 586 587 for (ValidationFailure e : set.getFailures()) { 588 sb.append(e.getPrefix()).append(" ... ").append(e.getComponentName()).append(":\t").append(e.getMessage(2)); 589 } 590 591 throw new DeploymentException(sb.toString()); 592 } catch (OpenEJBException e) { 593 throw new DeploymentException(e); 594 } 595 596 // add all of the modules to the ear data 597 for (EjbJarInfo ejbJar : appInfo.ejbJars) { 598 earData.addEjbJar(ejbJar); 599 } 600 601 // add the cmp jar 602 CmpJarBuilder cmp2Builder = new CmpJarBuilder(appInfo, classLoader); 603 try { 604 File generatedJar = cmp2Builder.getJarFile(); 605 if (generatedJar != null) { 606 String generatedPath = ejbModule.getTargetPath(); 607 if (generatedPath.endsWith(".jar")) { 608 generatedPath = generatedPath.substring(0, generatedPath.length() - 4); 609 } 610 generatedPath += "-cmp2.jar"; 611 earContext.addInclude(URI.create(generatedPath), generatedJar); 612 } 613 } catch (IOException e) { 614 throw new DeploymentException(e); 615 } 616 617 // add the cmp persistence unit if needed 618 if (appInfo.cmpMappingsXml != null) { 619 addGeronimmoOpenEJBPersistenceUnit(ejbModule); 620 } 621 } 622 623 // find our module 624 EjbJarInfo ejbJarInfo = earData.getEjbJar(ejbModule.getEjbModule().getModuleId()); 625 return ejbJarInfo; 626 } 627 628 private AppInfo configureApplication(AppModule appModule, Configuration configuration) throws OpenEJBException { 629 OpenEjbConfiguration openEjbConfiguration = new OpenEjbConfiguration(); 630 openEjbConfiguration.containerSystem = new ContainerSystemInfo(); 631 openEjbConfiguration.facilities = new FacilitiesInfo(); 632 boolean offline = true; 633 ConfigurationFactory configurationFactory = new ConfigurationFactory(offline, openEjbConfiguration); 634 ClassLoader oldClassLoader = Thread.currentThread().getContextClassLoader(); 635 Thread.currentThread().setContextClassLoader(appModule.getClassLoader()); 636 try { 637 addContainerInfos(configuration, openEjbConfiguration.containerSystem, configurationFactory); 638 addResourceAdapterMDBInfos(configuration, openEjbConfiguration.containerSystem, configurationFactory); 639 //process resource adapters 640 641 return configurationFactory.configureApplication(appModule); 642 } finally { 643 Thread.currentThread().setContextClassLoader(oldClassLoader); 644 } 645 } 646 647 private void addContainerInfos(Configuration configuration, ContainerSystemInfo containerSystem, ConfigurationFactory configurationFactory) throws OpenEJBException { 648 LinkedHashSet<GBeanData> containerDatas = configuration.findGBeanDatas(Collections.singleton(new AbstractNameQuery(EjbContainer.class.getName()))); 649 for (GBeanData containerData : containerDatas) { 650 Class<? extends ContainerInfo> infoClass = (Class<? extends ContainerInfo>) containerData.getAttribute("infoType"); 651 if (infoClass == null) { 652 String type = (String) containerData.getAttribute("type"); 653 infoClass = EjbContainer.getInfoType(type); 654 } 655 String serviceId = (String) containerData.getAttribute("id"); 656 Properties declaredProperties = (Properties) containerData.getAttribute("properties"); 657 String providerId = (String) containerData.getAttribute("provider"); 658 ContainerInfo containerInfo = configurationFactory.configureService(infoClass, serviceId, declaredProperties, providerId, "Container"); 659 containerSystem.containers.add(containerInfo); 660 } 661 } 662 663 private void addResourceAdapterMDBInfos(Configuration configuration, ContainerSystemInfo containerSystem, ConfigurationFactory configurationFactory) throws OpenEJBException { 664 LinkedHashSet<GBeanData> resourceAdapterWrappers = configuration.findGBeanDatas(Collections.singleton(new AbstractNameQuery(ResourceAdapterWrapperGBean.class.getName()))); 665 for (GBeanData resourceAdapterWrapperData : resourceAdapterWrappers) { 666 String resourceAdapterId = getResourceAdapterId(resourceAdapterWrapperData.getAbstractName()); 667 Map<String, String> messageListenerToActivationSpecMap = (Map<String, String>) resourceAdapterWrapperData.getAttribute("messageListenerToActivationSpecMap"); 668 if (messageListenerToActivationSpecMap == null) { 669 continue; 670 } 671 for (Map.Entry<String, String> entry : messageListenerToActivationSpecMap.entrySet()) { 672 String messageListenerInterface = entry.getKey(); 673 String activationSpecClass = entry.getValue(); 674 675 // only process RA if not previously processed 676 String containerName = resourceAdapterId + "-" + messageListenerInterface; 677 // get default mdb config 678 ContainerInfo containerInfo = configurationFactory.configureService(MdbContainerInfo.class); 679 containerInfo.id = containerName; 680 containerInfo.displayName = containerName; 681 682 // set ra specific properties 683 684 try { 685 containerInfo.properties.put("MessageListenerInterface", 686 configuration.getConfigurationClassLoader().loadClass(messageListenerInterface)); 687 } catch (ClassNotFoundException e) { 688 throw new OpenEJBException("Could not load MessageListenerInterface " + messageListenerInterface + " in classloader: " + configuration.getConfigurationClassLoader(), e); 689 } 690 try { 691 containerInfo.properties.put("ActivationSpecClass", 692 configuration.getConfigurationClassLoader().loadClass(activationSpecClass)); 693 } catch (ClassNotFoundException e) { 694 throw new OpenEJBException("Could not load ActivationSpecClass " + activationSpecClass + " in classloader: " + configuration.getConfigurationClassLoader(), e); 695 } 696 containerInfo.properties.put("TxRecovery", true); 697 //TODO is this necessary???? 698 // containerInfo.properties.put("ResourceAdapter", resourceAdapter); 699 700 containerSystem.containers.add(containerInfo); 701 } 702 } 703 } 704 705 706 private void addGeronimmoOpenEJBPersistenceUnit(EjbModule ejbModule) { 707 GeronimoEjbJarType geronimoEjbJarType = (GeronimoEjbJarType) ejbModule.getEjbModule().getAltDDs().get("geronimo-openejb.xml"); 708 709 // search for the cmp persistence unit 710 PersistenceUnit persistenceUnit = null; 711 for (Persistence persistence : geronimoEjbJarType.getPersistence()) { 712 for (PersistenceUnit unit : persistence.getPersistenceUnit()) { 713 if ("cmp".equals(unit.getName())) { 714 persistenceUnit = unit; 715 break; 716 } 717 } 718 } 719 720 // if not found create one 721 if (persistenceUnit == null) { 722 String jtaDataSource = null; 723 // todo Persistence Unit Data Sources need to be global JNDI names 724 Object altDD = ejbModule.getEjbModule().getAltDDs().get("openejb-jar.xml"); 725 if (altDD instanceof OpenejbJarType) { 726 ResourceLocatorType cmpConnectionFactory = ((OpenejbJarType) altDD).getCmpConnectionFactory(); 727 if (cmpConnectionFactory != null) { 728 String datasourceName = cmpConnectionFactory.getResourceLink(); 729 if (datasourceName != null) { 730 jtaDataSource = datasourceName.trim(); 731 } 732 } 733 } 734 735 persistenceUnit = new PersistenceUnit(); 736 persistenceUnit.setName("cmp"); 737 persistenceUnit.setTransactionType(TransactionType.JTA); 738 if (jtaDataSource != null) { 739 persistenceUnit.setJtaDataSource(jtaDataSource); 740 } else { 741 persistenceUnit.setJtaDataSource(defaultCmpJTADataSource); 742 } 743 persistenceUnit.setNonJtaDataSource(defaultCmpNonJTADataSource); 744 persistenceUnit.setExcludeUnlistedClasses(true); 745 746 Persistence persistence = new Persistence(); 747 persistence.setVersion("1.0"); 748 persistence.getPersistenceUnit().add(persistenceUnit); 749 750 geronimoEjbJarType.getPersistence().add(persistence); 751 } 752 persistenceUnit.getMappingFile().add("META-INF/openejb-cmp-generated-orm.xml"); 753 } 754 755 /** 756 * Does the meaty work of processing the deployment information and 757 * creating GBeans for all the EJBs in the JAR, etc. 758 */ 759 public void addGBeans(EARContext earContext, Module module, ClassLoader cl, Collection repositories) throws DeploymentException { 760 EjbModule ejbModule = (EjbModule) module; 761 EjbDeploymentBuilder ejbDeploymentBuilder = ejbModule.getEjbBuilder(); 762 763 // add enc 764 ejbDeploymentBuilder.buildEnc(); 765 766 Set<GBeanData> gBeanDatas = earContext.getConfiguration().findGBeanDatas(Collections.singleton(new AbstractNameQuery(PersistenceUnitGBean.class.getName()))); 767 LinkResolver<String> linkResolver = new UniqueDefaultLinkResolver<String>(); 768 for (GBeanData gBeanData : gBeanDatas) { 769 String name = (String) gBeanData.getAttribute("persistenceUnitName"); 770 String rootUrl = (String) gBeanData.getAttribute("persistenceUnitRoot"); 771 if (name.equals("cmp")) continue; 772 String id = name + " " + rootUrl.hashCode(); 773 linkResolver.add(rootUrl, name, id); 774 } 775 776 EjbJarInfo ejbJarInfo = ejbModule.getEjbJarInfo(); 777 for (EnterpriseBeanInfo beanInfo : ejbJarInfo.enterpriseBeans) { 778 if (beanInfo instanceof StatefulBeanInfo) { 779 StatefulBeanInfo statefulBeanInfo = (StatefulBeanInfo) beanInfo; 780 for (PersistenceContextReferenceInfo refInfo : statefulBeanInfo.jndiEnc.persistenceContextRefs) { 781 if (refInfo.extended) { 782 String id = linkResolver.resolveLink(refInfo.persistenceUnitName, ejbJarInfo.moduleId); 783 refInfo.unitId = id; 784 } 785 } 786 } 787 } 788 // Add JSR77 EJBModule GBean 789 GBeanData ejbModuleGBeanData = new GBeanData(ejbModule.getModuleName(), EjbModuleImplGBean.GBEAN_INFO); 790 try { 791 ejbModuleGBeanData.setReferencePattern("J2EEServer", earContext.getServerName()); 792 if (!ejbModule.isStandAlone()) { 793 ejbModuleGBeanData.setReferencePattern("J2EEApplication", earContext.getModuleName()); 794 } 795 796 ejbModuleGBeanData.setAttribute("deploymentDescriptor", ejbModule.getOriginalSpecDD()); 797 798 ejbModuleGBeanData.setReferencePatterns("EJBCollection", 799 new ReferencePatterns(new AbstractNameQuery(null, 800 Collections.singletonMap(NameFactory.EJB_MODULE, ejbModule.getModuleName().getNameProperty(NameFactory.J2EE_NAME)), 801 EjbDeployment.class.getName()))); 802 803 ejbModuleGBeanData.setReferencePattern("OpenEjbSystem", new AbstractNameQuery(null, Collections.EMPTY_MAP, OpenEjbSystem.class.getName())); 804 ejbModuleGBeanData.setAttribute("ejbJarInfo", ejbModule.getEjbJarInfo()); 805 806 earContext.addGBean(ejbModuleGBeanData); 807 } catch (Exception e) { 808 throw new DeploymentException("Unable to initialize EJBModule GBean " + ejbModuleGBeanData.getAbstractName(), e); 809 } 810 811 // add a depdendency on the ejb module object 812 ejbDeploymentBuilder.addEjbModuleDependency(ejbModuleGBeanData.getAbstractName()); 813 814 // add the Jacc permissions to the ear 815 ComponentPermissions componentPermissions = ejbDeploymentBuilder.buildComponentPermissions(); 816 earContext.addSecurityContext(ejbModule.getEjbJarInfo().moduleId, componentPermissions); 817 818 setMdbContainerIds(earContext, ejbModule, ejbModuleGBeanData); 819 820 for (ModuleBuilderExtension builder : moduleBuilderExtensions) { 821 try { 822 builder.addGBeans(earContext, module, cl, repositories); 823 } catch (Throwable t) { 824 String builderName = builder.getClass().getSimpleName(); 825 log.error(builderName + ".addGBeans() failed: " + t.getMessage(), t); 826 } 827 } 828 } 829 830 private void setMdbContainerIds(EARContext earContext, EjbModule ejbModule, GBeanData ejbModuleGBeanData) throws DeploymentException { 831 Object altDD = ejbModule.getEjbModule().getAltDDs().get("openejb-jar.xml"); 832 if (!(altDD instanceof OpenejbJarType)) { 833 return; 834 } 835 OpenejbJarType openejbJarType = (OpenejbJarType) altDD; 836 EjbJarInfo ejbJarInfo = ejbModule.getEjbJarInfo(); 837 838 Map<String, MessageDrivenBeanInfo> mdbs = new TreeMap<String, MessageDrivenBeanInfo>(); 839 for (EnterpriseBeanInfo enterpriseBean : ejbJarInfo.enterpriseBeans) { 840 if (enterpriseBean instanceof MessageDrivenBeanInfo) { 841 mdbs.put(enterpriseBean.ejbName, (MessageDrivenBeanInfo) enterpriseBean); 842 } 843 } 844 for (org.apache.openejb.jee.oejb2.EnterpriseBean enterpriseBean : openejbJarType.getEnterpriseBeans()) { 845 if (!(enterpriseBean instanceof MessageDrivenBeanType)) { 846 continue; 847 } 848 MessageDrivenBeanType bean = (MessageDrivenBeanType) enterpriseBean; 849 MessageDrivenBeanInfo messageDrivenBeanInfo = mdbs.get(bean.getEjbName()); 850 if (messageDrivenBeanInfo == null) { 851 continue; 852 } 853 if (messageDrivenBeanInfo.containerId != null) { 854 // containerId already set 855 continue; 856 } 857 858 if (bean.getResourceAdapter() == null) { 859 throw new DeploymentException("No Resource Adapter defined for MDB '" + bean.getEjbName() + "'"); 860 } 861 862 AbstractNameQuery resourceAdapterNameQuery = getResourceAdapterNameQuery(bean.getResourceAdapter()); 863 AbstractName resourceAdapterAbstractName; 864 try { 865 resourceAdapterAbstractName = earContext.findGBean(resourceAdapterNameQuery); 866 } catch (GBeanNotFoundException e) { 867 throw new DeploymentException("Resource Adapter for MDB '" + bean.getEjbName() + "'not found: " + resourceAdapterNameQuery, e); 868 } 869 870 String resourceAdapterId = getResourceAdapterId(resourceAdapterAbstractName); 871 messageDrivenBeanInfo.containerId = resourceAdapterId + "-" + messageDrivenBeanInfo.mdbInterface; 872 873 // add a dependency from the module to the ra so we can be assured the mdb 874 // container exists when this app is started 875 ejbModuleGBeanData.addDependency(resourceAdapterAbstractName); 876 } 877 } 878 879 private String getResourceAdapterId(AbstractName resourceAdapterAbstractName) { 880 Map properties = resourceAdapterAbstractName.getName(); 881 String shortName = (String) properties.get("name"); 882 String moduleName = (String) properties.get("ResourceAdapterModule"); 883 if (shortName != null && moduleName != null) { 884 return moduleName + "." + shortName; 885 } else { 886 return resourceAdapterAbstractName.getObjectName().toString(); 887 } 888 } 889 890 private static AbstractNameQuery getResourceAdapterNameQuery(ResourceLocatorType resourceLocator) { 891 if (resourceLocator.getResourceLink() != null) { 892 Map<String, String> nameMap = new HashMap<String, String>(); 893 nameMap.put("name", resourceLocator.getResourceLink()); 894 nameMap.put("j2eeType", NameFactory.JCA_RESOURCE_ADAPTER); 895 return new AbstractNameQuery(null, nameMap); 896 } 897 898 //construct name from components 899 PatternType pattern = resourceLocator.getPattern(); 900 Artifact artifact = null; 901 if (pattern.getArtifactId() != null) { 902 artifact = new Artifact(pattern.getGroupId(), pattern.getArtifactId(), pattern.getVersion(), "car"); 903 } 904 905 Map<String, String> nameMap = new HashMap<String, String>(); 906 nameMap.put("name", pattern.getName()); 907 nameMap.put("j2eeType", NameFactory.JCA_RESOURCE_ADAPTER); 908 if (pattern.getModule() != null) { 909 nameMap.put(NameFactory.RESOURCE_ADAPTER_MODULE, pattern.getModule()); 910 } 911 return new AbstractNameQuery(artifact, nameMap, (Set) null); 912 } 913 914 public static class EarData { 915 private final Map<String, EjbModule> ejbModules = new TreeMap<String, EjbModule>(); 916 private final Map<String, EjbJarInfo> ejbJars = new TreeMap<String, EjbJarInfo>(); 917 918 public void addEjbModule(EjbModule ejbModule) { 919 ejbModules.put(ejbModule.getEjbModule().getModuleId(), ejbModule); 920 } 921 922 public EjbModule getEjbModule(String moduleId) throws DeploymentException { 923 EjbModule ejbModule = ejbModules.get(moduleId); 924 if (ejbModule == null) { 925 throw new DeploymentException("Ejb module " + moduleId + " was not found in configured module list " + ejbModules.keySet()); 926 } 927 return ejbModule; 928 } 929 930 public Collection<EjbModule> getEjbModuels() { 931 return ejbModules.values(); 932 } 933 934 public void addEjbJar(EjbJarInfo ejbJarInfo) { 935 ejbJars.put(ejbJarInfo.moduleId, ejbJarInfo); 936 } 937 938 public EjbJarInfo getEjbJar(String moduleId) throws DeploymentException { 939 EjbJarInfo ejbJarInfo = ejbJars.get(moduleId); 940 if (ejbJarInfo == null) { 941 throw new DeploymentException("Ejb jar configuration passed but expected module " + 942 moduleId + " was not found in configured module list " + ejbJars.keySet()); 943 } 944 return ejbJarInfo; 945 } 946 947 public Collection<EjbJarInfo> getEjbJars() { 948 return ejbJars.values(); 949 } 950 } 951 952 953 public static final GBeanInfo GBEAN_INFO; 954 955 static { 956 GBeanInfoBuilder infoBuilder = GBeanInfoBuilder.createStatic(EjbModuleBuilder.class, NameFactory.MODULE_BUILDER); 957 infoBuilder.addAttribute("defaultEnvironment", Environment.class, true); 958 infoBuilder.addAttribute("defaultCmpJTADataSource", String.class, true); 959 infoBuilder.addAttribute("defaultCmpNonJTADataSource", String.class, true); 960 infoBuilder.addReference("ModuleBuilderExtensions", ModuleBuilderExtension.class, NameFactory.MODULE_BUILDER); 961 infoBuilder.addReference("SecurityBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER); 962 infoBuilder.addReference("ServiceBuilders", NamespaceDrivenBuilder.class, NameFactory.MODULE_BUILDER); 963 infoBuilder.addReference("NamingBuilders", NamingBuilder.class, NameFactory.MODULE_BUILDER); 964 infoBuilder.addReference("ResourceEnvironmentSetter", ResourceEnvironmentSetter.class, NameFactory.MODULE_BUILDER); 965 966 infoBuilder.setConstructor(new String[]{ 967 "defaultEnvironment", 968 "defaultCmpJTADataSource", 969 "defaultCmpNonJTADataSource", 970 "ModuleBuilderExtensions", 971 "SecurityBuilders", 972 "ServiceBuilders", 973 "NamingBuilders", 974 "ResourceEnvironmentSetter"}); 975 GBEAN_INFO = infoBuilder.getBeanInfo(); 976 } 977 978 public static GBeanInfo getGBeanInfo() { 979 return GBEAN_INFO; 980 } 981 982 }