/*
 * Copyright 2014 - 2020 Rafael Winterhalter
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.bytebuddy.utility;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
import net.bytebuddy.description.NamedElement;
import net.bytebuddy.description.annotation.AnnotationList;
import net.bytebuddy.description.annotation.AnnotationSource;
import net.bytebuddy.description.type.PackageDescription;

import java.io.InputStream;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;

Type-safe representation of a java.lang.Module. On platforms that do not support the module API, modules are represented by null.
/** * Type-safe representation of a {@code java.lang.Module}. On platforms that do not support the module API, modules are represented by {@code null}. */
public class JavaModule implements NamedElement.WithOptionalName, AnnotationSource {
Canonical representation of a Java module on a JVM that does not support the module API.
/** * Canonical representation of a Java module on a JVM that does not support the module API. */
public static final JavaModule UNSUPPORTED = null;
The dispatcher to use for accessing Java modules, if available.
/** * The dispatcher to use for accessing Java modules, if available. */
private static final Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE);
The java.lang.Module instance this wrapper represents.
/** * The {@code java.lang.Module} instance this wrapper represents. */
private final AnnotatedElement module;
Creates a new Java module representation.
Params:
  • module – The java.lang.Module instance this wrapper represents.
/** * Creates a new Java module representation. * * @param module The {@code java.lang.Module} instance this wrapper represents. */
protected JavaModule(AnnotatedElement module) { this.module = module; }
Returns a representation of the supplied type's java.lang.Module or null if the current VM does not support modules.
Params:
  • type – The type for which to describe the module.
Returns:A representation of the type's module or null if the current VM does not support modules.
/** * Returns a representation of the supplied type's {@code java.lang.Module} or {@code null} if the current VM does not support modules. * * @param type The type for which to describe the module. * @return A representation of the type's module or {@code null} if the current VM does not support modules. */
public static JavaModule ofType(Class<?> type) { return DISPATCHER.moduleOf(type); }
Represents the supplied java.lang.Module as an instance of this class and validates that the supplied instance really represents a Java Module.
Params:
  • module – The module to represent.
Returns:A representation of the supplied Java module.
/** * Represents the supplied {@code java.lang.Module} as an instance of this class and validates that the * supplied instance really represents a Java {@code Module}. * * @param module The module to represent. * @return A representation of the supplied Java module. */
public static JavaModule of(Object module) { if (!JavaType.MODULE.isInstance(module)) { throw new IllegalArgumentException("Not a Java module: " + module); } return new JavaModule((AnnotatedElement) module); }
Checks if the current VM supports the java.lang.Module API.
Returns:true if the current VM supports modules.
/** * Checks if the current VM supports the {@code java.lang.Module} API. * * @return {@code true} if the current VM supports modules. */
public static boolean isSupported() { return DISPATCHER.isAlive(); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isNamed() { return DISPATCHER.isNamed(module); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getActualName() { return DISPATCHER.getName(module); }
Returns a resource stream for this module for a resource of the given name or null if such a resource does not exist.
Params:
  • name – The name of the resource.
Returns:An input stream for the resource or null if it does not exist.
/** * Returns a resource stream for this module for a resource of the given name or {@code null} if such a resource does not exist. * * @param name The name of the resource. * @return An input stream for the resource or {@code null} if it does not exist. */
public InputStream getResourceAsStream(String name) { return DISPATCHER.getResourceAsStream(module, name); }
Returns the class loader of this module.
Returns:The class loader of the represented module.
/** * Returns the class loader of this module. * * @return The class loader of the represented module. */
public ClassLoader getClassLoader() { return DISPATCHER.getClassLoader(module); }
Unwraps this instance to a java.lang.Module.
Returns:The represented java.lang.Module.
/** * Unwraps this instance to a {@code java.lang.Module}. * * @return The represented {@code java.lang.Module}. */
public Object unwrap() { return module; }
Checks if this module can read the exported packages of the supplied module.
Params:
  • module – The module to check for its readability by this module.
Returns:true if this module can read the supplied module.
/** * Checks if this module can read the exported packages of the supplied module. * * @param module The module to check for its readability by this module. * @return {@code true} if this module can read the supplied module. */
public boolean canRead(JavaModule module) { return DISPATCHER.canRead(this.module, module.unwrap()); }
Returns true if this module exports the supplied package to this module.
Params:
  • packageDescription – The package to check for
  • module – The target module.
Returns:true if this module exports the supplied package to this module.
/** * Returns {@code true} if this module exports the supplied package to this module. * * @param packageDescription The package to check for * @param module The target module. * @return {@code true} if this module exports the supplied package to this module. */
public boolean isExported(PackageDescription packageDescription, JavaModule module) { return packageDescription == null || DISPATCHER.isExported(this.module, module.unwrap(), packageDescription.getName()); }
Returns true if this module opens the supplied package to this module.
Params:
  • packageDescription – The package to check for.
  • module – The target module.
Returns:true if this module opens the supplied package to this module.
/** * Returns {@code true} if this module opens the supplied package to this module. * * @param packageDescription The package to check for. * @param module The target module. * @return {@code true} if this module opens the supplied package to this module. */
public boolean isOpened(PackageDescription packageDescription, JavaModule module) { return packageDescription == null || DISPATCHER.isOpened(this.module, module.unwrap(), packageDescription.getName()); }
{@inheritDoc}
/** * {@inheritDoc} */
public AnnotationList getDeclaredAnnotations() { return new AnnotationList.ForLoadedAnnotations(module.getDeclaredAnnotations()); }
Modifies this module's properties.
Params:
  • instrumentation – The instrumentation instace to use for applying the modification.
  • reads – A set of additional modules this module should read.
  • exports – A map of packages to export to a set of modules.
  • opens – A map of packages to open to a set of modules.
  • uses – A set of provider interfaces to use by this module.
  • provides – A map of provider interfaces to provide by this module mapped to the provider implementations.
/** * Modifies this module's properties. * * @param instrumentation The instrumentation instace to use for applying the modification. * @param reads A set of additional modules this module should read. * @param exports A map of packages to export to a set of modules. * @param opens A map of packages to open to a set of modules. * @param uses A set of provider interfaces to use by this module. * @param provides A map of provider interfaces to provide by this module mapped to the provider implementations. */
public void modify(Instrumentation instrumentation, Set<JavaModule> reads, Map<String, Set<JavaModule>> exports, Map<String, Set<JavaModule>> opens, Set<Class<?>> uses, Map<Class<?>, List<Class<?>>> provides) { Set<Object> unwrappedReads = new HashSet<Object>(); for (JavaModule read : reads) { unwrappedReads.add(read.unwrap()); } Map<String, Set<Object>> unwrappedExports = new HashMap<String, Set<Object>>(); for (Map.Entry<String, Set<JavaModule>> entry : exports.entrySet()) { Set<Object> modules = new HashSet<Object>(); for (JavaModule module : entry.getValue()) { modules.add(module.unwrap()); } unwrappedExports.put(entry.getKey(), modules); } Map<String, Set<Object>> unwrappedOpens = new HashMap<String, Set<Object>>(); for (Map.Entry<String, Set<JavaModule>> entry : opens.entrySet()) { Set<Object> modules = new HashSet<Object>(); for (JavaModule module : entry.getValue()) { modules.add(module.unwrap()); } unwrappedOpens.put(entry.getKey(), modules); } DISPATCHER.modify(instrumentation, module, unwrappedReads, unwrappedExports, unwrappedOpens, uses, provides); } @Override public int hashCode() { return module.hashCode(); } @Override public boolean equals(Object other) { if (this == other) { return true; } else if (!(other instanceof JavaModule)) { return false; } JavaModule javaModule = (JavaModule) other; return module.equals(javaModule.module); } @Override public String toString() { return module.toString(); }
A dispatcher for accessing the java.lang.Module API if it is available on the current VM.
/** * A dispatcher for accessing the {@code java.lang.Module} API if it is available on the current VM. */
protected interface Dispatcher {
Checks if this dispatcher is alive, i.e. supports modules.
Returns:true if modules are supported on the current VM.
/** * Checks if this dispatcher is alive, i.e. supports modules. * * @return {@code true} if modules are supported on the current VM. */
boolean isAlive();
Extracts the Java Module for the provided class or returns null if the current VM does not support modules.
Params:
  • type – The type for which to extract the module.
Returns:The class's Module or null if the current VM does not support modules.
/** * Extracts the Java {@code Module} for the provided class or returns {@code null} if the current VM does not support modules. * * @param type The type for which to extract the module. * @return The class's {@code Module} or {@code null} if the current VM does not support modules. */
JavaModule moduleOf(Class<?> type);
Returns true if the supplied module is named.
Params:
  • module – The java.lang.Module to check for the existence of a name.
Returns:true if the supplied module is named.
/** * Returns {@code true} if the supplied module is named. * * @param module The {@code java.lang.Module} to check for the existence of a name. * @return {@code true} if the supplied module is named. */
boolean isNamed(Object module);
Returns the module's name.
Params:
  • module – The java.lang.Module to check for its name.
Returns:The module's (implicit or explicit) name.
/** * Returns the module's name. * * @param module The {@code java.lang.Module} to check for its name. * @return The module's (implicit or explicit) name. */
String getName(Object module);
Returns a resource stream for this module for a resource of the given name or null if such a resource does not exist.
Params:
  • module – The java.lang.Module instance to apply this method upon.
  • name – The name of the resource.
Returns:An input stream for the resource or null if it does not exist.
/** * Returns a resource stream for this module for a resource of the given name or {@code null} if such a resource does not exist. * * @param module The {@code java.lang.Module} instance to apply this method upon. * @param name The name of the resource. * @return An input stream for the resource or {@code null} if it does not exist. */
InputStream getResourceAsStream(Object module, String name);
Returns the module's class loader.
Params:
  • module – The java.lang.Module
Returns:The module's class loader.
/** * Returns the module's class loader. * * @param module The {@code java.lang.Module} * @return The module's class loader. */
ClassLoader getClassLoader(Object module);
Returns true if the source module exports the supplied package to the target module.
Params:
  • source – The source module.
  • target – The target module.
  • aPackage – The name of the package to check.
Returns:true if the source module exports the supplied package to the target module.
/** * Returns {@code true} if the source module exports the supplied package to the target module. * * @param source The source module. * @param target The target module. * @param aPackage The name of the package to check. * @return {@code true} if the source module exports the supplied package to the target module. */
boolean isExported(Object source, Object target, String aPackage);
Returns true if the source module opens the supplied package to the target module.
Params:
  • source – The source module.
  • target – The target module.
  • aPackage – The name of the package to check.
Returns:true if the source module opens the supplied package to the target module.
/** * Returns {@code true} if the source module opens the supplied package to the target module. * * @param source The source module. * @param target The target module. * @param aPackage The name of the package to check. * @return {@code true} if the source module opens the supplied package to the target module. */
boolean isOpened(Object source, Object target, String aPackage);
Checks if the source module can read the target module.
Params:
  • source – The source module.
  • target – The target module.
Returns:true if the source module can read the target module.
/** * Checks if the source module can read the target module. * * @param source The source module. * @param target The target module. * @return {@code true} if the source module can read the target module. */
boolean canRead(Object source, Object target);
Modifies this module's properties.
Params:
  • instrumentation – The instrumentation instace to use for applying the modification.
  • module – The module to modify.
  • reads – A set of additional modules this module should read.
  • exports – A map of packages to export to a set of modules.
  • opens – A map of packages to open to a set of modules.
  • uses – A set of provider interfaces to use by this module.
  • provides – A map of provider interfaces to provide by this module mapped to the provider implementations.
/** * Modifies this module's properties. * * @param instrumentation The instrumentation instace to use for applying the modification. * @param module The module to modify. * @param reads A set of additional modules this module should read. * @param exports A map of packages to export to a set of modules. * @param opens A map of packages to open to a set of modules. * @param uses A set of provider interfaces to use by this module. * @param provides A map of provider interfaces to provide by this module mapped to the provider implementations. */
void modify(Instrumentation instrumentation, Object module, Set<Object> reads, Map<String, Set<Object>> exports, Map<String, Set<Object>> opens, Set<Class<?>> uses, Map<Class<?>, List<Class<?>>> provides);
A creation action for a dispatcher.
/** * A creation action for a dispatcher. */
enum CreationAction implements PrivilegedAction<Dispatcher> {
The singleton instance.
/** * The singleton instance. */
INSTANCE;
{@inheritDoc}
/** * {@inheritDoc} */
@SuppressFBWarnings(value = "REC_CATCH_EXCEPTION", justification = "Exception should not be rethrown but trigger a fallback") public Dispatcher run() { try { Class<?> module = Class.forName("java.lang.Module", false, null); // e.g. Netbeans contains a comilation target proxy try { Class<?> instrumentation = Class.forName("java.lang.instrument.Instrumentation"); return new Dispatcher.Enabled.WithInstrumentationSupport(Class.class.getMethod("getModule"), module.getMethod("getClassLoader"), module.getMethod("isNamed"), module.getMethod("getName"), module.getMethod("getResourceAsStream", String.class), module.getMethod("isExported", String.class, module), module.getMethod("isOpen", String.class, module), module.getMethod("canRead", module), instrumentation.getMethod("isModifiableModule", module), instrumentation.getMethod("redefineModule", module, Set.class, Map.class, Map.class, Set.class, Map.class)); } catch (ClassNotFoundException ignored) { return new Dispatcher.Enabled.WithoutInstrumentationSupport(Class.class.getMethod("getModule"), module.getMethod("getClassLoader"), module.getMethod("isNamed"), module.getMethod("getName"), module.getMethod("getResourceAsStream", String.class), module.getMethod("isExported", String.class, module), module.getMethod("isOpen", String.class, module), module.getMethod("canRead", module)); } } catch (ClassNotFoundException ignored) { return Dispatcher.Disabled.INSTANCE; } catch (NoSuchMethodException ignored) { return Dispatcher.Disabled.INSTANCE; } } }
A dispatcher for a VM that does support the java.lang.Module API.
/** * A dispatcher for a VM that does support the {@code java.lang.Module} API. */
@HashCodeAndEqualsPlugin.Enhance abstract class Enabled implements Dispatcher {
An empty array that can be used to indicate no arguments to avoid an allocation on a reflective call.
/** * An empty array that can be used to indicate no arguments to avoid an allocation on a reflective call. */
private static final Object[] NO_ARGUMENTS = new Object[0];
The java.lang.Class#getModule() method.
/** * The {@code java.lang.Class#getModule()} method. */
private final Method getModule;
The java.lang.Module#getClassLoader() method.
/** * The {@code java.lang.Module#getClassLoader()} method. */
private final Method getClassLoader;
The java.lang.Module#isNamed() method.
/** * The {@code java.lang.Module#isNamed()} method. */
private final Method isNamed;
The java.lang.Module#getName() method.
/** * The {@code java.lang.Module#getName()} method. */
private final Method getName;
The java.lang.Module#getResourceAsStream(String) method.
/** * The {@code java.lang.Module#getResourceAsStream(String)} method. */
private final Method getResourceAsStream;
The java.lang.Module#isExported(String,Module) method.
/** * The {@code java.lang.Module#isExported(String,Module)} method. */
private final Method isExported;
The java.lang.Module#isOpened(String,Module) method.
/** * The {@code java.lang.Module#isOpened(String,Module)} method. */
private final Method isOpened;
The java.lang.Module#canRead(Module) method.
/** * The {@code java.lang.Module#canRead(Module)} method. */
private final Method canRead;
Creates an enabled dispatcher.
Params:
  • getModule – The java.lang.Class#getModule() method.
  • getClassLoader – The java.lang.Module#getClassLoader() method.
  • isNamed – The java.lang.Module#isNamed() method.
  • getName – The java.lang.Module#getName() method.
  • getResourceAsStream – The java.lang.Module#getResourceAsStream(String) method.
  • isExported – The java.lang.Module#isExported(String,Module) method.
  • isOpened – The java.lang.Module#isOpened(String,Module) method.
  • canRead – The java.lang.Module#canRead(Module) method.
/** * Creates an enabled dispatcher. * * @param getModule The {@code java.lang.Class#getModule()} method. * @param getClassLoader The {@code java.lang.Module#getClassLoader()} method. * @param isNamed The {@code java.lang.Module#isNamed()} method. * @param getName The {@code java.lang.Module#getName()} method. * @param getResourceAsStream The {@code java.lang.Module#getResourceAsStream(String)} method. * @param isExported The {@code java.lang.Module#isExported(String,Module)} method. * @param isOpened The {@code java.lang.Module#isOpened(String,Module)} method. * @param canRead The {@code java.lang.Module#canRead(Module)} method. */
protected Enabled(Method getModule, Method getClassLoader, Method isNamed, Method getName, Method getResourceAsStream, Method isExported, Method isOpened, Method canRead) { this.getModule = getModule; this.getClassLoader = getClassLoader; this.isNamed = isNamed; this.getName = getName; this.getResourceAsStream = getResourceAsStream; this.isExported = isExported; this.isOpened = isOpened; this.canRead = canRead; }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isAlive() { return true; }
{@inheritDoc}
/** * {@inheritDoc} */
public JavaModule moduleOf(Class<?> type) { try { return new JavaModule((AnnotatedElement) getModule.invoke(type, NO_ARGUMENTS)); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getModule, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getModule, exception.getCause()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public InputStream getResourceAsStream(Object module, String name) { try { return (InputStream) getResourceAsStream.invoke(module, name); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getResourceAsStream, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getResourceAsStream, exception.getCause()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public ClassLoader getClassLoader(Object module) { try { return (ClassLoader) getClassLoader.invoke(module, NO_ARGUMENTS); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getClassLoader, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getClassLoader, exception.getCause()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isNamed(Object module) { try { return (Boolean) isNamed.invoke(module, NO_ARGUMENTS); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + isNamed, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + isNamed, exception.getCause()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public String getName(Object module) { try { return (String) getName.invoke(module, NO_ARGUMENTS); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + getName, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + getName, exception.getCause()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isExported(Object source, Object target, String aPackage) { try { return (Boolean) isExported.invoke(source, aPackage, target); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + isExported, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + isExported, exception.getCause()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isOpened(Object source, Object target, String aPackage) { try { return (Boolean) isOpened.invoke(source, aPackage, target); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + isOpened, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + isOpened, exception.getCause()); } }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean canRead(Object source, Object target) { try { return (Boolean) canRead.invoke(source, target); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + canRead, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + canRead, exception.getCause()); } }
A dispatcher for a VM that does support the java.lang.Module API and that does not support Instrumentation.
/** * A dispatcher for a VM that does support the {@code java.lang.Module} API and that does not support {@link Instrumentation}. */
protected static class WithoutInstrumentationSupport extends Enabled {
Creates an enabled dispatcher without support for Instrumentation.
Params:
  • getModule – The java.lang.Class#getModule() method.
  • getClassLoader – The java.lang.Module#getClassLoader() method.
  • isNamed – The java.lang.Module#isNamed() method.
  • getName – The java.lang.Module#getName() method.
  • getResourceAsStream – The java.lang.Module#getResourceAsStream(String) method.
  • isExported – The java.lang.Module#isExported(String,Module) method.
  • isOpened – The java.lang.Module#isOpened(String,Module) method.
  • canRead – The java.lang.Module#canRead(Module) method.
/** * Creates an enabled dispatcher without support for {@link Instrumentation}. * * @param getModule The {@code java.lang.Class#getModule()} method. * @param getClassLoader The {@code java.lang.Module#getClassLoader()} method. * @param isNamed The {@code java.lang.Module#isNamed()} method. * @param getName The {@code java.lang.Module#getName()} method. * @param getResourceAsStream The {@code java.lang.Module#getResourceAsStream(String)} method. * @param isExported The {@code java.lang.Module#isExported(String,Module)} method. * @param isOpened The {@code java.lang.Module#isOpened(String,Module)} method. * @param canRead The {@code java.lang.Module#canRead(Module)} method. */
protected WithoutInstrumentationSupport(Method getModule, Method getClassLoader, Method isNamed, Method getName, Method getResourceAsStream, Method isExported, Method isOpened, Method canRead) { super(getModule, getClassLoader, isNamed, getName, getResourceAsStream, isExported, isOpened, canRead); }
{@inheritDoc}
/** * {@inheritDoc} */
public void modify(Instrumentation instrumentation, Object source, Set<Object> reads, Map<String, Set<Object>> exports, Map<String, Set<Object>> opens, Set<Class<?>> uses, Map<Class<?>, List<Class<?>>> provides) { throw new IllegalStateException("Did not expect use of instrumentation"); } }
A dispatcher for a VM that does support the java.lang.Module API and that supports Instrumentation.
/** * A dispatcher for a VM that does support the {@code java.lang.Module} API and that supports {@link Instrumentation}. */
protected static class WithInstrumentationSupport extends Enabled {
The java.lang.instrument.Instrumentation#isModifiableModule method.
/** * The {@code java.lang.instrument.Instrumentation#isModifiableModule} method. */
private final Method isModifiableModule;
The java.lang.instrument.Instrumentation#redefineModule method.
/** * The {@code java.lang.instrument.Instrumentation#redefineModule} method. */
private final Method redefineModule;
Creates an enabled dispatcher.
Params:
  • getModule – The java.lang.Class#getModule() method.
  • getClassLoader – The java.lang.Module#getClassLoader() method.
  • isNamed – The java.lang.Module#isNamed() method.
  • getName – The java.lang.Module#getName() method.
  • getResourceAsStream – The java.lang.Module#getResourceAsStream(String) method.
  • isExported – The java.lang.Module#isExported(String,Module) method.
  • isOpened – The java.lang.Module#isOpened(String,Module) method.
  • canRead – The java.lang.Module#canRead(Module) method.
  • isModifiableModule – The java.lang.instrument.Instrumentation#isModifiableModule method.
  • redefineModule – The java.lang.instrument.Instrumentation#redefineModule method.
/** * Creates an enabled dispatcher. * * @param getModule The {@code java.lang.Class#getModule()} method. * @param getClassLoader The {@code java.lang.Module#getClassLoader()} method. * @param isNamed The {@code java.lang.Module#isNamed()} method. * @param getName The {@code java.lang.Module#getName()} method. * @param getResourceAsStream The {@code java.lang.Module#getResourceAsStream(String)} method. * @param isExported The {@code java.lang.Module#isExported(String,Module)} method. * @param isOpened The {@code java.lang.Module#isOpened(String,Module)} method. * @param canRead The {@code java.lang.Module#canRead(Module)} method. * @param isModifiableModule The {@code java.lang.instrument.Instrumentation#isModifiableModule} method. * @param redefineModule The {@code java.lang.instrument.Instrumentation#redefineModule} method. */
protected WithInstrumentationSupport(Method getModule, Method getClassLoader, Method isNamed, Method getName, Method getResourceAsStream, Method isExported, Method isOpened, Method canRead, Method isModifiableModule, Method redefineModule) { super(getModule, getClassLoader, isNamed, getName, getResourceAsStream, isExported, isOpened, canRead); this.isModifiableModule = isModifiableModule; this.redefineModule = redefineModule; }
{@inheritDoc}
/** * {@inheritDoc} */
public void modify(Instrumentation instrumentation, Object source, Set<Object> reads, Map<String, Set<Object>> exports, Map<String, Set<Object>> opens, Set<Class<?>> uses, Map<Class<?>, List<Class<?>>> provides) { try { if (!(Boolean) isModifiableModule.invoke(instrumentation, source)) { throw new IllegalStateException(source + " is not modifiable"); } } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + redefineModule, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + redefineModule, exception.getCause()); } try { redefineModule.invoke(instrumentation, source, reads, exports, opens, uses, provides); } catch (IllegalAccessException exception) { throw new IllegalStateException("Cannot access " + redefineModule, exception); } catch (InvocationTargetException exception) { throw new IllegalStateException("Cannot invoke " + redefineModule, exception.getCause()); } } } }
A disabled dispatcher for a VM that does not support the java.lang.Module API.
/** * A disabled dispatcher for a VM that does not support the {@code java.lang.Module} API. */
enum Disabled implements Dispatcher {
The singleton instance.
/** * The singleton instance. */
INSTANCE;
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isAlive() { return false; }
{@inheritDoc}
/** * {@inheritDoc} */
public JavaModule moduleOf(Class<?> type) { return UNSUPPORTED; }
{@inheritDoc}
/** * {@inheritDoc} */
public ClassLoader getClassLoader(Object module) { throw new UnsupportedOperationException("Current VM does not support modules"); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isNamed(Object module) { throw new UnsupportedOperationException("Current VM does not support modules"); }
{@inheritDoc}
/** * {@inheritDoc} */
public String getName(Object module) { throw new UnsupportedOperationException("Current VM does not support modules"); }
{@inheritDoc}
/** * {@inheritDoc} */
public InputStream getResourceAsStream(Object module, String name) { throw new UnsupportedOperationException("Current VM does not support modules"); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isExported(Object source, Object target, String aPackage) { throw new UnsupportedOperationException("Current VM does not support modules"); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean isOpened(Object source, Object target, String aPackage) { throw new UnsupportedOperationException("Current VM does not support modules"); }
{@inheritDoc}
/** * {@inheritDoc} */
public boolean canRead(Object source, Object target) { throw new UnsupportedOperationException("Current VM does not support modules"); }
{@inheritDoc}
/** * {@inheritDoc} */
public void modify(Instrumentation instrumentation, Object module, Set<Object> reads, Map<String, Set<Object>> exports, Map<String, Set<Object>> opens, Set<Class<?>> uses, Map<Class<?>, List<Class<?>>> provides) { throw new UnsupportedOperationException("Current VM does not support modules"); } } } }