1. 调试类:
org.jboss.as.server.Main的main方法
断点:
Module.registerURLStreamHandlerFactoryModule(Module.getBootModuleLoader().loadModule(ModuleIdentifier.create("org.jboss.vfs")));
2.程序过程如下:
2.1 初始化模块加载器(Module.getBootModuleLoader())
org.jboss.modules.LocalModuleLoader的构造方法:
/** * Construct a new instance, using the {@code module.path} system property or the {@code JAVA_MODULEPATH} environment variable * to get the list of module repository roots. */ public LocalModuleLoader() { final String modulePath = System.getProperty("module.path", System.getenv("JAVA_MODULEPATH")); if (modulePath == null) { //noinspection ZeroLengthArrayAllocation repoRoots = new File[0]; } else { repoRoots = getFiles(modulePath, 0, 0); } pathFilter = PathFilters.acceptAll(); }
在此时设置module.path路径的值为:/jboss-home/modules,我自己的路径为:D:\source\jboss-as-7.1.1.Final\modules
2. 2 加载模块:(loadModule(ModuleIdentifier.create("org.jboss.vfs"))
/** * Load a module based on an identifier. This method delegates to {@link #preloadModule(ModuleIdentifier)} and then * links the returned module if necessary. * * @param identifier The module identifier * @return The loaded Module * @throws ModuleLoadException if the Module can not be loaded */ public final Module loadModule(ModuleIdentifier identifier) throws ModuleLoadException { final Module module = preloadModule(identifier); if (module == null) { throw new ModuleNotFoundException(identifier.toString()); } module.relinkIfNecessary(); return module; }
2.2.1 预加载模块
/** * Preload a module based on an identifier. By default, no delegation is done and this method simply invokes * {@link #loadModuleLocal(ModuleIdentifier)}. A delegating module loader may delegate to the appropriate module * loader based on loader-specific criteria (via the {@link #preloadModule(ModuleIdentifier, ModuleLoader)} method). * * @param identifier the module identifier * @return the load result, or {@code null} if the module is not found * @throws ModuleLoadException if an error occurs */ protected Module preloadModule(ModuleIdentifier identifier) throws ModuleLoadException { return loadModuleLocal(identifier); }
2.2.2 加载本地模块
/** * 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); } } }
2.2.2.1 查找模块
protected ModuleSpec findModule(final ModuleIdentifier moduleIdentifier) throws ModuleLoadException { final String child = toPathString(moduleIdentifier); if (pathFilter.accept(child)) { for (File root : repoRoots) { final File file = new File(root, child); final File moduleXml = new File(file, "module.xml"); if (moduleXml.exists()) { return parseModuleInfoFile(moduleIdentifier, file, moduleXml); } } } throw new ModuleNotFoundException("Module " + moduleIdentifier + " is not found in " + this); }
2.2.2.1 解析模块
private ModuleSpec parseModuleInfoFile(final ModuleIdentifier moduleIdentifier, final File moduleRoot, final File moduleInfoFile) throws ModuleLoadException {
return ModuleXmlParser.parseModuleXml(moduleIdentifier, moduleRoot, moduleInfoFile);
}
static ModuleSpec parseModuleXml(final ModuleIdentifier moduleIdentifier, final File root, final File moduleInfoFile) throws ModuleLoadException { final FileInputStream fis; try { fis = new FileInputStream(moduleInfoFile); } catch (FileNotFoundException e) { throw new ModuleLoadException("No module.xml file found at " + moduleInfoFile); } try { return parseModuleXml(new ResourceRootFactory() { public ResourceLoader createResourceLoader(final String rootPath, final String loaderPath, final String loaderName) throws IOException { File file = new File(rootPath, loaderPath); if (file.isDirectory()) { return new FileResourceLoader(loaderName, file); } else { final JarFile jarFile = new JarFile(file, true); return new JarFileResourceLoader(loaderName, jarFile); } } }, root.getPath(), new BufferedInputStream(fis), moduleInfoFile.getPath(), moduleIdentifier); } finally { safeClose(fis); } }
static ModuleSpec parseModuleXml(final ResourceRootFactory factory, final String rootPath, InputStream source, final String moduleInfoFile, final ModuleIdentifier moduleIdentifier) throws ModuleLoadException { try { final XMLInputFactory inputFactory = INPUT_FACTORY; setIfSupported(inputFactory, XMLInputFactory.IS_VALIDATING, Boolean.FALSE); setIfSupported(inputFactory, XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); final XMLStreamReader streamReader = inputFactory.createXMLStreamReader(source); try { return parseDocument(factory, rootPath, streamReader, moduleIdentifier); } finally { safeClose(streamReader); } } catch (XMLStreamException e) { throw new ModuleLoadException("Error loading module from " + moduleInfoFile, e); } }
private static ModuleSpec parseDocument(final ResourceRootFactory factory, final String rootPath, XMLStreamReader reader, final ModuleIdentifier moduleIdentifier) throws XMLStreamException { while (reader.hasNext()) { switch (reader.nextTag()) { case START_DOCUMENT: { return parseRootElement(factory, rootPath, reader, moduleIdentifier); } case START_ELEMENT: { final Element element = Element.of(reader.getName()); switch (element) { case MODULE: { final ModuleSpec.Builder specBuilder = ModuleSpec.build(moduleIdentifier); parseModuleContents(factory, rootPath, reader, specBuilder); parseEndDocument(reader); return specBuilder.create(); } case MODULE_ALIAS: { final ModuleSpec moduleSpec = parseModuleAliasContents(reader, moduleIdentifier); parseEndDocument(reader); return moduleSpec; } default: { throw unexpectedContent(reader); } } } default: { throw unexpectedContent(reader); } } } throw endOfDocument(reader.getLocation()); }
private static void parseModuleContents(final ResourceRootFactory factory, final String rootPath, final XMLStreamReader reader, final ModuleSpec.Builder specBuilder) throws XMLStreamException { final int count = reader.getAttributeCount(); String name = null; String slot = null; final Set<Attribute> required = EnumSet.of(Attribute.NAME); for (int i = 0; i < count; i ++) { final Attribute attribute = Attribute.of(reader.getAttributeName(i)); required.remove(attribute); switch (attribute) { case NAME: name = reader.getAttributeValue(i); break; case SLOT: slot = reader.getAttributeValue(i); break; default: throw unexpectedContent(reader); } } if (! required.isEmpty()) { throw missingAttributes(reader.getLocation(), required); } if (! specBuilder.getIdentifier().equals(ModuleIdentifier.create(name, slot))) { throw invalidModuleName(reader.getLocation(), specBuilder.getIdentifier()); } // xsd:all MultiplePathFilterBuilder exportsBuilder = PathFilters.multiplePathFilterBuilder(true); Set<Element> visited = EnumSet.noneOf(Element.class); while (reader.hasNext()) { switch (reader.nextTag()) { case END_ELEMENT: { specBuilder.addDependency(DependencySpec.createLocalDependencySpec(PathFilters.acceptAll(), exportsBuilder.create())); return; } case START_ELEMENT: { final Element element = Element.of(reader.getName()); if (visited.contains(element)) { throw unexpectedContent(reader); } visited.add(element); switch (element) { case EXPORTS: parseFilterList(reader, exportsBuilder); break; case DEPENDENCIES: parseDependencies(reader, specBuilder); break; case MAIN_CLASS: parseMainClass(reader, specBuilder); break; case RESOURCES: parseResources(factory, rootPath, reader, specBuilder); break; case PROPERTIES: parseProperties(reader, specBuilder); break; default: throw unexpectedContent(reader); } break; } default: { throw unexpectedContent(reader); } } } throw endOfDocument(reader.getLocation()); }