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 018 package org.apache.geronimo.deployment; 019 020 import java.io.ByteArrayInputStream; 021 import java.io.File; 022 import java.io.FileOutputStream; 023 import java.io.IOException; 024 import java.io.InputStream; 025 import java.io.OutputStream; 026 import java.net.URI; 027 import java.net.URISyntaxException; 028 import java.net.URL; 029 import java.util.ArrayList; 030 import java.util.Collection; 031 import java.util.Collections; 032 import java.util.HashSet; 033 import java.util.LinkedHashMap; 034 import java.util.LinkedHashSet; 035 import java.util.List; 036 import java.util.Map; 037 import java.util.Set; 038 import java.util.StringTokenizer; 039 import java.util.jar.Attributes; 040 import java.util.jar.JarFile; 041 import java.util.jar.Manifest; 042 import java.util.zip.ZipEntry; 043 import java.util.zip.ZipFile; 044 045 import org.apache.geronimo.common.DeploymentException; 046 import org.apache.geronimo.deployment.util.DeploymentUtil; 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.GReferenceInfo; 052 import org.apache.geronimo.gbean.ReferencePatterns; 053 import org.apache.geronimo.kernel.GBeanAlreadyExistsException; 054 import org.apache.geronimo.kernel.GBeanNotFoundException; 055 import org.apache.geronimo.kernel.Naming; 056 import org.apache.geronimo.kernel.config.Configuration; 057 import org.apache.geronimo.kernel.config.ConfigurationData; 058 import org.apache.geronimo.kernel.config.ConfigurationManager; 059 import org.apache.geronimo.kernel.config.ConfigurationModuleType; 060 import org.apache.geronimo.kernel.config.NoSuchConfigException; 061 import org.apache.geronimo.kernel.repository.Artifact; 062 import org.apache.geronimo.kernel.repository.Environment; 063 064 /** 065 * @version $Rev:385232 $ $Date: 2007-07-23 21:41:35 -0400 (Mon, 23 Jul 2007) $ 066 */ 067 public class DeploymentContext { 068 private final File baseDir; 069 private final File inPlaceConfigurationDir; 070 private final ResourceContext resourceContext; 071 private final byte[] buffer = new byte[4096]; 072 private final Map<String, ConfigurationData> childConfigurationDatas = new LinkedHashMap<String, ConfigurationData>(); 073 private final ConfigurationManager configurationManager; 074 private final Configuration configuration; 075 private final Naming naming; 076 private final List<ConfigurationData> additionalDeployment = new ArrayList<ConfigurationData>(); 077 protected final AbstractName moduleName; 078 079 public DeploymentContext(File baseDir, File inPlaceConfigurationDir, Environment environment, AbstractName moduleName, ConfigurationModuleType moduleType, Naming naming, ConfigurationManager configurationManager, Collection repositories) throws DeploymentException { 080 this(baseDir, inPlaceConfigurationDir, environment, moduleName, moduleType, naming, createConfigurationManager(configurationManager, repositories)); 081 } 082 083 public DeploymentContext(File baseDir, File inPlaceConfigurationDir, Environment environment, AbstractName moduleName, ConfigurationModuleType moduleType, Naming naming, ConfigurationManager configurationManager) throws DeploymentException { 084 if (baseDir == null) throw new NullPointerException("baseDir is null"); 085 if (environment == null) throw new NullPointerException("environment is null"); 086 if (moduleType == null) throw new NullPointerException("type is null"); 087 if (configurationManager == null) throw new NullPointerException("configurationManager is null"); 088 089 if (!baseDir.exists()) { 090 baseDir.mkdirs(); 091 } 092 this.baseDir = baseDir; 093 094 this.inPlaceConfigurationDir = inPlaceConfigurationDir; 095 096 this.moduleName = moduleName; 097 098 this.naming = naming; 099 100 this.configuration = createTempConfiguration(environment, moduleType, baseDir, inPlaceConfigurationDir, configurationManager, naming); 101 102 this.configurationManager = configurationManager; 103 104 if (null == inPlaceConfigurationDir) { 105 resourceContext = new CopyResourceContext(configuration, baseDir); 106 } else { 107 resourceContext = new InPlaceResourceContext(configuration, inPlaceConfigurationDir); 108 } 109 } 110 111 private static ConfigurationManager createConfigurationManager(ConfigurationManager configurationManager, Collection repositories) { 112 return new DeploymentConfigurationManager(configurationManager, repositories); 113 } 114 115 private static Configuration createTempConfiguration(Environment environment, ConfigurationModuleType moduleType, File baseDir, File inPlaceConfigurationDir, ConfigurationManager configurationManager, Naming naming) throws DeploymentException { 116 try { 117 configurationManager.loadConfiguration(new ConfigurationData(moduleType, null, null, null, environment, baseDir, inPlaceConfigurationDir, naming)); 118 return configurationManager.getConfiguration(environment.getConfigId()); 119 } catch (Exception e) { 120 throw new DeploymentException("Unable to create configuration for deployment", e); 121 } 122 } 123 124 public ConfigurationManager getConfigurationManager() { 125 return configurationManager; 126 } 127 128 public Artifact getConfigID() { 129 return configuration.getId(); 130 } 131 132 public File getBaseDir() { 133 return baseDir; 134 } 135 136 public File getInPlaceConfigurationDir() { 137 return inPlaceConfigurationDir; 138 } 139 140 public Naming getNaming() { 141 return naming; 142 } 143 144 public GBeanData addGBean(String name, GBeanInfo gbeanInfo) throws GBeanAlreadyExistsException { 145 if (name == null) throw new NullPointerException("name is null"); 146 if (gbeanInfo == null) throw new NullPointerException("gbean is null"); 147 GBeanData gbean = new GBeanData(gbeanInfo); 148 configuration.addGBean(name, gbean); 149 return gbean; 150 } 151 152 public void addGBean(GBeanData gbean) throws GBeanAlreadyExistsException { 153 if (gbean == null) throw new NullPointerException("gbean is null"); 154 if (gbean.getAbstractName() == null) throw new NullPointerException("gbean.getAbstractName() is null"); 155 configuration.addGBean(gbean); 156 } 157 158 public void removeGBean(AbstractName name) throws GBeanNotFoundException { 159 if (name == null) throw new NullPointerException("name is null"); 160 configuration.removeGBean(name); 161 } 162 163 public Set<AbstractName> getGBeanNames() { 164 return new HashSet<AbstractName>(configuration.getGBeans().keySet()); 165 } 166 167 /** 168 * @deprecated use findGBeans(pattern) 169 * @param pattern Search for gbeans whose name matches pattern. 170 * @return the set of gbeans whose name matches the pattern. 171 */ 172 public Set<AbstractName> listGBeans(AbstractNameQuery pattern) { 173 return findGBeans(pattern); 174 } 175 176 public AbstractName findGBean(AbstractNameQuery pattern) throws GBeanNotFoundException { 177 return configuration.findGBean(pattern); 178 } 179 180 public AbstractName findGBean(Set<AbstractNameQuery> patterns) throws GBeanNotFoundException { 181 return configuration.findGBean(patterns); 182 } 183 184 public LinkedHashSet<AbstractName> findGBeans(AbstractNameQuery pattern) { 185 return configuration.findGBeans(pattern); 186 } 187 188 public LinkedHashSet<GBeanData> findGBeanDatas(Configuration configuration, AbstractNameQuery pattern) { 189 return configuration.findGBeanDatas(configuration, Collections.singleton(pattern)); 190 } 191 192 public LinkedHashSet<AbstractName> findGBeans(Set<AbstractNameQuery> patterns) { 193 return configuration.findGBeans(patterns); 194 } 195 196 public GBeanData getGBeanInstance(AbstractName name) throws GBeanNotFoundException { 197 Map gbeans = configuration.getGBeans(); 198 GBeanData gbeanData = (GBeanData) gbeans.get(name); 199 if (gbeanData == null) { 200 throw new GBeanNotFoundException(name); 201 } 202 return gbeanData; 203 } 204 205 /** 206 * Add a packed jar file into the deployment context and place it into the 207 * path specified in the target path. The newly added packed jar is added 208 * to the classpath of the configuration. 209 * 210 * @param targetPath where the packed jar file should be placed 211 * @param jarFile the jar file to copy 212 * @throws IOException if there's a problem copying the jar file 213 */ 214 public void addIncludeAsPackedJar(URI targetPath, JarFile jarFile) throws IOException { 215 resourceContext.addIncludeAsPackedJar(targetPath, jarFile); 216 } 217 218 /** 219 * Add a ZIP file entry into the deployment context and place it into the 220 * path specified in the target path. The newly added entry is added 221 * to the classpath of the configuration. 222 * 223 * @param targetPath where the ZIP file entry should be placed 224 * @param zipFile the ZIP file 225 * @param zipEntry the ZIP file entry 226 * @throws IOException if there's a problem copying the ZIP entry 227 */ 228 public void addInclude(URI targetPath, ZipFile zipFile, ZipEntry zipEntry) throws IOException { 229 resourceContext.addInclude(targetPath, zipFile, zipEntry); 230 } 231 232 /** 233 * Add a file into the deployment context and place it into the 234 * path specified in the target path. The newly added file is added 235 * to the classpath of the configuration. 236 * 237 * @param targetPath where the file should be placed 238 * @param source the URL of file to be copied 239 * @throws IOException if there's a problem copying the ZIP entry 240 */ 241 public void addInclude(URI targetPath, URL source) throws IOException { 242 resourceContext.addInclude(targetPath, source); 243 } 244 245 /** 246 * Add a file into the deployment context and place it into the 247 * path specified in the target path. The newly added file is added 248 * to the classpath of the configuration. 249 * 250 * @param targetPath where the file should be placed 251 * @param source the file to be copied 252 * @throws IOException if there's a problem copying the ZIP entry 253 */ 254 public void addInclude(URI targetPath, File source) throws IOException { 255 resourceContext.addInclude(targetPath, source); 256 } 257 258 interface JarFileFactory { 259 JarFile newJarFile(URI relativeURI) throws IOException; 260 261 String getManifestClassPath(JarFile jarFile) throws IOException; 262 } 263 264 private class DefaultJarFileFactory implements JarFileFactory { 265 266 public JarFile newJarFile(URI relativeURI) throws IOException { 267 File targetFile = getTargetFile(relativeURI); 268 try { 269 return new JarFile(targetFile); 270 } catch (IOException e) { 271 throw (IOException)new IOException("Could not create JarFile for file: " + targetFile).initCause(e); 272 } 273 } 274 275 public String getManifestClassPath(JarFile jarFile) throws IOException { 276 Manifest manifest = jarFile.getManifest(); 277 if (manifest == null) { 278 return null; 279 } 280 return manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); 281 } 282 } 283 284 public void getCompleteManifestClassPath(JarFile moduleFile, URI moduleBaseUri, URI resolutionUri, ClassPathList classpath, ModuleList exclusions) throws DeploymentException { 285 List<DeploymentException> problems = new ArrayList<DeploymentException>(); 286 getCompleteManifestClassPath(moduleFile, moduleBaseUri, resolutionUri, classpath, exclusions, new DefaultJarFileFactory(), problems); 287 if (!problems.isEmpty()) { 288 if (problems.size() == 1) { 289 throw problems.get(0); 290 } 291 throw new DeploymentException("Determining complete manifest classpath unsuccessful:", problems); 292 } 293 } 294 295 /** 296 * Recursively construct the complete set of paths in the ear for the manifest classpath of the supplied modulefile. 297 * Used only in PersistenceUnitBuilder to figure out if a persistence.xml relates to the starting module. Having a classloader for 298 * each ejb module would eliminate the need for this and be more elegant. 299 * 300 * @param moduleFile the module that we start looking at classpaths at, in the car. 301 * @param moduleBaseUri where the moduleFile is inside the car file. For an (unpacked) war this ends with / which means we also need: 302 * @param resolutionUri the uri to resolve all entries against. For a module such as an ejb jar that is part of the 303 * root ear car it is ".". For a sub-configuration such as a war it is the "reverse" of the path to the war file in the car. 304 * For instance, if the war file is foo/bar/myweb.war, the resolutionUri is "../../..". 305 * @param classpath the classpath list we are constructing. 306 * @param exclusions the paths to not investigate. These are typically the other modules in the ear/car file: they will have their contents processed for themselves. 307 * @param factory the factory for constructing JarFiles and the way to extract the manifest classpath from a JarFile. Introduced to make 308 * testing plausible, but may be useful for in-IDE deployment. 309 * @param problems List to save all the problems we encounter. 310 * @throws org.apache.geronimo.common.DeploymentException 311 * if something goes wrong. 312 */ 313 public void getCompleteManifestClassPath(JarFile moduleFile, URI moduleBaseUri, URI resolutionUri, ClassPathList classpath, ModuleList exclusions, JarFileFactory factory, List<DeploymentException> problems) throws DeploymentException { 314 String manifestClassPath; 315 try { 316 manifestClassPath = factory.getManifestClassPath(moduleFile); 317 } catch (IOException e) { 318 problems.add(new DeploymentException(printInfo("Could not read manifest: " + moduleBaseUri, moduleBaseUri, classpath, exclusions), e)); 319 return; 320 } 321 322 if (manifestClassPath == null) { 323 return; 324 } 325 326 for (StringTokenizer tokenizer = new StringTokenizer(manifestClassPath, " "); tokenizer.hasMoreTokens();) { 327 String path = tokenizer.nextToken(); 328 329 URI pathUri; 330 try { 331 pathUri = new URI(path); 332 } catch (URISyntaxException e) { 333 problems.add(new DeploymentException(printInfo("Invalid manifest classpath entry, path=" + path, moduleBaseUri, classpath, exclusions))); 334 return; 335 } 336 337 if (!pathUri.getPath().endsWith(".jar")) { 338 problems.add(new DeploymentException(printInfo("Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): path=" + path, moduleBaseUri, classpath, exclusions))); 339 return; 340 } 341 if (pathUri.isAbsolute()) { 342 problems.add(new DeploymentException(printInfo("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): path=" + path, moduleBaseUri, classpath, exclusions))); 343 return; 344 } 345 346 URI targetUri = moduleBaseUri.resolve(pathUri); 347 if (targetUri.getPath().endsWith("/")) { 348 problems.add(new DeploymentException(printInfo("target path must not end with a '/' character: path=" + path + ", resolved to targetURI=" + targetUri, moduleBaseUri, classpath, exclusions))); 349 return; 350 } 351 String targetEntry = targetUri.toString(); 352 if (exclusions.contains(targetEntry)) { 353 continue; 354 } 355 URI resolvedUri = resolutionUri.resolve(targetUri); 356 String classpathEntry = resolvedUri.toString(); 357 //don't get caught in circular references 358 if (classpath.contains(classpathEntry)) { 359 continue; 360 } 361 classpath.add(classpathEntry); 362 363 JarFile classPathJarFile; 364 try { 365 classPathJarFile = factory.newJarFile(targetUri); 366 } catch (IOException e) { 367 problems.add(new DeploymentException(printInfo("Manifest class path entries must be a valid jar file (JAVAEE 5 Section 8.2): path=" + path + ", resolved to targetURI=" + targetUri, moduleBaseUri, classpath, exclusions), e)); 368 return; 369 } 370 371 getCompleteManifestClassPath(classPathJarFile, targetUri, resolutionUri, classpath, exclusions, factory, problems); 372 } 373 } 374 375 private String printInfo(String message, URI moduleBaseUri, ClassPathList classpath, ModuleList exclusions) { 376 StringBuffer buf = new StringBuffer(message).append("\n"); 377 buf.append(" looking at: ").append(moduleBaseUri); 378 buf.append(" current classpath: ").append(classpath); 379 buf.append(" ignoring modules: ").append(exclusions); 380 return buf.toString(); 381 } 382 383 /** 384 * Import the classpath from a jar file's manifest. The imported classpath 385 * is crafted relative to <code>moduleBaseUri</code>. 386 * 387 * @param moduleFile the jar file from which the manifest is obtained. 388 * @param moduleBaseUri the base for the imported classpath 389 * @throws DeploymentException if there is a problem with the classpath in 390 * the manifest 391 */ 392 public void addManifestClassPath(JarFile moduleFile, URI moduleBaseUri) throws DeploymentException { 393 Manifest manifest; 394 try { 395 manifest = moduleFile.getManifest(); 396 } catch (IOException e) { 397 throw new DeploymentException("Could not read manifest: " + moduleBaseUri); 398 } 399 400 if (manifest == null) { 401 return; 402 } 403 String manifestClassPath = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH); 404 if (manifestClassPath == null) { 405 return; 406 } 407 408 for (StringTokenizer tokenizer = new StringTokenizer(manifestClassPath, " "); tokenizer.hasMoreTokens();) { 409 String path = tokenizer.nextToken(); 410 411 URI pathUri; 412 try { 413 pathUri = new URI(path); 414 } catch (URISyntaxException e) { 415 throw new DeploymentException("Invalid manifest classpath entry: module=" + moduleBaseUri + ", path=" + path); 416 } 417 418 if (!pathUri.getPath().endsWith(".jar")) { 419 throw new DeploymentException("Manifest class path entries must end with the .jar extension (J2EE 1.4 Section 8.2): module=" + moduleBaseUri); 420 } 421 if (pathUri.isAbsolute()) { 422 throw new DeploymentException("Manifest class path entries must be relative (J2EE 1.4 Section 8.2): moduel=" + moduleBaseUri); 423 } 424 425 try { 426 URI targetUri = moduleBaseUri.resolve(pathUri); 427 if (targetUri.getPath().endsWith("/")) 428 throw new IllegalStateException("target path must not end with a '/' character: " + targetUri); 429 configuration.addToClassPath(targetUri.toString()); 430 } catch (IOException e) { 431 throw new DeploymentException(e); 432 } 433 } 434 } 435 436 public void addClass(URI targetPath, String fqcn, byte[] bytes) throws IOException, URISyntaxException { 437 if (!targetPath.getPath().endsWith("/")) 438 throw new IllegalStateException("target path must end with a '/' character: " + targetPath); 439 440 String classFileName = fqcn.replace('.', '/') + ".class"; 441 442 File targetFile = getTargetFile(new URI(targetPath.toString() + classFileName)); 443 addFile(targetFile, new ByteArrayInputStream(bytes)); 444 445 configuration.addToClassPath(targetPath.toString()); 446 } 447 448 public void addFile(URI targetPath, ZipFile zipFile, ZipEntry zipEntry) throws IOException { 449 resourceContext.addFile(targetPath, zipFile, zipEntry); 450 } 451 452 public void addFile(URI targetPath, URL source) throws IOException { 453 resourceContext.addFile(targetPath, source); 454 } 455 456 public void addFile(URI targetPath, File source) throws IOException { 457 resourceContext.addFile(targetPath, source); 458 } 459 460 public void addFile(URI targetPath, String source) throws IOException { 461 resourceContext.addFile(targetPath, source); 462 } 463 464 private void addFile(File targetFile, InputStream source) throws IOException { 465 targetFile.getParentFile().mkdirs(); 466 OutputStream out = null; 467 try { 468 out = new FileOutputStream(targetFile); 469 int count; 470 while ((count = source.read(buffer)) > 0) { 471 out.write(buffer, 0, count); 472 } 473 } finally { 474 DeploymentUtil.close(out); 475 } 476 } 477 478 public File getTargetFile(URI targetPath) { 479 return resourceContext.getTargetFile(targetPath); 480 } 481 482 public ClassLoader getClassLoader() throws DeploymentException { 483 return configuration.getConfigurationClassLoader(); 484 } 485 486 public Configuration getConfiguration() { 487 return configuration; 488 } 489 490 public void flush() throws IOException { 491 resourceContext.flush(); 492 } 493 494 public void close() throws IOException, DeploymentException { 495 if (configurationManager != null) { 496 try { 497 configurationManager.unloadConfiguration(configuration.getId()); 498 } catch (NoSuchConfigException ignored) { 499 //ignore 500 } 501 } 502 } 503 504 public void addChildConfiguration(String moduleName, ConfigurationData configurationData) { 505 childConfigurationDatas.put(moduleName, configurationData); 506 } 507 508 public ConfigurationData getConfigurationData() throws DeploymentException { 509 List<String> failures = verify(configuration); 510 if (!failures.isEmpty()) { 511 StringBuffer message = new StringBuffer(); 512 for (String failure : failures) { 513 if (message.length() > 0) message.append("\n"); 514 message.append(failure); 515 } 516 throw new DeploymentException(message.toString()); 517 } 518 519 ArrayList<GBeanData> gbeans = new ArrayList<GBeanData>(configuration.getGBeans().values()); 520 Collections.sort(gbeans, new GBeanData.PriorityComparator()); 521 ConfigurationData configurationData = new ConfigurationData(configuration.getModuleType(), 522 new LinkedHashSet<String>(configuration.getClassPath()), 523 gbeans, 524 childConfigurationDatas, 525 configuration.getEnvironment(), 526 baseDir, 527 inPlaceConfigurationDir, 528 naming); 529 530 for (ConfigurationData ownedConfiguration : additionalDeployment) { 531 configurationData.addOwnedConfigurations(ownedConfiguration.getId()); 532 } 533 534 return configurationData; 535 } 536 537 public void addAdditionalDeployment(ConfigurationData configurationData) { 538 additionalDeployment.add(configurationData); 539 } 540 541 public List getAdditionalDeployment() { 542 return additionalDeployment; 543 } 544 545 public AbstractName getModuleName() { 546 return moduleName; 547 } 548 549 public List<String> verify(Configuration configuration) throws DeploymentException { 550 List<String> failures = new ArrayList<String>(); 551 for (Map.Entry<AbstractName, GBeanData> entry : this.configuration.getGBeans().entrySet()) { 552 AbstractName name = entry.getKey(); 553 GBeanData gbean = entry.getValue(); 554 555 for (Map.Entry<String, ReferencePatterns> referenceEntry : gbean.getReferences().entrySet()) { 556 String referenceName = referenceEntry.getKey(); 557 ReferencePatterns referencePatterns = referenceEntry.getValue(); 558 559 String failure = verifyReference(gbean, referenceName, referencePatterns, configuration); 560 if (failure != null) { 561 failures.add(failure); 562 } 563 } 564 565 for (ReferencePatterns referencePatterns : gbean.getDependencies()) { 566 String failure = verifyDependency(name, referencePatterns, configuration); 567 if (failure != null) { 568 failures.add(failure); 569 } 570 } 571 } 572 return failures; 573 } 574 575 private String verifyReference(GBeanData gbean, String referenceName, ReferencePatterns referencePatterns, Configuration configuration) { 576 GReferenceInfo referenceInfo = gbean.getGBeanInfo().getReference(referenceName); 577 578 // if there is no reference info we can't verify 579 if (referenceInfo == null) return null; 580 581 // A collection valued reference doesn't need to be verified 582 if (referenceInfo.getProxyType().equals(Collection.class.getName())) return null; 583 584 String message = isVerifyReference(referencePatterns, configuration); 585 if (message != null) { 586 return "Unable to resolve reference \"" + referenceName + "\" in gbean " + 587 gbean.getAbstractName() + " to a gbean matching the pattern " + referencePatterns.getPatterns() + "due to: " + message; 588 } 589 return null; 590 } 591 592 private String verifyDependency(AbstractName name, ReferencePatterns referencePatterns, Configuration configuration) { 593 String message = isVerifyReference(referencePatterns, configuration); 594 if (message != null) { 595 return "Unable to resolve dependency in gbean " + name + 596 " to a gbean matching the pattern " + referencePatterns.getPatterns() + "due to: " + message; 597 } 598 599 return null; 600 } 601 602 private String isVerifyReference(ReferencePatterns referencePatterns, Configuration configuration) { 603 // we can't verify a resolved reference since it will have a specific artifact already set... 604 // hopefully the deployer won't generate bad resolved references 605 if (referencePatterns.isResolved()) return null; 606 607 // Do not verify the reference if it has an explicit depenency on another artifact, because it it likely 608 // that the other artifact is not in the "environment" (if it were you wouldn't use the long form) 609 Set<AbstractNameQuery> patterns = referencePatterns.getPatterns(); 610 for (AbstractNameQuery query : patterns) { 611 if (query.getArtifact() != null) return null; 612 } 613 614 // attempt to find the bean 615 try { 616 configuration.findGBean(patterns); 617 return null; 618 } catch (GBeanNotFoundException e) { 619 //TODO bug!! GERONIMO-3140 Multiple matches may be caused by using an already-loaded configuration rather than reloading one 620 // using the client_artifact_aliases.properties which e.g. remap the server tm to the client tm. 621 if (e.hasMatches()) { 622 return null; 623 } 624 return e.getMessage(); 625 } 626 } 627 }