Esempio n. 1
0
 /**
  * Find an already-loaded module, returning {@code null} if the module isn't currently loaded. May
  * block while the loaded state of the module is in question (if the module is being concurrently
  * loaded from another thread, for example).
  *
  * @param identifier the module identifier
  * @return the module, or {@code null} if it wasn't found
  */
 protected final Module findLoadedModuleLocal(ModuleIdentifier identifier) {
   FutureModule futureModule = moduleMap.get(identifier);
   if (futureModule != null) {
     try {
       return futureModule.getModule();
     } catch (ModuleNotFoundException e) {
       return null;
     }
   } else {
     return null;
   }
 }
Esempio n. 2
0
  /**
   * Defines a Module based on a specification. Use of this method is required by any ModuleLoader
   * implementations in order to fully define a Module.
   *
   * @param moduleSpec The module specification to create the Module from
   * @return The defined Module
   * @throws ModuleLoadException If any dependent modules can not be loaded
   */
  protected final Module defineModule(ModuleSpec moduleSpec) throws ModuleLoadException {

    final ModuleIdentifier moduleIdentifier = moduleSpec.getIdentifier();
    FutureModule futureModule = moduleMap.get(moduleIdentifier);
    if (futureModule == null) {
      FutureModule newFuture = new FutureModule(moduleIdentifier);
      futureModule = moduleMap.putIfAbsent(moduleIdentifier, newFuture);
      if (futureModule == null) futureModule = newFuture;
    }
    // early detect
    if (futureModule.module != null) {
      throw new ModuleAlreadyExistsException(moduleIdentifier.toString());
    }
    try {
      final List<Dependency> dependencies =
          new ArrayList<Dependency>(moduleSpec.getDependencies().size());
      for (DependencySpec dependencySpec : moduleSpec.getDependencies()) {
        final Module dependencyModule;
        try {
          dependencyModule = loadModule(dependencySpec.getModuleIdentifier());
        } catch (ModuleLoadException e) {
          if (dependencySpec.isOptional()) {
            continue;
          } else {
            throw e;
          }
        }
        final Dependency dependency = new Dependency(dependencyModule, dependencySpec.isExport());
        dependencies.add(dependency);
      }
      final Module module = new Module(moduleSpec, dependencies, moduleSpec.getModuleFlags(), this);
      synchronized (futureModule) {
        futureModule.setModule(module);
      }
      return module;
    } catch (ModuleLoadException e) {
      futureModule.setModule(null);
      throw e;
    } catch (RuntimeException e) {
      futureModule.setModule(null);
      throw e;
    } catch (Error e) {
      futureModule.setModule(null);
      throw e;
    }
  }
Esempio n. 3
0
  /**
   * Load a module based on an identifier.
   *
   * @param identifier The module identifier
   * @return The loaded Module
   * @throws ModuleLoadException if the Module can not be loaded
   */
  public Module loadModule(ModuleIdentifier identifier) throws ModuleLoadException {
    final Set<ModuleIdentifier> visited = VISITED.get();

    if (visited.contains(identifier))
      throw new ModuleLoadException(
          "Failed to load " + identifier + "; module cycle discovered: " + visited);

    FutureModule futureModule = moduleMap.get(identifier);
    if (futureModule == null) {
      FutureModule newFuture = new FutureModule(identifier);
      futureModule = moduleMap.putIfAbsent(identifier, newFuture);
      if (futureModule == null) {
        visited.add(identifier);
        try {
          final Module module = findModule(identifier);
          if (module == null) throw new ModuleNotFoundException(identifier.toString());
          return module;
        } finally {
          visited.remove(identifier);
        }
      }
    }
    return futureModule.getModule();
  }
Esempio n. 4
0
  /**
   * Try to load a module from this module loader. Returns {@code null} if the module is not found.
   * The returned module may not yet be resolved. The returned module may have a different name than
   * the given identifier if the identifier is an alias for another module.
   *
   * @param identifier the module identifier
   * @return the module
   * @throws ModuleLoadException if an error occurs while loading the module
   */
  protected final Module loadModuleLocal(ModuleIdentifier identifier) throws ModuleLoadException {
    FutureModule futureModule = moduleMap.get(identifier);
    if (futureModule != null) {
      return futureModule.getModule();
    }

    FutureModule newFuture = new FutureModule(identifier);
    futureModule = moduleMap.putIfAbsent(identifier, newFuture);
    if (futureModule != null) {
      return futureModule.getModule();
    }

    boolean ok = false;
    try {
      final ModuleLogger log = Module.log;
      log.trace("Locally loading module %s from %s", identifier, this);
      final long startTime = Metrics.getCurrentCPUTime();
      final ModuleSpec moduleSpec = findModule(identifier);
      loadTimeUpdater.addAndGet(this, Metrics.getCurrentCPUTime() - startTime);
      if (moduleSpec == null) {
        log.trace("Module %s not found from %s", identifier, this);
        return null;
      }
      if (!moduleSpec.getModuleIdentifier().equals(identifier)) {
        throw new ModuleLoadException("Module loader found a module with the wrong name");
      }
      final Module module;
      if (moduleSpec instanceof AliasModuleSpec) {
        final ModuleIdentifier aliasTarget = ((AliasModuleSpec) moduleSpec).getAliasTarget();
        try {
          newFuture.setModule(module = loadModuleLocal(aliasTarget));
        } catch (RuntimeException e) {
          log.trace(e, "Failed to load module %s (alias for %s)", identifier, aliasTarget);
          throw e;
        } catch (Error e) {
          log.trace(e, "Failed to load module %s (alias for %s)", identifier, aliasTarget);
          throw e;
        }
      } else {
        module = defineModule((ConcreteModuleSpec) moduleSpec, newFuture);
      }
      log.trace("Loaded module %s from %s", identifier, this);
      ok = true;
      return module;
    } finally {
      if (!ok) {
        newFuture.setModule(null);
        moduleMap.remove(identifier, newFuture);
      }
    }
  }
Esempio n. 5
0
  /**
   * Defines a Module based on a specification. May only be called from {@link
   * #loadModuleLocal(ModuleIdentifier)}.
   *
   * @param moduleSpec The module specification to create the Module from
   * @param futureModule the future module to populate
   * @return The defined Module
   * @throws ModuleLoadException If any dependent modules can not be loaded
   */
  private Module defineModule(final ConcreteModuleSpec moduleSpec, final FutureModule futureModule)
      throws ModuleLoadException {

    final ModuleLogger log = Module.log;
    final ModuleIdentifier moduleIdentifier = moduleSpec.getModuleIdentifier();

    final Module module = new Module(moduleSpec, this, futureModule);
    module.getClassLoaderPrivate().recalculate();
    module.setDependencies(Arrays.asList(moduleSpec.getDependencies()));
    log.moduleDefined(moduleIdentifier, this);
    try {
      futureModule.setModule(module);
      return module;
    } catch (RuntimeException e) {
      log.trace(e, "Failed to load module %s", moduleIdentifier);
      throw e;
    } catch (Error e) {
      log.trace(e, "Failed to load module %s", moduleIdentifier);
      throw e;
    }
  }