JDK-8159145 : Add JVMTI function GetNamedModule
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: jvmti
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-06-09
  • Updated: 2017-05-17
  • Resolved: 2016-07-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b129Fixed
Related Reports
Duplicate :  
Relates :  
Description
JVM TI agents that instrument code in named modules need the Module at class load time. One way to do this is by introducing a new ClassFileLoadHook that takes an additional parameter but this approach is disruptive. The alternative option is a JVM TI function that maps a classloader + package name to a module. We were initially not confident with this approach so we introduced it as JVM function JVM_GetModuleByPackageName. Based on experience to date then this approach seems okay and so this function needs to be promoted to a JVMTI function.

Update: This function has to be live phase only. Also the most consistent way to define this function is for it to return the unnamed module of the ClassLoader when the package is not in a named module defined to the class loader.

Comments
We decided to change the JVMTI function name from GetModuleByPackageName to GetNamedModule.
24-06-2016

The suggested fix is: diff -r e903242021db src/share/vm/classfile/modules.cpp --- a/src/share/vm/classfile/modules.cpp Wed Jun 08 16:26:11 2016 +0200 +++ b/src/share/vm/classfile/modules.cpp Fri Jun 10 02:02:02 2016 -0700 @@ -784,8 +784,6 @@ jobject Modules::get_module_by_package_name(jobject loader, jstring package, TRAPS) { ResourceMark rm(THREAD); - assert(ModuleEntryTable::javabase_defined(), - "Attempt to call get_module_from_pkg before java.base is defined"); if (NULL == package) { THROW_MSG_(vmSymbols::java_lang_NullPointerException(), @@ -797,6 +795,14 @@ THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "Invalid package", JNI_FALSE); } + return get_module_by_package_name(loader, package_str, THREAD); +} + + +jobject Modules::get_module_by_package_name(jobject loader, const char* package_str, TRAPS) { + ResourceMark rm(THREAD); + assert(ModuleEntryTable::javabase_defined(), + "Attempt to call get_module_from_pkg before java.base is defined"); Handle h_loader (THREAD, JNIHandles::resolve(loader)); // Check that loader is a subclass of java.lang.ClassLoader. diff -r e903242021db src/share/vm/classfile/modules.hpp --- a/src/share/vm/classfile/modules.hpp Wed Jun 08 16:26:11 2016 +0200 +++ b/src/share/vm/classfile/modules.hpp Fri Jun 10 02:02:02 2016 -0700 @@ -121,6 +121,7 @@ // IllegalArgumentException is thrown if loader is neither null nor a subtype of // java/lang/ClassLoader. static jobject get_module_by_package_name(jobject loader, jstring package, TRAPS); + static jobject get_module_by_package_name(jobject loader, const char* package, TRAPS); // If package is defined by loader, return the // java.lang.reflect.Module object for the module in which the package is defined. diff -r e903242021db src/share/vm/prims/jvmti.xml --- a/src/share/vm/prims/jvmti.xml Wed Jun 08 16:26:11 2016 +0200 +++ b/src/share/vm/prims/jvmti.xml Fri Jun 10 02:02:02 2016 -0700 @@ -6509,6 +6509,47 @@ <errors> </errors> </function> + + <function id="GetModuleByPackageName" num="40" since="9"> + <synopsis>Get Module By Package Name</synopsis> + <description> + Return a <code>java.lang.reflect.Module object</code> + of the class loader exporting the specified package. + The module is returned via <code>module_ptr</code>. + <p/> + </description> + <origin>new</origin> + <capabilities> + </capabilities> + <parameters> + <param id="class_loader"> + <ptrtype> + <jobject/> + <nullok>A module of the bootstrap loader</nullok> + </ptrtype> + <description> + A class loader. + </description> + </param> + <param id="package_name"> + <inbuf><char/></inbuf> + <description> + The name of a package exported by the requested module, encoded as a + <internallink id="mUTF">modified UTF-8</internallink> string. + </description> + </param> + <param id="module_ptr"> + <outptr><jobject/></outptr> + <description> + On return, points to a <code>java.lang.reflect.Module</code> object. + If there is no such a module, then, + on return, points to <code>NULL</code>. + </description> + </param> + </parameters> + <errors> + </errors> + </function> </category> <category id="class" label="Class"> diff -r e903242021db src/share/vm/prims/jvmtiEnv.cpp --- a/src/share/vm/prims/jvmtiEnv.cpp Wed Jun 08 16:26:11 2016 +0200 +++ b/src/share/vm/prims/jvmtiEnv.cpp Fri Jun 10 02:02:02 2016 -0700 @@ -201,6 +201,17 @@ } /* end GetAllModules */ +// class_loader - NULL is a valid value, must be pre-checked +// package - pre-checked for NULL +// module_ptr - pre-checked for NULL +jvmtiError +JvmtiEnv::GetModuleByPackageName(jobject loader, const char* package, jobject* module_ptr) { + JavaThread* current_thread = JavaThread::current(); + + *module_ptr = Modules::get_module_by_package_name(loader, package, current_thread); + return JVMTI_ERROR_NONE; +} /* end GetModuleByPackageName */ + // // Class functions //
10-06-2016