下面列出了怎么用java.lang.module.ModuleReader的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* 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) {
ModuleReader reader = moduleReaderFor(loadedModule.mref());
try {
// read class file
String rn = cn.replace('.', '/').concat(".class");
ByteBuffer bb = reader.read(rn).orElse(null);
if (bb == null) {
// class not found
return null;
}
try {
return defineClass(cn, bb, loadedModule.codeSource());
} finally {
reader.release(bb);
}
} catch (IOException ioe) {
// TBD on how I/O errors should be propagated
return null;
}
}
/**
* 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) {
// Return a null module reader to avoid a future class
// load attempting to open the module again.
return new NullModuleReader();
}
}
};
reader = moduleToReader.computeIfAbsent(mref, create);
}
return reader;
}
/**
* Creates a ModuleReference to a possibly-patched module
*/
private static ModuleReference newModule(ModuleInfo.Attributes attrs,
URI uri,
Supplier<ModuleReader> supplier,
ModulePatcher patcher,
HashSupplier hasher) {
ModuleReference mref = new ModuleReferenceImpl(attrs.descriptor(),
uri,
supplier,
null,
attrs.target(),
attrs.recordedHashes(),
hasher,
attrs.moduleResolution());
if (patcher != null)
mref = patcher.patchIfNeeded(mref);
return mref;
}
/**
* Constructs a new instance of this class.
*/
public ModuleReferenceImpl(ModuleDescriptor descriptor,
URI location,
Supplier<ModuleReader> readerSupplier,
ModulePatcher patcher,
ModuleTarget target,
ModuleHashes recordedHashes,
ModuleHashes.HashSupplier hasher,
ModuleResolution moduleResolution)
{
super(descriptor, Objects.requireNonNull(location));
this.location = location;
this.readerSupplier = readerSupplier;
this.patcher = patcher;
this.target = target;
this.recordedHashes = recordedHashes;
this.hasher = hasher;
this.moduleResolution = moduleResolution;
}
void add(ModuleDescriptor... descriptors) {
for (ModuleDescriptor descriptor: descriptors) {
String name = descriptor.name();
if (!namesToReference.containsKey(name)) {
//modules.add(descriptor);
URI uri = URI.create("module:/" + descriptor.name());
ModuleReference mref = new ModuleReference(descriptor, uri) {
@Override
public ModuleReader open() {
throw new UnsupportedOperationException();
}
};
namesToReference.put(name, mref);
}
}
}
/**
* 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) {
ModuleReader reader = moduleReaderFor(loadedModule.mref());
try {
// read class file
String rn = cn.replace('.', '/').concat(".class");
ByteBuffer bb = reader.read(rn).orElse(null);
if (bb == null) {
// class not found
return null;
}
try {
return defineClass(cn, bb, loadedModule.codeSource());
} finally {
reader.release(bb);
}
} catch (IOException ioe) {
// TBD on how I/O errors should be propagated
return null;
}
}
/**
* Creates a ModuleReference to a possibly-patched module
*/
private static ModuleReference newModule(ModuleInfo.Attributes attrs,
URI uri,
Supplier<ModuleReader> supplier,
ModulePatcher patcher,
HashSupplier hasher) {
ModuleReference mref = new ModuleReferenceImpl(attrs.descriptor(),
uri,
supplier,
null,
attrs.target(),
attrs.recordedHashes(),
hasher,
attrs.moduleResolution());
if (patcher != null)
mref = patcher.patchIfNeeded(mref);
return mref;
}
/**
* Constructs a new instance of this class.
*/
ModuleReferenceImpl(ModuleDescriptor descriptor,
URI location,
Supplier<ModuleReader> readerSupplier,
ModulePatcher patcher,
ModuleTarget target,
ModuleHashes recordedHashes,
ModuleHashes.HashSupplier hasher,
ModuleResolution moduleResolution)
{
super(descriptor, Objects.requireNonNull(location));
this.location = location;
this.readerSupplier = readerSupplier;
this.patcher = patcher;
this.target = target;
this.recordedHashes = recordedHashes;
this.hasher = hasher;
this.moduleResolution = moduleResolution;
}
public static void main(String[] args) throws Exception {
String mn = args[0];
ModuleReference mref = ModuleLayer.boot()
.configuration()
.findModule(mn)
.map(ResolvedModule::reference)
.orElseThrow(() -> new RuntimeException(mn + " not resolved!!"));
try (ModuleReader reader = mref.open()) {
reader.list().forEach(name -> {
testFindUnchecked(name);
// if the resource is a directory then find without trailing slash
if (name.endsWith("/")) {
testFindUnchecked(name.substring(0, name.length() - 1));
}
});
}
}
/**
* Test ModuleReader#find
*/
void testFind(ModuleReader reader, String name, byte[] expectedBytes)
throws IOException
{
Optional<URI> ouri = reader.find(name);
assertTrue(ouri.isPresent());
URL url = ouri.get().toURL();
if (!url.getProtocol().equalsIgnoreCase("jmod")) {
URLConnection uc = url.openConnection();
uc.setUseCaches(false);
try (InputStream in = uc.getInputStream()) {
byte[] bytes = in.readAllBytes();
assertTrue(Arrays.equals(bytes, expectedBytes));
}
}
}
/**
* Test ModuleReader#read
*/
void testRead(ModuleReader reader, String name, byte[] expectedBytes)
throws IOException
{
Optional<ByteBuffer> obb = reader.read(name);
assertTrue(obb.isPresent());
ByteBuffer bb = obb.get();
try {
int rem = bb.remaining();
assertTrue(rem == expectedBytes.length);
byte[] bytes = new byte[rem];
bb.get(bytes);
assertTrue(Arrays.equals(bytes, expectedBytes));
} finally {
reader.release(bb);
}
}
private static void scanManifest(String resource, ModuleReader reader, Map<String, Object> propertyMap) throws IOException {
try(var input = reader.open(resource).orElseThrow(() -> new IOException("resource unavailable " + resource));
var isr = new InputStreamReader(input, StandardCharsets.UTF_8);
var lineReader = new BufferedReader(isr)) {
lineReader.lines()
.flatMap(line -> {
int index = line.indexOf(':');
if (index == -1) {
return Stream.empty();
}
String key = line.substring(0, index);
String value = line.substring(index + 1).trim();
return extractManifestValue(key, value).map(object -> Map.entry(key, object)).stream();
})
.forEach(entry -> propertyMap.put(entry.getKey(), entry.getValue()));
}
}
private static void scanJavaClass(String resource, ModuleReader reader, Set<String> requirePackages, Set<String> exports, Set<String> uses) throws IOException {
try(var input = reader.open(resource).orElseThrow(() -> new IOException("resource unavailable " + resource))) {
var classReader = new ClassReader(input);
var className = classReader.getClassName();
if (className.equals("module-info")) {
return; // skip module-info
}
var packageName = packageOf(className);
exports.add(packageName);
classReader.accept(new ClassRemapper(EmptyClassVisitor.getInstance(), new Remapper() {
@Override
public String map(String typeName) {
String packageName = packageOf(typeName);
requirePackages.add(packageName);
return typeName;
}
}) {
String owner;
/**
* Creates a ModuleReader for the given module.
*/
private ModuleReader createModuleReader(ModuleReference mref) {
try {
return mref.open();
} catch (IOException e) {
// Return a null module reader to avoid a future class load
// attempting to open the module again.
return new NullModuleReader();
}
}
/**
* Creates a ModuleReference to a possibly-patched module in a modular JAR.
*/
static ModuleReference newJarModule(ModuleInfo.Attributes attrs,
ModulePatcher patcher,
Path file) {
URI uri = file.toUri();
Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
return newModule(attrs, uri, supplier, patcher, hasher);
}
/**
* Creates a ModuleReference to a module in a JMOD file.
*/
static ModuleReference newJModModule(ModuleInfo.Attributes attrs, Path file) {
URI uri = file.toUri();
Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
return newModule(attrs, uri, supplier, null, hasher);
}
/**
* Creates a ModuleReference to a possibly-patched exploded module.
*/
static ModuleReference newExplodedModule(ModuleInfo.Attributes attrs,
ModulePatcher patcher,
Path dir) {
Supplier<ModuleReader> supplier = () -> new ExplodedModuleReader(dir);
return newModule(attrs, dir.toUri(), supplier, patcher, null);
}
@Override
public ModuleReader open() throws IOException {
try {
return readerSupplier.get();
} catch (UncheckedIOException e) {
throw e.getCause();
}
}
/**
* Creates a ModuleReference to the system module.
*/
static ModuleReference toModuleReference(ModuleDescriptor descriptor,
ModuleTarget target,
ModuleHashes recordedHashes,
HashSupplier hasher,
ModuleResolution mres) {
String mn = descriptor.name();
URI uri = JNUA.create("jrt", "/".concat(mn));
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
@Override
public ModuleReader get() {
return new SystemModuleReader(mn, uri);
}
};
ModuleReference mref = new ModuleReferenceImpl(descriptor,
uri,
readerSupplier,
null,
target,
recordedHashes,
hasher,
mres);
// may need a reference to a patched module if --patch-module specified
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
return mref;
}
/**
* Returns the ModuleReader to delegate to when the resource is not
* found in a patch location.
*/
private ModuleReader delegate() throws IOException {
ModuleReader r = delegate;
if (r == null) {
synchronized (this) {
r = delegate;
if (r == null) {
delegate = r = mref.open();
}
}
}
return r;
}
/**
* Creates a ModuleReader for the given module.
*/
private ModuleReader createModuleReader(ModuleReference mref) {
try {
return mref.open();
} catch (IOException e) {
// Return a null module reader to avoid a future class load
// attempting to open the module again.
return new NullModuleReader();
}
}
/**
* Creates a ModuleReader for the given module.
*/
private static ModuleReader createModuleReader(ModuleReference mref) {
try {
return mref.open();
} catch (IOException e) {
// Return a null module reader to avoid a future class load
// attempting to open the module again.
return new NullModuleReader();
}
}
private ModuleReference toModuleReference(ModuleDescriptor md,
ModuleTarget target,
ModuleHashes recordedHashes,
HashSupplier hasher,
ModuleResolution mres) {
String mn = md.name();
URI uri = JNUA.create("jrt", "/".concat(mn));
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
@Override
public ModuleReader get() {
return new ImageModuleReader(mn, uri);
}
};
ModuleReference mref = new ModuleReferenceImpl(md,
uri,
readerSupplier,
null,
target,
recordedHashes,
hasher,
mres);
// may need a reference to a patched module if --patch-module specified
mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
return mref;
}
/**
* Creates a ModuleReference to a possibly-patched module in a modular JAR.
*/
static ModuleReference newJarModule(ModuleInfo.Attributes attrs,
ModulePatcher patcher,
Path file) {
URI uri = file.toUri();
Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
return newModule(attrs, uri, supplier, patcher, hasher);
}
/**
* Creates a ModuleReference to a module in a JMOD file.
*/
static ModuleReference newJModModule(ModuleInfo.Attributes attrs, Path file) {
URI uri = file.toUri();
Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
return newModule(attrs, uri, supplier, null, hasher);
}
/**
* Creates a ModuleReference to a possibly-patched exploded module.
*/
static ModuleReference newExplodedModule(ModuleInfo.Attributes attrs,
ModulePatcher patcher,
Path dir) {
Supplier<ModuleReader> supplier = () -> new ExplodedModuleReader(dir);
return newModule(attrs, dir.toUri(), supplier, patcher, null);
}
@Override
public ModuleReader open() throws IOException {
try {
return readerSupplier.get();
} catch (UncheckedIOException e) {
throw e.getCause();
}
}
/**
* Returns the ModuleReader to delegate to when the resource is not
* found in a patch location.
*/
private ModuleReader delegate() throws IOException {
ModuleReader r = delegate;
if (r == null) {
synchronized (this) {
r = delegate;
if (r == null) {
delegate = r = mref.open();
}
}
}
return r;
}
private static ModuleReference moduleReference(ModuleDescriptor desc) {
return new ModuleReference(desc, null) {
@Override
public ModuleReader open() {
throw new UnsupportedOperationException();
}
};
}
/**
* Test ModuleReader#open
*/
void testOpen(ModuleReader reader, String name, byte[] expectedBytes)
throws IOException
{
Optional<InputStream> oin = reader.open(name);
assertTrue(oin.isPresent());
InputStream in = oin.get();
try (in) {
byte[] bytes = in.readAllBytes();
assertTrue(Arrays.equals(bytes, expectedBytes));
}
}