use of java.lang.module.ModuleReference in project Bytecoder by mirkosertic.
the class BuiltinClassLoader method defineClass.
/**
* Defines the given binary class name to the VM, loading the class
* bytes from the given module.
*
* @return the resulting Class or {@code null} if an I/O error occurs
*/
private Class<?> defineClass(String cn, LoadedModule loadedModule) {
ModuleReference mref = loadedModule.mref();
ModuleReader reader = moduleReaderFor(mref);
try {
ByteBuffer bb = null;
URL csURL = null;
// locate class file, special handling for patched modules to
// avoid locating the resource twice
String rn = cn.replace('.', '/').concat(".class");
if (reader instanceof PatchedModuleReader) {
Resource r = ((PatchedModuleReader) reader).findResource(rn);
if (r != null) {
bb = r.getByteBuffer();
csURL = r.getCodeSourceURL();
}
} else {
bb = reader.read(rn).orElse(null);
csURL = loadedModule.codeSourceURL();
}
if (bb == null) {
// class not found
return null;
}
CodeSource cs = new CodeSource(csURL, (CodeSigner[]) null);
try {
// define class to VM
return defineClass(cn, bb, cs);
} finally {
reader.release(bb);
}
} catch (IOException ioe) {
// TBD on how I/O errors should be propagated
return null;
}
}
use of java.lang.module.ModuleReference in project Bytecoder by mirkosertic.
the class ModuleBootstrap method boot.
/**
* Initialize the module system, returning the boot layer.
*
* @see java.lang.System#initPhase2()
*/
public static ModuleLayer boot() throws Exception {
// Step 0: Command line options
long t0 = System.nanoTime();
ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
ModuleFinder appModulePath = finderFor("jdk.module.path");
boolean isPatched = patcher.hasPatches();
String mainModule = System.getProperty("jdk.module.main");
Set<String> addModules = addModules();
Set<String> limitModules = limitModules();
PrintStream traceOutput = null;
String trace = getAndRemoveProperty("jdk.module.showModuleResolution");
if (trace != null && Boolean.parseBoolean(trace))
traceOutput = System.out;
// Step 1: The observable system modules, either all system modules
// or the system modules pre-generated for the initial module (the
// initial module may be the unnamed module). If the system modules
// are pre-generated for the initial module then resolution can be
// skipped.
long t1 = System.nanoTime();
SystemModules systemModules = null;
ModuleFinder systemModuleFinder;
boolean haveModulePath = (appModulePath != null || upgradeModulePath != null);
boolean needResolution = true;
if (!haveModulePath && addModules.isEmpty() && limitModules.isEmpty()) {
systemModules = SystemModuleFinders.systemModules(mainModule);
if (systemModules != null && !isPatched && (traceOutput == null)) {
needResolution = false;
}
}
if (systemModules == null) {
// all system modules are observable
systemModules = SystemModuleFinders.allSystemModules();
}
if (systemModules != null) {
// images build
systemModuleFinder = SystemModuleFinders.of(systemModules);
} else {
// exploded build or testing
systemModules = new ExplodedSystemModules();
systemModuleFinder = SystemModuleFinders.ofSystem();
}
Counters.add("jdk.module.boot.1.systemModulesTime", t1);
// Step 2: Define and load java.base. This patches all classes loaded
// to date so that they are members of java.base. Once java.base is
// loaded then resources in java.base are available for error messages
// needed from here on.
long t2 = System.nanoTime();
ModuleReference base = systemModuleFinder.find(JAVA_BASE).orElse(null);
if (base == null)
throw new InternalError(JAVA_BASE + " not found");
URI baseUri = base.location().orElse(null);
if (baseUri == null)
throw new InternalError(JAVA_BASE + " does not have a location");
BootLoader.loadModule(base);
Modules.defineModule(null, base.descriptor(), baseUri);
Counters.add("jdk.module.boot.2.defineBaseTime", t2);
if (getAndRemoveProperty("jdk.module.validation") != null) {
return createBootLayerForValidation();
}
// Step 3: If resolution is needed then create the module finder and
// the set of root modules to resolve.
long t3 = System.nanoTime();
ModuleFinder savedModuleFinder = null;
ModuleFinder finder;
Set<String> roots;
if (needResolution) {
// upgraded modules override the modules in the run-time image
if (upgradeModulePath != null)
systemModuleFinder = ModuleFinder.compose(upgradeModulePath, systemModuleFinder);
// The module finder: [--upgrade-module-path] system [--module-path]
if (appModulePath != null) {
finder = ModuleFinder.compose(systemModuleFinder, appModulePath);
} else {
finder = systemModuleFinder;
}
// The root modules to resolve
roots = new HashSet<>();
// launcher -m option to specify the main/initial module
if (mainModule != null)
roots.add(mainModule);
// additional module(s) specified by --add-modules
boolean addAllDefaultModules = false;
boolean addAllSystemModules = false;
boolean addAllApplicationModules = false;
for (String mod : addModules) {
switch(mod) {
case ALL_DEFAULT:
addAllDefaultModules = true;
break;
case ALL_SYSTEM:
addAllSystemModules = true;
break;
case ALL_MODULE_PATH:
addAllApplicationModules = true;
break;
default:
roots.add(mod);
}
}
// --limit-modules
savedModuleFinder = finder;
if (!limitModules.isEmpty()) {
finder = limitFinder(finder, limitModules, roots);
}
// the default set of roots.
if (mainModule == null || addAllDefaultModules) {
roots.addAll(DefaultRoots.compute(systemModuleFinder, finder));
}
// modules will be resolved.
if (addAllSystemModules) {
// observable modules
ModuleFinder f = finder;
systemModuleFinder.findAll().stream().map(ModuleReference::descriptor).map(ModuleDescriptor::name).filter(// observable
mn -> f.find(mn).isPresent()).forEach(mn -> roots.add(mn));
}
// modules on the application module path will be resolved.
if (appModulePath != null && addAllApplicationModules) {
// observable modules
ModuleFinder f = finder;
appModulePath.findAll().stream().map(ModuleReference::descriptor).map(ModuleDescriptor::name).filter(// observable
mn -> f.find(mn).isPresent()).forEach(mn -> roots.add(mn));
}
} else {
// no resolution case
finder = systemModuleFinder;
roots = null;
}
Counters.add("jdk.module.boot.3.optionsAndRootsTime", t3);
// Step 4: Resolve the root modules, with service binding, to create
// the configuration for the boot layer. If resolution is not needed
// then create the configuration for the boot layer from the
// readability graph created at link time.
long t4 = System.nanoTime();
Configuration cf;
if (needResolution) {
cf = JLMA.resolveAndBind(finder, roots, traceOutput);
} else {
Map<String, Set<String>> map = systemModules.moduleReads();
cf = JLMA.newConfiguration(systemModuleFinder, map);
}
// check that modules specified to --patch-module are resolved
if (isPatched) {
patcher.patchedModules().stream().filter(mn -> !cf.findModule(mn).isPresent()).forEach(mn -> warnUnknownModule(PATCH_MODULE, mn));
}
Counters.add("jdk.module.boot.4.resolveTime", t4);
// Step 5: Map the modules in the configuration to class loaders.
// The static configuration provides the mapping of standard and JDK
// modules to the boot and platform loaders. All other modules (JDK
// tool modules, and both explicit and automatic modules on the
// application module path) are defined to the application class
// loader.
long t5 = System.nanoTime();
// mapping of modules to class loaders
Function<String, ClassLoader> clf = ModuleLoaderMap.mappingFunction(cf);
// loaded from the runtime image
if (haveModulePath) {
for (ResolvedModule resolvedModule : cf.modules()) {
ModuleReference mref = resolvedModule.reference();
String name = mref.descriptor().name();
ClassLoader cl = clf.apply(name);
if (cl == null) {
if (upgradeModulePath != null && upgradeModulePath.find(name).isPresent())
fail(name + ": cannot be loaded from upgrade module path");
if (!systemModuleFinder.find(name).isPresent())
fail(name + ": cannot be loaded from application module path");
}
}
}
// check for split packages in the modules mapped to the built-in loaders
if (systemModules.hasSplitPackages() || isPatched || haveModulePath) {
checkSplitPackages(cf, clf);
}
// load/register the modules with the built-in class loaders
loadModules(cf, clf);
Counters.add("jdk.module.boot.5.loadModulesTime", t5);
// Step 6: Define all modules to the VM
long t6 = System.nanoTime();
ModuleLayer bootLayer = ModuleLayer.empty().defineModules(cf, clf);
Counters.add("jdk.module.boot.6.layerCreateTime", t6);
// check incubating status
if (systemModules.hasIncubatorModules() || haveModulePath) {
checkIncubatingStatus(cf);
}
// --add-reads, --add-exports/--add-opens, and --illegal-access
long t7 = System.nanoTime();
addExtraReads(bootLayer);
boolean extraExportsOrOpens = addExtraExportsAndOpens(bootLayer);
addIllegalAccess(upgradeModulePath, systemModules, bootLayer, extraExportsOrOpens);
Counters.add("jdk.module.boot.7.adjustModulesTime", t7);
// save module finders for later use
if (savedModuleFinder != null) {
unlimitedFinder = new SafeModuleFinder(savedModuleFinder);
if (savedModuleFinder != finder)
limitedFinder = new SafeModuleFinder(finder);
}
// total time to initialize
Counters.add("jdk.module.boot.totalTime", t0);
Counters.publish();
return bootLayer;
}
use of java.lang.module.ModuleReference in project Bytecoder by mirkosertic.
the class Loader method findResource.
@Override
public URL findResource(String name) {
String pn = Resources.toPackageName(name);
LoadedModule module = localPackageToModule.get(pn);
if (module != null) {
try {
URL url = findResource(module.name(), name);
if (url != null && (name.endsWith(".class") || url.toString().endsWith("/") || isOpen(module.mref(), pn))) {
return url;
}
} catch (IOException ioe) {
// ignore
}
} else {
for (ModuleReference mref : nameToModule.values()) {
try {
URL url = findResource(mref.descriptor().name(), name);
if (url != null)
return url;
} catch (IOException ioe) {
// ignore
}
}
}
return null;
}
use of java.lang.module.ModuleReference in project Bytecoder by mirkosertic.
the class BuiltinClassLoader method findMiscResource.
/**
* Returns the list of URLs to a "miscellaneous" resource in modules
* defined to this loader. A miscellaneous resource is not in a module
* package, e.g. META-INF/services/p.S.
*
* The cache used by this method avoids repeated searching of all modules.
*/
private List<URL> findMiscResource(String name) throws IOException {
SoftReference<Map<String, List<URL>>> ref = this.resourceCache;
Map<String, List<URL>> map = (ref != null) ? ref.get() : null;
if (map == null) {
map = new ConcurrentHashMap<>();
this.resourceCache = new SoftReference<>(map);
} else {
List<URL> urls = map.get(name);
if (urls != null)
return urls;
}
// search all modules for the resource
List<URL> urls;
try {
urls = AccessController.doPrivileged(new PrivilegedExceptionAction<>() {
@Override
public List<URL> run() throws IOException {
List<URL> result = null;
for (ModuleReference mref : nameToModule.values()) {
URI u = moduleReaderFor(mref).find(name).orElse(null);
if (u != null) {
try {
if (result == null)
result = new ArrayList<>();
result.add(u.toURL());
} catch (MalformedURLException | IllegalArgumentException e) {
}
}
}
return (result != null) ? result : Collections.emptyList();
}
});
} catch (PrivilegedActionException pae) {
throw (IOException) pae.getCause();
}
// only cache resources after VM is fully initialized
if (VM.isModuleSystemInited()) {
map.putIfAbsent(name, urls);
}
return urls;
}
use of java.lang.module.ModuleReference in project Bytecoder by mirkosertic.
the class BuiltinClassLoader method moduleReaderFor.
// -- miscellaneous supporting methods
/**
* Returns the ModuleReader for the given module, creating it if needed
*/
private ModuleReader moduleReaderFor(ModuleReference mref) {
ModuleReader reader = moduleToReader.get(mref);
if (reader == null) {
// avoid method reference during startup
Function<ModuleReference, ModuleReader> create = new Function<>() {
public ModuleReader apply(ModuleReference moduleReference) {
try {
return mref.open();
} catch (IOException e) {
// load attempting to open the module again.
return new NullModuleReader();
}
}
};
reader = moduleToReader.computeIfAbsent(mref, create);
}
return reader;
}
Aggregations