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