1/*
2* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*
5* This code is free software; you can redistribute it and/or modify it
6* under the terms of the GNU General Public License version 2 only, as
7* published by the Free Software Foundation.
8*
9* This code is distributed in the hope that it will be useful, but WITHOUT
10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11* FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12* version 2 for more details (a copy is included in the LICENSE file that
13* accompanied this code).
14*
15* You should have received a copy of the GNU General Public License version
16* 2 along with this work; if not, write to the Free Software Foundation,
17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18*
19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20* or visit www.oracle.com if you need additional information or have any
21* questions.
22*
23*/
24
25#include "precompiled.hpp"
26#include "classfile/classFileParser.hpp"
27#include "classfile/classLoader.hpp"
28#include "classfile/classLoaderData.inline.hpp"
29#include "classfile/javaAssertions.hpp"
30#include "classfile/javaClasses.hpp"
31#include "classfile/javaClasses.inline.hpp"
32#include "classfile/moduleEntry.hpp"
33#include "classfile/modules.hpp"
34#include "classfile/packageEntry.hpp"
35#include "classfile/stringTable.hpp"
36#include "classfile/symbolTable.hpp"
37#include "classfile/systemDictionary.hpp"
38#include "classfile/vmSymbols.hpp"
39#include "logging/log.hpp"
40#include "logging/logStream.hpp"
41#include "memory/resourceArea.hpp"
42#include "oops/instanceKlass.hpp"
43#include "prims/jvm.h"
44#include "runtime/arguments.hpp"
45#include "runtime/handles.inline.hpp"
46#include "runtime/javaCalls.hpp"
47#include "runtime/reflection.hpp"
48#include "utilities/stringUtils.hpp"
49#include "utilities/utf8.hpp"
50
51static bool verify_module_name(const char *module_name) {
52  if (module_name == NULL) return false;
53  int len = (int)strlen(module_name);
54  return (len > 0 && len <= Symbol::max_length());
55}
56
57bool Modules::verify_package_name(const char* package_name) {
58  if (package_name == NULL) return false;
59  int len = (int)strlen(package_name);
60  return (len > 0 && len <= Symbol::max_length() &&
61    UTF8::is_legal_utf8((const unsigned char *)package_name, len, false) &&
62    ClassFileParser::verify_unqualified_name(package_name, len,
63    ClassFileParser::LegalClass));
64}
65
66static char* get_module_name(oop module, TRAPS) {
67  oop name_oop = java_lang_Module::name(module);
68  if (name_oop == NULL) {
69    THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), "Null module name");
70  }
71  char* module_name = java_lang_String::as_utf8_string(name_oop);
72  if (!verify_module_name(module_name)) {
73    THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
74                   err_msg("Invalid module name: %s",
75                           module_name != NULL ? module_name : "NULL"));
76  }
77  return module_name;
78}
79
80static const char* get_module_version(jstring version) {
81  if (version == NULL) {
82    return NULL;
83  }
84  return java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(version));
85}
86
87static ModuleEntryTable* get_module_entry_table(Handle h_loader, TRAPS) {
88  // This code can be called during start-up, before the classLoader's classLoader data got
89  // created.  So, call register_loader() to make sure the classLoader data gets created.
90  ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader, CHECK_NULL);
91  return loader_cld->modules();
92}
93
94static PackageEntryTable* get_package_entry_table(Handle h_loader, TRAPS) {
95  // This code can be called during start-up, before the classLoader's classLoader data got
96  // created.  So, call register_loader() to make sure the classLoader data gets created.
97  ClassLoaderData *loader_cld = SystemDictionary::register_loader(h_loader, CHECK_NULL);
98  return loader_cld->packages();
99}
100
101static ModuleEntry* get_module_entry(jobject module, TRAPS) {
102  Handle module_h(THREAD, JNIHandles::resolve(module));
103  if (!java_lang_Module::is_instance(module_h())) {
104    THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(),
105                   "module is not an instance of type java.lang.Module");
106  }
107  return java_lang_Module::module_entry(module_h(), CHECK_NULL);
108}
109
110static PackageEntry* get_package_entry(ModuleEntry* module_entry, const char* package_name, TRAPS) {
111  ResourceMark rm(THREAD);
112  if (package_name == NULL) return NULL;
113  TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK_NULL);
114  PackageEntryTable* package_entry_table = module_entry->loader_data()->packages();
115  assert(package_entry_table != NULL, "Unexpected null package entry table");
116  return package_entry_table->lookup_only(pkg_symbol);
117}
118
119static PackageEntry* get_package_entry_by_name(Symbol* package,
120                                               Handle h_loader,
121                                               TRAPS) {
122  if (package != NULL) {
123    ResourceMark rm(THREAD);
124    if (Modules::verify_package_name(package->as_C_string())) {
125      PackageEntryTable* const package_entry_table =
126        get_package_entry_table(h_loader, CHECK_NULL);
127      assert(package_entry_table != NULL, "Unexpected null package entry table");
128      return package_entry_table->lookup_only(package);
129    }
130  }
131  return NULL;
132}
133
134bool Modules::is_package_defined(Symbol* package, Handle h_loader, TRAPS) {
135  PackageEntry* res = get_package_entry_by_name(package, h_loader, CHECK_false);
136  return res != NULL;
137}
138
139static void define_javabase_module(jobject module, jstring version,
140                                   jstring location, const char* const* packages,
141                                   jsize num_packages, TRAPS) {
142  ResourceMark rm(THREAD);
143
144  Handle module_handle(THREAD, JNIHandles::resolve(module));
145
146  // Obtain java.base's module version
147  const char* module_version = get_module_version(version);
148  TempNewSymbol version_symbol;
149  if (module_version != NULL) {
150    version_symbol = SymbolTable::new_symbol(module_version, CHECK);
151  } else {
152    version_symbol = NULL;
153  }
154
155  // Obtain java.base's location
156  const char* module_location = NULL;
157  TempNewSymbol location_symbol = NULL;
158  if (location != NULL) {
159    module_location =
160      java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(location));
161    if (module_location != NULL) {
162      location_symbol = SymbolTable::new_symbol(module_location, CHECK);
163    }
164  }
165
166
167  // Check that the packages are syntactically ok.
168  GrowableArray<Symbol*>* pkg_list = new GrowableArray<Symbol*>(num_packages);
169  for (int x = 0; x < num_packages; x++) {
170    const char *package_name = packages[x];
171    if (!Modules::verify_package_name(package_name)) {
172      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
173                err_msg("Invalid package name: %s for module: " JAVA_BASE_NAME, package_name));
174    }
175    Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK);
176    pkg_list->append(pkg_symbol);
177  }
178
179  // Validate java_base's loader is the boot loader.
180  oop loader = java_lang_Module::loader(module_handle());
181  if (loader != NULL) {
182    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
183              "Class loader must be the boot class loader");
184  }
185  Handle h_loader(THREAD, loader);
186
187  // Ensure the boot loader's PackageEntryTable has been created
188  PackageEntryTable* package_table = get_package_entry_table(h_loader, CHECK);
189  assert(pkg_list->length() == 0 || package_table != NULL, "Bad package_table");
190
191  // Ensure java.base's ModuleEntry has been created
192  assert(ModuleEntryTable::javabase_moduleEntry() != NULL, "No ModuleEntry for " JAVA_BASE_NAME);
193
194  bool duplicate_javabase = false;
195  {
196    MutexLocker m1(Module_lock, THREAD);
197
198    if (ModuleEntryTable::javabase_defined()) {
199      duplicate_javabase = true;
200    } else {
201
202      // Verify that all java.base packages created during bootstrapping are in
203      // pkg_list.  If any are not in pkg_list, than a non-java.base class was
204      // loaded erroneously pre java.base module definition.
205      package_table->verify_javabase_packages(pkg_list);
206
207      // loop through and add any new packages for java.base
208      PackageEntry* pkg;
209      for (int x = 0; x < pkg_list->length(); x++) {
210        // Some of java.base's packages were added early in bootstrapping, ignore duplicates.
211        if (package_table->lookup_only(pkg_list->at(x)) == NULL) {
212          pkg = package_table->locked_create_entry_or_null(pkg_list->at(x), ModuleEntryTable::javabase_moduleEntry());
213          assert(pkg != NULL, "Unable to create a " JAVA_BASE_NAME " package entry");
214        }
215        // Unable to have a GrowableArray of TempNewSymbol.  Must decrement the refcount of
216        // the Symbol* that was created above for each package. The refcount was incremented
217        // by SymbolTable::new_symbol and as well by the PackageEntry creation.
218        pkg_list->at(x)->decrement_refcount();
219      }
220
221      // Finish defining java.base's ModuleEntry
222      ModuleEntryTable::finalize_javabase(module_handle, version_symbol, location_symbol);
223    }
224  }
225  if (duplicate_javabase) {
226    THROW_MSG(vmSymbols::java_lang_InternalError(),
227              "Module " JAVA_BASE_NAME " is already defined");
228  }
229
230  // Only the thread that actually defined the base module will get here,
231  // so no locking is needed.
232
233  // Patch any previously loaded class's module field with java.base's java.lang.Module.
234  ModuleEntryTable::patch_javabase_entries(module_handle);
235
236  log_info(module, load)(JAVA_BASE_NAME " location: %s",
237                         module_location != NULL ? module_location : "NULL");
238  log_debug(module)("define_javabase_module(): Definition of module: "
239                    JAVA_BASE_NAME ", version: %s, location: %s, package #: %d",
240                    module_version != NULL ? module_version : "NULL",
241                    module_location != NULL ? module_location : "NULL",
242                    pkg_list->length());
243
244  // packages defined to java.base
245  if (log_is_enabled(Trace, module)) {
246    for (int x = 0; x < pkg_list->length(); x++) {
247      log_trace(module)("define_javabase_module(): creation of package %s for module " JAVA_BASE_NAME,
248                        (pkg_list->at(x))->as_C_string());
249    }
250  }
251}
252
253// Caller needs ResourceMark.
254void throw_dup_pkg_exception(const char* module_name, PackageEntry* package, TRAPS) {
255  const char* package_name = package->name()->as_C_string();
256  if (package->module()->is_named()) {
257    THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
258      err_msg("Package %s for module %s is already in another module, %s, defined to the class loader",
259              package_name, module_name, package->module()->name()->as_C_string()));
260  } else {
261    THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
262      err_msg("Package %s for module %s is already in the unnamed module defined to the class loader",
263              package_name, module_name));
264  }
265}
266
267void Modules::define_module(jobject module, jboolean is_open, jstring version,
268                            jstring location, const char* const* packages,
269                            jsize num_packages, TRAPS) {
270  ResourceMark rm(THREAD);
271
272  if (module == NULL) {
273    THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Null module object");
274  }
275
276  if (num_packages < 0) {
277    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
278              "num_packages must be >= 0");
279  }
280
281  if (packages == NULL && num_packages > 0) {
282    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
283              "num_packages should be zero if packages is null");
284  }
285
286  Handle module_handle(THREAD, JNIHandles::resolve(module));
287  if (!java_lang_Module::is_instance(module_handle())) {
288    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
289              "module is not an instance of type java.lang.Module");
290  }
291
292  char* module_name = get_module_name(module_handle(), CHECK);
293  if (module_name == NULL) {
294    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
295              "Module name cannot be null");
296  }
297
298  // Special handling of java.base definition
299  if (strcmp(module_name, JAVA_BASE_NAME) == 0) {
300    assert(is_open == JNI_FALSE, "java.base module cannot be open");
301    define_javabase_module(module, version, location, packages, num_packages, CHECK);
302    return;
303  }
304
305  const char* module_version = get_module_version(version);
306
307  oop loader = java_lang_Module::loader(module_handle());
308  // Make sure loader is not the jdk.internal.reflect.DelegatingClassLoader.
309  if (loader != java_lang_ClassLoader::non_reflection_class_loader(loader)) {
310    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
311              "Class loader is an invalid delegating class loader");
312  }
313  Handle h_loader = Handle(THREAD, loader);
314
315  // Check that the list of packages has no duplicates and that the
316  // packages are syntactically ok.
317  GrowableArray<Symbol*>* pkg_list = new GrowableArray<Symbol*>(num_packages);
318  for (int x = 0; x < num_packages; x++) {
319    const char* package_name = packages[x];
320    if (!verify_package_name(package_name)) {
321      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
322                err_msg("Invalid package name: %s for module: %s",
323                        package_name, module_name));
324    }
325
326    // Only modules defined to either the boot or platform class loader, can define a "java/" package.
327    if (!h_loader.is_null() &&
328        !SystemDictionary::is_platform_class_loader(h_loader()) &&
329        (strncmp(package_name, JAVAPKG, JAVAPKG_LEN) == 0 &&
330          (package_name[JAVAPKG_LEN] == '/' || package_name[JAVAPKG_LEN] == '\0'))) {
331      const char* class_loader_name = SystemDictionary::loader_name(h_loader());
332      size_t pkg_len = strlen(package_name);
333      char* pkg_name = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, pkg_len);
334      strncpy(pkg_name, package_name, pkg_len);
335      StringUtils::replace_no_expand(pkg_name, "/", ".");
336      const char* msg_text1 = "Class loader (instance of): ";
337      const char* msg_text2 = " tried to define prohibited package name: ";
338      size_t len = strlen(msg_text1) + strlen(class_loader_name) + strlen(msg_text2) + pkg_len + 1;
339      char* message = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, len);
340      jio_snprintf(message, len, "%s%s%s%s", msg_text1, class_loader_name, msg_text2, pkg_name);
341      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message);
342    }
343
344    Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK);
345    pkg_list->append(pkg_symbol);
346  }
347
348  ModuleEntryTable* module_table = get_module_entry_table(h_loader, CHECK);
349  assert(module_table != NULL, "module entry table shouldn't be null");
350
351  // Create symbol* entry for module name.
352  TempNewSymbol module_symbol = SymbolTable::new_symbol(module_name, CHECK);
353
354  bool dupl_modules = false;
355
356  // Create symbol* entry for module version.
357  TempNewSymbol version_symbol;
358  if (module_version != NULL) {
359    version_symbol = SymbolTable::new_symbol(module_version, CHECK);
360  } else {
361    version_symbol = NULL;
362  }
363
364  // Create symbol* entry for module location.
365  const char* module_location = NULL;
366  TempNewSymbol location_symbol = NULL;
367  if (location != NULL) {
368    module_location =
369      java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(location));
370    if (module_location != NULL) {
371      location_symbol = SymbolTable::new_symbol(module_location, CHECK);
372    }
373  }
374
375  ClassLoaderData* loader_data = ClassLoaderData::class_loader_data_or_null(h_loader());
376  assert(loader_data != NULL, "class loader data shouldn't be null");
377
378  PackageEntryTable* package_table = NULL;
379  PackageEntry* existing_pkg = NULL;
380  {
381    MutexLocker ml(Module_lock, THREAD);
382
383    if (num_packages > 0) {
384      package_table = get_package_entry_table(h_loader, CHECK);
385      assert(package_table != NULL, "Missing package_table");
386
387      // Check that none of the packages exist in the class loader's package table.
388      for (int x = 0; x < pkg_list->length(); x++) {
389        existing_pkg = package_table->lookup_only(pkg_list->at(x));
390        if (existing_pkg != NULL) {
391          // This could be because the module was already defined.  If so,
392          // report that error instead of the package error.
393          if (module_table->lookup_only(module_symbol) != NULL) {
394            dupl_modules = true;
395          }
396          break;
397        }
398      }
399    }  // if (num_packages > 0)...
400
401    // Add the module and its packages.
402    if (!dupl_modules && existing_pkg == NULL) {
403      // Create the entry for this module in the class loader's module entry table.
404      ModuleEntry* module_entry = module_table->locked_create_entry_or_null(module_handle,
405                                    (is_open == JNI_TRUE), module_symbol,
406                                    version_symbol, location_symbol, loader_data);
407
408      if (module_entry == NULL) {
409        dupl_modules = true;
410      } else {
411        // Add the packages.
412        assert(pkg_list->length() == 0 || package_table != NULL, "Bad package table");
413        PackageEntry* pkg;
414        for (int y = 0; y < pkg_list->length(); y++) {
415          pkg = package_table->locked_create_entry_or_null(pkg_list->at(y), module_entry);
416          assert(pkg != NULL, "Unable to create a module's package entry");
417
418          // Unable to have a GrowableArray of TempNewSymbol.  Must decrement the refcount of
419          // the Symbol* that was created above for each package. The refcount was incremented
420          // by SymbolTable::new_symbol and as well by the PackageEntry creation.
421          pkg_list->at(y)->decrement_refcount();
422        }
423
424        // Store pointer to ModuleEntry record in java.lang.Module object.
425        java_lang_Module::set_module_entry(module_handle(), module_entry);
426      }
427    }
428  }  // Release the lock
429
430  // any errors ?
431  if (dupl_modules) {
432     THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
433               err_msg("Module %s is already defined", module_name));
434  } else if (existing_pkg != NULL) {
435      throw_dup_pkg_exception(module_name, existing_pkg, CHECK);
436  }
437
438  log_info(module, load)("%s location: %s", module_name,
439                         module_location != NULL ? module_location : "NULL");
440  LogTarget(Debug, module) lt;
441  if (lt.is_enabled()) {
442    LogStream ls(lt);
443    ls.print("define_module(): creation of module: %s, version: %s, location: %s, ",
444                 module_name, module_version != NULL ? module_version : "NULL",
445                 module_location != NULL ? module_location : "NULL");
446    loader_data->print_value_on(&ls);
447    ls.print_cr(", package #: %d", pkg_list->length());
448    for (int y = 0; y < pkg_list->length(); y++) {
449      log_trace(module)("define_module(): creation of package %s for module %s",
450                        (pkg_list->at(y))->as_C_string(), module_name);
451    }
452  }
453
454  // If the module is defined to the boot loader and an exploded build is being
455  // used, prepend <java.home>/modules/modules_name to the system boot class path.
456  if (loader == NULL && !ClassLoader::has_jrt_entry()) {
457    ClassLoader::add_to_exploded_build_list(module_symbol, CHECK);
458  }
459}
460
461void Modules::set_bootloader_unnamed_module(jobject module, TRAPS) {
462  ResourceMark rm(THREAD);
463
464  if (module == NULL) {
465    THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Null module object");
466  }
467  Handle module_handle(THREAD, JNIHandles::resolve(module));
468  if (!java_lang_Module::is_instance(module_handle())) {
469    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
470              "module is not an instance of type java.lang.Module");
471  }
472
473  // Ensure that this is an unnamed module
474  oop name = java_lang_Module::name(module_handle());
475  if (name != NULL) {
476    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
477              "boot loader's unnamed module's java.lang.Module has a name");
478  }
479
480  // Validate java_base's loader is the boot loader.
481  oop loader = java_lang_Module::loader(module_handle());
482  if (loader != NULL) {
483    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
484              "Class loader must be the boot class loader");
485  }
486  Handle h_loader(THREAD, loader);
487
488  log_debug(module)("set_bootloader_unnamed_module(): recording unnamed module for boot loader");
489
490  // Set java.lang.Module for the boot loader's unnamed module
491  ClassLoaderData* boot_loader_data = ClassLoaderData::the_null_class_loader_data();
492  ModuleEntry* unnamed_module = boot_loader_data->unnamed_module();
493  assert(unnamed_module != NULL, "boot loader's unnamed ModuleEntry not defined");
494  unnamed_module->set_module(boot_loader_data->add_handle(module_handle));
495  // Store pointer to the ModuleEntry in the unnamed module's java.lang.Module object.
496  java_lang_Module::set_module_entry(module_handle(), unnamed_module);
497}
498
499void Modules::add_module_exports(jobject from_module, const char* package_name, jobject to_module, TRAPS) {
500  if (package_name == NULL) {
501    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
502              "package is null");
503  }
504  if (from_module == NULL) {
505    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
506              "from_module is null");
507  }
508  ModuleEntry* from_module_entry = get_module_entry(from_module, CHECK);
509  if (from_module_entry == NULL) {
510    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
511              "from_module cannot be found");
512  }
513
514  // All packages in unnamed and open modules are exported by default.
515  if (!from_module_entry->is_named() || from_module_entry->is_open()) return;
516
517  ModuleEntry* to_module_entry;
518  if (to_module == NULL) {
519    to_module_entry = NULL;  // It's an unqualified export.
520  } else {
521    to_module_entry = get_module_entry(to_module, CHECK);
522    if (to_module_entry == NULL) {
523      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
524                "to_module is invalid");
525    }
526  }
527
528  PackageEntry *package_entry = get_package_entry(from_module_entry, package_name, CHECK);
529  ResourceMark rm(THREAD);
530  if (package_entry == NULL) {
531    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
532              err_msg("Package %s not found in from_module %s",
533                      package_name != NULL ? package_name : "",
534                      from_module_entry->name()->as_C_string()));
535  }
536  if (package_entry->module() != from_module_entry) {
537    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
538              err_msg("Package: %s found in module %s, not in from_module: %s",
539                      package_entry->name()->as_C_string(),
540                      package_entry->module()->name()->as_C_string(),
541                      from_module_entry->name()->as_C_string()));
542  }
543
544  log_debug(module)("add_module_exports(): package %s in module %s is exported to module %s",
545                    package_entry->name()->as_C_string(),
546                    from_module_entry->name()->as_C_string(),
547                    to_module_entry == NULL ? "NULL" :
548                      to_module_entry->is_named() ?
549                        to_module_entry->name()->as_C_string() : UNNAMED_MODULE);
550
551  // Do nothing if modules are the same.
552  if (from_module_entry != to_module_entry) {
553    package_entry->set_exported(to_module_entry);
554  }
555}
556
557
558void Modules::add_module_exports_qualified(jobject from_module, const char* package,
559                                           jobject to_module, TRAPS) {
560  if (to_module == NULL) {
561    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
562              "to_module is null");
563  }
564  add_module_exports(from_module, package, to_module, CHECK);
565}
566
567void Modules::add_reads_module(jobject from_module, jobject to_module, TRAPS) {
568  if (from_module == NULL) {
569    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
570              "from_module is null");
571  }
572
573  ModuleEntry* from_module_entry = get_module_entry(from_module, CHECK);
574  if (from_module_entry == NULL) {
575    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
576              "from_module is not valid");
577  }
578
579  ModuleEntry* to_module_entry;
580  if (to_module != NULL) {
581    to_module_entry = get_module_entry(to_module, CHECK);
582    if (to_module_entry == NULL) {
583      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
584                "to_module is invalid");
585    }
586  } else {
587    to_module_entry = NULL;
588  }
589
590  ResourceMark rm(THREAD);
591  log_debug(module)("add_reads_module(): Adding read from module %s to module %s",
592                    from_module_entry->is_named() ?
593                    from_module_entry->name()->as_C_string() : UNNAMED_MODULE,
594                    to_module_entry == NULL ? "all unnamed" :
595                      (to_module_entry->is_named() ?
596                       to_module_entry->name()->as_C_string() : UNNAMED_MODULE));
597
598  // if modules are the same or if from_module is unnamed then no need to add the read.
599  if (from_module_entry != to_module_entry && from_module_entry->is_named()) {
600    from_module_entry->add_read(to_module_entry);
601  }
602}
603
604// This method is called by JFR and JNI.
605jobject Modules::get_module(jclass clazz, TRAPS) {
606  assert(ModuleEntryTable::javabase_defined(),
607         "Attempt to call get_module before " JAVA_BASE_NAME " is defined");
608
609  if (clazz == NULL) {
610    THROW_MSG_(vmSymbols::java_lang_NullPointerException(),
611               "class is null", JNI_FALSE);
612  }
613  oop mirror = JNIHandles::resolve_non_null(clazz);
614  if (mirror == NULL) {
615    log_debug(module)("get_module(): no mirror, returning NULL");
616    return NULL;
617  }
618  if (!java_lang_Class::is_instance(mirror)) {
619    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
620               "Invalid class", JNI_FALSE);
621  }
622
623  oop module = java_lang_Class::module(mirror);
624
625  assert(module != NULL, "java.lang.Class module field not set");
626  assert(java_lang_Module::is_instance(module), "module is not an instance of type java.lang.Module");
627
628  LogTarget(Debug,module) lt;
629  if (lt.is_enabled()) {
630    ResourceMark rm(THREAD);
631    LogStream ls(lt);
632    Klass* klass = java_lang_Class::as_Klass(mirror);
633    oop module_name = java_lang_Module::name(module);
634    if (module_name != NULL) {
635      ls.print("get_module(): module ");
636      java_lang_String::print(module_name, tty);
637    } else {
638      ls.print("get_module(): Unamed Module");
639    }
640    if (klass != NULL) {
641      ls.print_cr(" for class %s", klass->external_name());
642    } else {
643      ls.print_cr(" for primitive class");
644    }
645  }
646
647  return JNIHandles::make_local(THREAD, module);
648}
649
650jobject Modules::get_named_module(Handle h_loader, const char* package_name, TRAPS) {
651  assert(ModuleEntryTable::javabase_defined(),
652         "Attempt to call get_named_module before " JAVA_BASE_NAME " is defined");
653  assert(h_loader.is_null() || java_lang_ClassLoader::is_subclass(h_loader->klass()),
654         "Class loader is not a subclass of java.lang.ClassLoader");
655  assert(package_name != NULL, "the package_name should not be NULL");
656
657  if (strlen(package_name) == 0) {
658    return NULL;
659  }
660  TempNewSymbol package_sym = SymbolTable::new_symbol(package_name, CHECK_NULL);
661  const PackageEntry* const pkg_entry =
662    get_package_entry_by_name(package_sym, h_loader, THREAD);
663  const ModuleEntry* const module_entry = (pkg_entry != NULL ? pkg_entry->module() : NULL);
664
665  if (module_entry != NULL && module_entry->module() != NULL && module_entry->is_named()) {
666    return JNIHandles::make_local(THREAD, module_entry->module());
667  }
668  return NULL;
669}
670
671
672// This method is called by JFR and by the above method.
673jobject Modules::get_module(Symbol* package_name, Handle h_loader, TRAPS) {
674  const PackageEntry* const pkg_entry =
675    get_package_entry_by_name(package_name, h_loader, THREAD);
676  const ModuleEntry* const module_entry = (pkg_entry != NULL ? pkg_entry->module() : NULL);
677
678  if (module_entry != NULL &&
679      module_entry->module() != NULL) {
680    return JNIHandles::make_local(THREAD, module_entry->module());
681  }
682
683  return NULL;
684}
685
686// Export package in module to all unnamed modules.
687void Modules::add_module_exports_to_all_unnamed(jobject module, const char* package_name, TRAPS) {
688  if (module == NULL) {
689    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
690              "module is null");
691  }
692  if (package_name == NULL) {
693    THROW_MSG(vmSymbols::java_lang_NullPointerException(),
694              "package is null");
695  }
696  ModuleEntry* module_entry = get_module_entry(module, CHECK);
697  if (module_entry == NULL) {
698    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
699              "module is invalid");
700  }
701
702  if (module_entry->is_named()) { // No-op for unnamed module.
703    PackageEntry *package_entry = get_package_entry(module_entry, package_name, CHECK);
704    ResourceMark rm(THREAD);
705    if (package_entry == NULL) {
706      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
707                err_msg("Package %s not found in module %s",
708                        package_name != NULL ? package_name : "",
709                        module_entry->name()->as_C_string()));
710    }
711    if (package_entry->module() != module_entry) {
712      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
713                err_msg("Package: %s found in module %s, not in module: %s",
714                        package_entry->name()->as_C_string(),
715                        package_entry->module()->name()->as_C_string(),
716                        module_entry->name()->as_C_string()));
717    }
718
719    log_debug(module)("add_module_exports_to_all_unnamed(): package %s in module"
720                      " %s is exported to all unnamed modules",
721                       package_entry->name()->as_C_string(),
722                       module_entry->name()->as_C_string());
723
724    // Mark package as exported to all unnamed modules.
725    package_entry->set_is_exported_allUnnamed();
726  }
727}
728