redefineModule
public interface Instrumentation {
boolean isModifiableModule(Module module);
void redefineModule (Module module,
Set<Module> extraReads,
Map<String, Set<Module>> extraExports,
Map<String, Set<Module>> extraOpens,
Set<Class<?>> extraUses,
Map<Class<?>, List<Class<?>>> extraProvides);
}
isModifiableModule
: Tests whether a module can be modified withredefineModule
.redefineModule
: Redefine a module to expand the set of modules that it reads, the set of packages that it exports or opens, or the services that it uses or provides.
示例
Application
package sample;
import java.lang.instrument.Instrumentation;
public class Program {
public static void main(String[] args) {
Module baseModule = Object.class.getModule();
Module instrumentModule = Instrumentation.class.getModule();
boolean canRead = baseModule.canRead(instrumentModule);
String message = String.format("%s can read %s: %s", baseModule.getName(), instrumentModule.getName(), canRead);
System.out.println(message);
}
}
Agent Jar
package lsieun.agent;
import java.lang.instrument.Instrumentation;
import java.util.Map;
import java.util.Set;
public class LoadTimeAgent {
public static void premain(String agentArgs, Instrumentation inst) {
// 第一步,打印信息
System.out.println("Premain-Class: " + LoadTimeAgent.class.getName());
System.out.println("Can-Redefine-Classes: " + inst.isRedefineClassesSupported());
System.out.println("Can-Retransform-Classes: " + inst.isRetransformClassesSupported());
System.out.println("Can-Set-Native-Method-Prefix: " + inst.isNativeMethodPrefixSupported());
System.out.println("========= ========= =========");
// 第二步,判断一个 module 是否可以读取另一个 module
Module baseModule = Object.class.getModule();
Module instrumentModule = Instrumentation.class.getModule();
boolean canRead = baseModule.canRead(instrumentModule);
// 第三步,使用 inst:修改 module 权限
if (!canRead && inst.isModifiableModule(baseModule)) {
Set<Module> extraReads = Set.of(instrumentModule);
inst.redefineModule(baseModule, extraReads, Map.of(), Map.of(), Set.of(), Map.of());
}
}
}
Run
None
$ java -cp ./target/classes/ sample.Program
java.base can read java.instrument: false
Load-Time
$ java -cp ./target/classes/ -javaagent:./target/TheAgent.jar sample.Program
Premain-Class: lsieun.agent.LoadTimeAgent
Can-Redefine-Classes: true
Can-Retransform-Classes: true
Can-Set-Native-Method-Prefix: true
========= ========= =========
java.base can read java.instrument: true
总结
本文内容总结如下:
- 第一点,
redefineModule
方法的作用是对 module 的访问权限进行修改,该方法是在 Java 9 引入的。