use of java.lang.module.ModuleDescriptor in project Bytecoder by mirkosertic.
the class ModulePath method deriveModuleDescriptor.
/**
* Treat the given JAR file as a module as follows:
*
* 1. The value of the Automatic-Module-Name attribute is the module name
* 2. The version, and the module name when the Automatic-Module-Name
* attribute is not present, is derived from the file ame of the JAR file
* 3. All packages are derived from the .class files in the JAR file
* 4. The contents of any META-INF/services configuration files are mapped
* to "provides" declarations
* 5. The Main-Class attribute in the main attributes of the JAR manifest
* is mapped to the module descriptor mainClass if possible
*/
private ModuleDescriptor deriveModuleDescriptor(JarFile jf) throws IOException {
// Read Automatic-Module-Name attribute if present
Manifest man = jf.getManifest();
Attributes attrs = null;
String moduleName = null;
if (man != null) {
attrs = man.getMainAttributes();
if (attrs != null) {
moduleName = attrs.getValue(AUTOMATIC_MODULE_NAME);
}
}
// Derive the version, and the module name if needed, from JAR file name
String fn = jf.getName();
int i = fn.lastIndexOf(File.separator);
if (i != -1)
fn = fn.substring(i + 1);
// drop ".jar"
String name = fn.substring(0, fn.length() - 4);
String vs = null;
// find first occurrence of -${NUMBER}. or -${NUMBER}$
Matcher matcher = Patterns.DASH_VERSION.matcher(name);
if (matcher.find()) {
int start = matcher.start();
// attempt to parse the tail as a version string
try {
String tail = name.substring(start + 1);
ModuleDescriptor.Version.parse(tail);
vs = tail;
} catch (IllegalArgumentException ignore) {
}
name = name.substring(0, start);
}
// Create builder, using the name derived from file name when
// Automatic-Module-Name not present
Builder builder;
if (moduleName != null) {
try {
builder = ModuleDescriptor.newAutomaticModule(moduleName);
} catch (IllegalArgumentException e) {
throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
}
} else {
builder = ModuleDescriptor.newAutomaticModule(cleanModuleName(name));
}
// module version if present
if (vs != null)
builder.version(vs);
// scan the names of the entries in the JAR file
Map<Boolean, Set<String>> map = VersionedStream.stream(jf).filter(e -> !e.isDirectory()).map(JarEntry::getName).filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX))).collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX), Collectors.toSet()));
Set<String> classFiles = map.get(Boolean.FALSE);
Set<String> configFiles = map.get(Boolean.TRUE);
// the packages containing class files
Set<String> packages = classFiles.stream().map(this::toPackageName).flatMap(Optional::stream).distinct().collect(Collectors.toSet());
// all packages are exported and open
builder.packages(packages);
// map names of service configuration files to service names
Set<String> serviceNames = configFiles.stream().map(this::toServiceName).flatMap(Optional::stream).collect(Collectors.toSet());
// parse each service configuration file
for (String sn : serviceNames) {
JarEntry entry = jf.getJarEntry(SERVICES_PREFIX + sn);
List<String> providerClasses = new ArrayList<>();
try (InputStream in = jf.getInputStream(entry)) {
BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF-8"));
String cn;
while ((cn = nextLine(reader)) != null) {
if (cn.length() > 0) {
String pn = packageName(cn);
if (!packages.contains(pn)) {
String msg = "Provider class " + cn + " not in module";
throw new InvalidModuleDescriptorException(msg);
}
providerClasses.add(cn);
}
}
}
if (!providerClasses.isEmpty())
builder.provides(sn, providerClasses);
}
// Main-Class attribute if it exists
if (attrs != null) {
String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
if (mainClass != null) {
mainClass = mainClass.replace("/", ".");
if (Checks.isClassName(mainClass)) {
String pn = packageName(mainClass);
if (packages.contains(pn)) {
builder.mainClass(mainClass);
}
}
}
}
return builder.build();
}
use of java.lang.module.ModuleDescriptor in project Bytecoder by mirkosertic.
the class ModulePath method readJar.
/**
* Returns a {@code ModuleReference} to a module in modular JAR file on
* the file system.
*
* @throws IOException
* @throws FindException
* @throws InvalidModuleDescriptorException
*/
private ModuleReference readJar(Path file) throws IOException {
try (JarFile jf = new JarFile(file.toFile(), // verify
true, ZipFile.OPEN_READ, releaseVersion)) {
ModuleInfo.Attributes attrs;
JarEntry entry = jf.getJarEntry(MODULE_INFO);
if (entry == null) {
// no module-info.class so treat it as automatic module
try {
ModuleDescriptor md = deriveModuleDescriptor(jf);
attrs = new ModuleInfo.Attributes(md, null, null, null);
} catch (RuntimeException e) {
throw new FindException("Unable to derive module descriptor for " + jf.getName(), e);
}
} else {
attrs = ModuleInfo.read(jf.getInputStream(entry), () -> jarPackages(jf));
}
return ModuleReferences.newJarModule(attrs, patcher, file);
} catch (ZipException e) {
throw new FindException("Error reading " + file, e);
}
}
use of java.lang.module.ModuleDescriptor 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.ModuleDescriptor in project jboss-modules by jboss-modules.
the class JDKModuleFinder method findModule.
public ModuleSpec findModule(final String name, final ModuleLoader delegateLoader) {
final Set<String> packages;
final Module module;
if ("org.jboss.modules".equals(name)) {
module = getClass().getModule();
if (module.isNamed()) {
packages = module.getPackages();
} else {
packages = Set.of("org.jboss.modules", "org.jboss.modules.filter", "org.jboss.modules.log", "org.jboss.modules.management", "org.jboss.modules.maven", "org.jboss.modules.ref", "org.jboss.modules.security", "org.jboss.modules.xml");
}
} else {
final Optional<Module> moduleOptional = layer.findModule(name);
if (!moduleOptional.isPresent()) {
return null;
}
module = moduleOptional.get();
packages = module.getPackages();
}
final ModuleSpec.Builder builder = ModuleSpec.build(name);
final ModuleDescriptor descriptor = module.getDescriptor();
if (descriptor != null) {
final Optional<String> version = descriptor.rawVersion();
if (version.isPresent())
builder.setVersion(Version.parse(version.get()));
for (ModuleDescriptor.Requires require : descriptor.requires()) {
final Set<ModuleDescriptor.Requires.Modifier> modifiers = require.modifiers();
builder.addDependency(new ModuleDependencySpecBuilder().setName(require.name()).setExport(modifiers.contains(ModuleDescriptor.Requires.Modifier.TRANSITIVE)).setOptional(modifiers.contains(ModuleDescriptor.Requires.Modifier.STATIC)).build());
}
}
final Set<String> paths = new HashSet<>(packages.size());
for (String pkg : packages) {
paths.add(pkg.replace('.', '/'));
}
final LocalDependencySpecBuilder depBuilder = new LocalDependencySpecBuilder();
depBuilder.setLoaderPaths(paths);
depBuilder.setExport(true);
depBuilder.setLocalLoader(new JDKModuleLoader(module, packages));
builder.addDependency(depBuilder.build());
return builder.create();
}
use of java.lang.module.ModuleDescriptor in project openj9 by eclipse.
the class MyLoader method dumpModules.
private void dumpModules() {
HashSet<Option> opts = new HashSet<>(Arrays.asList(new Option[] { Option.RETAIN_CLASS_REFERENCE, Option.SHOW_HIDDEN_FRAMES, Option.SHOW_REFLECT_FRAMES }));
List<StackFrame> frameList = (StackWalker.getInstance(opts)).walk(s -> s.collect(Collectors.toList()));
for (StackFrame f : frameList) {
Module frameModule = f.getDeclaringClass().getModule();
if ((null != frameModule)) {
ModuleDescriptor d = frameModule.getDescriptor();
if (null != d) {
StackTraceElement e = f.toStackTraceElement();
String modName = d.name();
if (null != modName) {
assertEquals(modName, e.getModuleName(), "Wrong module name");
}
Optional<Version> modVersion = d.version();
if (modVersion.isPresent()) {
assertEquals(modVersion.get(), e.getModuleVersion(), "Wrong module version");
}
if (f.getDeclaringClass() == Thread.class) {
assertEquals("java.base", e.getModuleName(), "Wrong module name");
}
}
}
}
}
Aggregations