In the Javaagent
public boolean openModuleTo(Instrumentation instrumentation, Class<?> classFromTargetModule, ClassLoader openTo, Collection<String> packagesToOpen) {
Module targetModule = classFromTargetModule.getModule();
Module openToModule = openTo.getUnnamedModule();
Set<Module> openToModuleSet = Collections.singleton(openToModule);
Map<String, Set<Module>> missingOpens = new HashMap<>();
for (String packageName : packagesToOpen) {
if (!targetModule.isOpen(packageName, openToModule)) {
missingOpens.put(packageName, openToModuleSet);
}
}
if (!missingOpens.isEmpty()) {
if (instrumentation.isModifiableModule(targetModule)) {
logger.debug("Opening packages {} from module {} for instrumentation to module {}", missingOpens.keySet(), targetModule, openToModule);
try {
instrumentation.redefineModule(targetModule,
Collections.<Module>emptySet(), //reads
Collections.<String, Set<Module>>emptyMap(), //exports
missingOpens, //opens
Collections.<Class<?>>emptySet(), //uses
Collections.<Class<?>, List<Class<?>>>emptyMap() //provides
);
} catch (Exception e) {
if (JvmRuntimeInfo.ofCurrentVM().getMajorVersion() >= 17) {
logger.error("Failed to open packages {} from module {} for instrumentation due to exception", missingOpens.keySet(), targetModule, e);
return false;
} else {
logger.warn("Failed to open packages {} from module {} for instrumentation due to exception", missingOpens.keySet(), targetModule, e);
}
}
} else {
if (JvmRuntimeInfo.ofCurrentVM().getMajorVersion() >= 17) {
logger.error("Cannot open packages {} from module {} for instrumentation because module cannot be redefined!", missingOpens.keySet(), targetModule);
return false;
} else {
logger.error("annot open packages {} from module {} for instrumentation because module cannot be redefined!", missingOpens.keySet(), targetModule);
}
}
}
return true;
}
}
if (JvmRuntimeInfo.ofCurrentVM().getMajorVersion() >= 17) {
logger.error("Cannot open packages {} from module {} for instrumentation because module cannot be redefined!", missingOpens.keySet(), targetModule);
return false;
}
The code above is contained in the ModuleOpenerImpl class. I'm a bit puzzled by the special handling for Java 17 and above. The code indicates that Java 17 and later versions will return false within some branches, while versions below Java 17 will not. Does anyone have any documentation or links that can explain what details in Java 17 lead to the need for this kind of behavior here? I tried searching previous PR information but didn't find any convincing explanation.