1 /* 2 * Copyright (c) 2015, 2024, 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 "cds/archiveUtils.hpp" 27 #include "cds/classListParser.hpp" 28 #include "cds/lambdaFormInvokers.hpp" 29 #include "cds/metaspaceShared.hpp" 30 #include "cds/unregisteredClasses.hpp" 31 #include "classfile/classLoaderExt.hpp" 32 #include "classfile/javaClasses.inline.hpp" 33 #include "classfile/symbolTable.hpp" 34 #include "classfile/systemDictionary.hpp" 35 #include "classfile/systemDictionaryShared.hpp" 36 #include "classfile/vmClasses.hpp" 37 #include "classfile/vmSymbols.hpp" 38 #include "interpreter/bytecode.hpp" 39 #include "interpreter/bytecodeStream.hpp" 40 #include "interpreter/linkResolver.hpp" 41 #include "jimage.hpp" 42 #include "jvm.h" 43 #include "logging/log.hpp" 44 #include "logging/logTag.hpp" 45 #include "memory/resourceArea.hpp" 46 #include "oops/constantPool.inline.hpp" 47 #include "runtime/atomic.hpp" 48 #include "runtime/handles.inline.hpp" 49 #include "runtime/java.hpp" 50 #include "runtime/javaCalls.hpp" 51 #include "utilities/defaultStream.hpp" 52 #include "utilities/macros.hpp" 53 #include "utilities/utf8.hpp" 54 55 volatile Thread* ClassListParser::_parsing_thread = nullptr; 56 ClassListParser* ClassListParser::_instance = nullptr; 57 58 ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) : 59 _classlist_file(file), 60 _id2klass_table(INITIAL_TABLE_SIZE, MAX_TABLE_SIZE), 61 _file_input(do_open(file), /* need_close=*/true), 62 _input_stream(&_file_input), 63 _parse_mode(parse_mode) { 64 log_info(cds)("Parsing %s%s", file, 65 parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : ""); 66 if (!_file_input.is_open()) { 67 char errmsg[JVM_MAXPATHLEN]; 68 os::lasterror(errmsg, JVM_MAXPATHLEN); 69 vm_exit_during_initialization("Loading classlist failed", errmsg); 70 } 71 _token = _line = nullptr; 72 _interfaces = new (mtClass) GrowableArray<int>(10, mtClass); 73 _indy_items = new (mtClass) GrowableArray<const char*>(9, mtClass); 74 75 // _instance should only be accessed by the thread that created _instance. 76 assert(_instance == nullptr, "must be singleton"); 77 _instance = this; 78 Atomic::store(&_parsing_thread, Thread::current()); 79 } 80 81 FILE* ClassListParser::do_open(const char* file) { 82 // Use os::open() because neither fopen() nor os::fopen() 83 // can handle long path name on Windows. (See JDK-8216184) 84 int fd = os::open(file, O_RDONLY, S_IREAD); 85 FILE* fp = nullptr; 86 if (fd != -1) { 87 // Obtain a FILE* from the file descriptor so that _input_stream 88 // can be used in ClassListParser::parse() 89 fp = os::fdopen(fd, "r"); 90 } 91 return fp; 92 } 93 94 bool ClassListParser::is_parsing_thread() { 95 return Atomic::load(&_parsing_thread) == Thread::current(); 96 } 97 98 ClassListParser::~ClassListParser() { 99 Atomic::store(&_parsing_thread, (Thread*)nullptr); 100 delete _indy_items; 101 delete _interfaces; 102 _instance = nullptr; 103 } 104 105 void ClassListParser::parse(TRAPS) { 106 for (; !_input_stream.done(); _input_stream.next()) { 107 _line = _input_stream.current_line(); 108 clean_up_input_line(); 109 110 // Each line in the classlist can be one of three forms: 111 if (_line[0] == '#') { 112 // A comment; ignore it 113 } else if (_line[0] == '@') { 114 // @xxx - a tag like @lambda-proxy, to be parsed by parse_at_tags() 115 parse_at_tags(CHECK); 116 } else { 117 // A class name, followed by optional attributes. E.g. 118 // java/lang/String 119 // java/lang/Object id: 1 120 // my/pkg/TestClass id: 5 super: 1 interfaces: 3 4 source: foo.jar 121 parse_class_name_and_attributes(CHECK); 122 } 123 } 124 } 125 126 void ClassListParser::parse_class_name_and_attributes(TRAPS) { 127 read_class_name_and_attributes(); 128 129 if (parse_lambda_forms_invokers_only()) { 130 return; 131 } 132 133 check_class_name(_class_name); 134 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name); 135 Klass* klass = load_current_class(class_name_symbol, THREAD); 136 if (HAS_PENDING_EXCEPTION) { 137 if (PENDING_EXCEPTION->is_a(vmClasses::OutOfMemoryError_klass())) { 138 // If we have run out of memory, don't try to load the rest of the classes in 139 // the classlist. Throw an exception, which will terminate the dumping process. 140 return; // THROW 141 } 142 143 ResourceMark rm(THREAD); 144 char* ex_msg = (char*)""; 145 oop message = java_lang_Throwable::message(PENDING_EXCEPTION); 146 if (message != nullptr) { 147 ex_msg = java_lang_String::as_utf8_string(message); 148 } 149 log_warning(cds)("%s: %s", PENDING_EXCEPTION->klass()->external_name(), ex_msg); 150 // We might have an invalid class name or an bad class. Warn about it 151 // and keep going to the next line. 152 CLEAR_PENDING_EXCEPTION; 153 log_warning(cds)("Preload Warning: Cannot find %s", _class_name); 154 return; 155 } 156 157 assert(klass != nullptr, "sanity"); 158 if (log_is_enabled(Trace, cds)) { 159 ResourceMark rm(THREAD); 160 log_trace(cds)("Shared spaces preloaded: %s", klass->external_name()); 161 } 162 163 if (klass->is_instance_klass()) { 164 InstanceKlass* ik = InstanceKlass::cast(klass); 165 166 // Link the class to cause the bytecodes to be rewritten and the 167 // cpcache to be created. The linking is done as soon as classes 168 // are loaded in order that the related data structures (klass and 169 // cpCache) are located together. 170 MetaspaceShared::try_link_class(THREAD, ik); 171 } 172 } 173 174 void ClassListParser::clean_up_input_line() { 175 int len = (int)strlen(_line); 176 int i; 177 // Replace \t\r\n\f with ' ' 178 for (i=0; i<len; i++) { 179 if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n' || _line[i] == '\f') { 180 _line[i] = ' '; 181 } 182 } 183 184 // Remove trailing newline/space 185 while (len > 0) { 186 if (_line[len-1] == ' ') { 187 _line[len-1] = '\0'; 188 len --; 189 } else { 190 break; 191 } 192 } 193 _line_len = len; 194 } 195 196 void ClassListParser::read_class_name_and_attributes() { 197 _class_name = _line; 198 _id = _unspecified; 199 _super = _unspecified; 200 _interfaces->clear(); 201 _source = nullptr; 202 _interfaces_specified = false; 203 204 if ((_token = strchr(_line, ' ')) == nullptr) { 205 // No optional attributes are specified. 206 return; 207 } 208 209 // Mark the end of the name, and go to the next input char 210 *_token++ = '\0'; 211 212 while (*_token) { 213 skip_whitespaces(); 214 215 if (parse_uint_option("id:", &_id)) { 216 continue; 217 } else if (parse_uint_option("super:", &_super)) { 218 check_already_loaded("Super class", _super); 219 continue; 220 } else if (skip_token("interfaces:")) { 221 int i; 222 while (try_parse_uint(&i)) { 223 check_already_loaded("Interface", i); 224 _interfaces->append(i); 225 } 226 } else if (skip_token("source:")) { 227 skip_whitespaces(); 228 _source = _token; 229 char* s = strchr(_token, ' '); 230 if (s == nullptr) { 231 break; // end of input line 232 } else { 233 *s = '\0'; // mark the end of _source 234 _token = s+1; 235 } 236 } else { 237 error("Unknown input"); 238 } 239 } 240 241 // if src is specified 242 // id super interfaces must all be specified 243 // loader may be specified 244 // else 245 // # the class is loaded from classpath 246 // id may be specified 247 // super, interfaces, loader must not be specified 248 } 249 250 void ClassListParser::split_tokens_by_whitespace(int offset, GrowableArray<const char*>* items) { 251 int start = offset; 252 int end; 253 bool done = false; 254 while (!done) { 255 while (_line[start] == ' ' || _line[start] == '\t') start++; 256 end = start; 257 while (_line[end] && _line[end] != ' ' && _line[end] != '\t') end++; 258 if (_line[end] == '\0') { 259 done = true; 260 } else { 261 _line[end] = '\0'; 262 } 263 items->append(_line + start); 264 start = ++end; 265 } 266 } 267 268 int ClassListParser::split_at_tag_from_line() { 269 _token = _line; 270 char* ptr; 271 if ((ptr = strchr(_line, ' ')) == nullptr) { 272 error("Too few items following the @ tag \"%s\" line #%zu", _line, lineno()); 273 return 0; 274 } 275 *ptr++ = '\0'; 276 while (*ptr == ' ' || *ptr == '\t') ptr++; 277 return (int)(ptr - _line); 278 } 279 280 void ClassListParser::parse_at_tags(TRAPS) { 281 assert(_line[0] == '@', "must be"); 282 int offset = split_at_tag_from_line(); 283 assert(offset > 0, "would have exited VM"); 284 285 if (strcmp(_token, LAMBDA_PROXY_TAG) == 0) { 286 _indy_items->clear(); 287 split_tokens_by_whitespace(offset, _indy_items); 288 if (_indy_items->length() < 2) { 289 error("Line with @ tag has too few items \"%s\" line #%zu", _token, lineno()); 290 } 291 if (!parse_lambda_forms_invokers_only()) { 292 _class_name = _indy_items->at(0); 293 check_class_name(_class_name); 294 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name); 295 if (_indy_items->length() > 0) { 296 // The current line is "@lambda-proxy class_name". Load the proxy class. 297 resolve_indy(THREAD, class_name_symbol); 298 } 299 } 300 } else if (strcmp(_token, LAMBDA_FORM_TAG) == 0) { 301 LambdaFormInvokers::append(os::strdup((const char*)(_line + offset), mtInternal)); 302 } else { 303 error("Invalid @ tag at the beginning of line \"%s\" line #%zu", _token, lineno()); 304 } 305 } 306 307 void ClassListParser::skip_whitespaces() { 308 while (*_token == ' ' || *_token == '\t') { 309 _token ++; 310 } 311 } 312 313 void ClassListParser::skip_non_whitespaces() { 314 while (*_token && *_token != ' ' && *_token != '\t') { 315 _token ++; 316 } 317 } 318 319 void ClassListParser::parse_int(int* value) { 320 skip_whitespaces(); 321 if (sscanf(_token, "%i", value) == 1) { 322 skip_non_whitespaces(); 323 } else { 324 error("Error: expected integer"); 325 } 326 } 327 328 void ClassListParser::parse_uint(int* value) { 329 parse_int(value); 330 if (*value < 0) { 331 error("Error: negative integers not allowed (%d)", *value); 332 } 333 } 334 335 bool ClassListParser::try_parse_uint(int* value) { 336 skip_whitespaces(); 337 if (sscanf(_token, "%i", value) == 1) { 338 skip_non_whitespaces(); 339 return true; 340 } 341 return false; 342 } 343 344 bool ClassListParser::skip_token(const char* option_name) { 345 size_t len = strlen(option_name); 346 if (strncmp(_token, option_name, len) == 0) { 347 _token += len; 348 return true; 349 } else { 350 return false; 351 } 352 } 353 354 bool ClassListParser::parse_int_option(const char* option_name, int* value) { 355 if (skip_token(option_name)) { 356 if (*value != _unspecified) { 357 error("%s specified twice", option_name); 358 } else { 359 parse_int(value); 360 return true; 361 } 362 } 363 return false; 364 } 365 366 bool ClassListParser::parse_uint_option(const char* option_name, int* value) { 367 if (skip_token(option_name)) { 368 if (*value != _unspecified) { 369 error("%s specified twice", option_name); 370 } else { 371 parse_uint(value); 372 return true; 373 } 374 } 375 return false; 376 } 377 378 void ClassListParser::print_specified_interfaces() { 379 const int n = _interfaces->length(); 380 jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n); 381 for (int i=0; i<n; i++) { 382 InstanceKlass* k = lookup_class_by_id(_interfaces->at(i)); 383 jio_fprintf(defaultStream::error_stream(), " %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name()); 384 } 385 jio_fprintf(defaultStream::error_stream(), "}\n"); 386 } 387 388 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) { 389 int n = ik->local_interfaces()->length(); 390 jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n); 391 for (int i = 0; i < n; i++) { 392 InstanceKlass* e = ik->local_interfaces()->at(i); 393 jio_fprintf(defaultStream::error_stream(), " %s\n", e->name()->as_klass_external_name()); 394 } 395 jio_fprintf(defaultStream::error_stream(), "}\n"); 396 } 397 398 void ClassListParser::error(const char* msg, ...) { 399 va_list ap; 400 va_start(ap, msg); 401 int error_index = pointer_delta_as_int(_token, _line); 402 if (error_index >= _line_len) { 403 error_index = _line_len - 1; 404 } 405 if (error_index < 0) { 406 error_index = 0; 407 } 408 409 jio_fprintf(defaultStream::error_stream(), 410 "An error has occurred while processing class list file %s %zu:%d.\n", 411 _classlist_file, lineno(), (error_index + 1)); 412 jio_vfprintf(defaultStream::error_stream(), msg, ap); 413 414 if (_line_len <= 0) { 415 jio_fprintf(defaultStream::error_stream(), "\n"); 416 } else { 417 jio_fprintf(defaultStream::error_stream(), ":\n"); 418 for (int i=0; i<_line_len; i++) { 419 char c = _line[i]; 420 if (c == '\0') { 421 jio_fprintf(defaultStream::error_stream(), "%s", " "); 422 } else { 423 jio_fprintf(defaultStream::error_stream(), "%c", c); 424 } 425 } 426 jio_fprintf(defaultStream::error_stream(), "\n"); 427 for (int i=0; i<error_index; i++) { 428 jio_fprintf(defaultStream::error_stream(), "%s", " "); 429 } 430 jio_fprintf(defaultStream::error_stream(), "^\n"); 431 } 432 va_end(ap); 433 434 vm_exit_during_initialization("class list format error.", nullptr); 435 } 436 437 void ClassListParser::check_class_name(const char* class_name) { 438 const char* err = nullptr; 439 size_t len = strlen(class_name); 440 if (len > (size_t)Symbol::max_length()) { 441 err = "class name too long"; 442 } else { 443 assert(Symbol::max_length() < INT_MAX && len < INT_MAX, "must be"); 444 if (!UTF8::is_legal_utf8((const unsigned char*)class_name, (int)len, /*version_leq_47*/false)) { 445 err = "class name is not valid UTF8"; 446 } 447 } 448 if (err != nullptr) { 449 jio_fprintf(defaultStream::error_stream(), 450 "An error has occurred while processing class list file %s:%zu %s\n", 451 _classlist_file, lineno(), err); 452 vm_exit_during_initialization("class list format error.", nullptr); 453 } 454 } 455 456 // This function is used for loading classes for customized class loaders 457 // during archive dumping. 458 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) { 459 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS))) 460 // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and 461 // (3) MacOSX/64-bit and (4) Windowss/64-bit 462 // This #if condition should be in sync with the areCustomLoadersSupportedForCDS 463 // method in test/lib/jdk/test/lib/Platform.java. 464 error("AppCDS custom class loaders not supported on this platform"); 465 #endif 466 467 if (!is_super_specified()) { 468 error("If source location is specified, super class must be also specified"); 469 } 470 if (!is_id_specified()) { 471 error("If source location is specified, id must be also specified"); 472 } 473 if (strncmp(_class_name, "java/", 5) == 0) { 474 log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s", 475 _class_name, _source); 476 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 477 } 478 479 InstanceKlass* k = UnregisteredClasses::load_class(class_name, _source, CHECK_NULL); 480 const int actual_num_interfaces = k->local_interfaces()->length(); 481 const int specified_num_interfaces = _interfaces->length(); // specified in classlist 482 int expected_num_interfaces = actual_num_interfaces; 483 484 if (specified_num_interfaces != expected_num_interfaces) { 485 print_specified_interfaces(); 486 print_actual_interfaces(k); 487 error("The number of interfaces (%d) specified in class list does not match the class file (%d)", 488 specified_num_interfaces, expected_num_interfaces); 489 } 490 491 assert(k->is_shared_unregistered_class(), "must be"); 492 493 bool added = SystemDictionaryShared::add_unregistered_class(THREAD, k); 494 if (!added) { 495 // We allow only a single unregistered class for each unique name. 496 error("Duplicated class %s", _class_name); 497 } 498 499 return k; 500 } 501 502 void ClassListParser::populate_cds_indy_info(const constantPoolHandle &pool, int cp_index, CDSIndyInfo* cii, TRAPS) { 503 // Caller needs to allocate ResourceMark. 504 int type_index = pool->bootstrap_name_and_type_ref_index_at(cp_index); 505 int name_index = pool->name_ref_index_at(type_index); 506 cii->add_item(pool->symbol_at(name_index)->as_C_string()); 507 int sig_index = pool->signature_ref_index_at(type_index); 508 cii->add_item(pool->symbol_at(sig_index)->as_C_string()); 509 int argc = pool->bootstrap_argument_count_at(cp_index); 510 if (argc > 0) { 511 for (int arg_i = 0; arg_i < argc; arg_i++) { 512 int arg = pool->bootstrap_argument_index_at(cp_index, arg_i); 513 jbyte tag = pool->tag_at(arg).value(); 514 if (tag == JVM_CONSTANT_MethodType) { 515 cii->add_item(pool->method_type_signature_at(arg)->as_C_string()); 516 } else if (tag == JVM_CONSTANT_MethodHandle) { 517 cii->add_ref_kind(pool->method_handle_ref_kind_at(arg)); 518 int callee_index = pool->method_handle_klass_index_at(arg); 519 Klass* callee = pool->klass_at(callee_index, CHECK); 520 cii->add_item(callee->name()->as_C_string()); 521 cii->add_item(pool->method_handle_name_ref_at(arg)->as_C_string()); 522 cii->add_item(pool->method_handle_signature_ref_at(arg)->as_C_string()); 523 } else { 524 ShouldNotReachHere(); 525 } 526 } 527 } 528 } 529 530 bool ClassListParser::is_matching_cp_entry(const constantPoolHandle &pool, int cp_index, TRAPS) { 531 ResourceMark rm(THREAD); 532 CDSIndyInfo cii; 533 populate_cds_indy_info(pool, cp_index, &cii, CHECK_0); 534 GrowableArray<const char*>* items = cii.items(); 535 int indy_info_offset = 1; 536 if (_indy_items->length() - indy_info_offset != items->length()) { 537 return false; 538 } 539 for (int i = 0; i < items->length(); i++) { 540 if (strcmp(_indy_items->at(i + indy_info_offset), items->at(i)) != 0) { 541 return false; 542 } 543 } 544 return true; 545 } 546 547 void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbol) { 548 ExceptionMark em(current); 549 JavaThread* THREAD = current; // For exception macros. 550 ClassListParser::resolve_indy_impl(class_name_symbol, THREAD); 551 if (HAS_PENDING_EXCEPTION) { 552 ResourceMark rm(current); 553 char* ex_msg = (char*)""; 554 oop message = java_lang_Throwable::message(PENDING_EXCEPTION); 555 if (message != nullptr) { 556 ex_msg = java_lang_String::as_utf8_string(message); 557 } 558 log_warning(cds)("resolve_indy for class %s has encountered exception: %s %s", 559 class_name_symbol->as_C_string(), 560 PENDING_EXCEPTION->klass()->external_name(), 561 ex_msg); 562 CLEAR_PENDING_EXCEPTION; 563 } 564 } 565 566 void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) { 567 Handle class_loader(THREAD, SystemDictionary::java_system_loader()); 568 Handle protection_domain; 569 Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK); 570 if (klass->is_instance_klass()) { 571 InstanceKlass* ik = InstanceKlass::cast(klass); 572 MetaspaceShared::try_link_class(THREAD, ik); 573 if (!ik->is_linked()) { 574 // Verification of ik has failed 575 return; 576 } 577 578 ConstantPool* cp = ik->constants(); 579 ConstantPoolCache* cpcache = cp->cache(); 580 bool found = false; 581 for (int indy_index = 0; indy_index < cpcache->resolved_indy_entries_length(); indy_index++) { 582 int pool_index = cpcache->resolved_indy_entry_at(indy_index)->constant_pool_index(); 583 constantPoolHandle pool(THREAD, cp); 584 BootstrapInfo bootstrap_specifier(pool, pool_index, indy_index); 585 Handle bsm = bootstrap_specifier.resolve_bsm(CHECK); 586 if (!SystemDictionaryShared::is_supported_invokedynamic(&bootstrap_specifier)) { 587 log_debug(cds, lambda)("is_supported_invokedynamic check failed for cp_index %d", pool_index); 588 continue; 589 } 590 bool matched = is_matching_cp_entry(pool, pool_index, CHECK); 591 if (matched) { 592 found = true; 593 CallInfo info; 594 bool is_done = bootstrap_specifier.resolve_previously_linked_invokedynamic(info, CHECK); 595 if (!is_done) { 596 // resolve it 597 Handle recv; 598 LinkResolver::resolve_invoke(info, 599 recv, 600 pool, 601 indy_index, 602 Bytecodes::_invokedynamic, CHECK); 603 break; 604 } 605 cpcache->set_dynamic_call(info, indy_index); 606 } 607 } 608 if (!found) { 609 ResourceMark rm(THREAD); 610 log_warning(cds)("No invoke dynamic constant pool entry can be found for class %s. The classlist is probably out-of-date.", 611 class_name_symbol->as_C_string()); 612 } 613 } 614 } 615 616 Klass* ClassListParser::load_current_class(Symbol* class_name_symbol, TRAPS) { 617 Klass* klass; 618 if (!is_loading_from_source()) { 619 // Load classes for the boot/platform/app loaders only. 620 if (is_super_specified()) { 621 error("If source location is not specified, super class must not be specified"); 622 } 623 if (are_interfaces_specified()) { 624 error("If source location is not specified, interface(s) must not be specified"); 625 } 626 627 if (Signature::is_array(class_name_symbol)) { 628 // array classes are not supported in class list. 629 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 630 } 631 632 JavaValue result(T_OBJECT); 633 // Call java_system_loader().loadClass() directly, which will 634 // delegate to the correct loader (boot, platform or app) depending on 635 // the package name. 636 637 // ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.' 638 Handle ext_class_name = java_lang_String::externalize_classname(class_name_symbol, CHECK_NULL); 639 Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); 640 641 JavaCalls::call_virtual(&result, 642 loader, //SystemDictionary::java_system_loader(), 643 vmClasses::ClassLoader_klass(), 644 vmSymbols::loadClass_name(), 645 vmSymbols::string_class_signature(), 646 ext_class_name, 647 CHECK_NULL); 648 649 assert(result.get_type() == T_OBJECT, "just checking"); 650 oop obj = result.get_oop(); 651 assert(obj != nullptr, "jdk.internal.loader.BuiltinClassLoader::loadClass never returns null"); 652 klass = java_lang_Class::as_Klass(obj); 653 } else { 654 // If "source:" tag is specified, all super class and super interfaces must be specified in the 655 // class list file. 656 klass = load_class_from_source(class_name_symbol, CHECK_NULL); 657 } 658 659 assert(klass != nullptr, "exception should have been thrown"); 660 assert(klass->is_instance_klass(), "array classes should have been filtered out"); 661 662 if (is_id_specified()) { 663 InstanceKlass* ik = InstanceKlass::cast(klass); 664 int id = this->id(); 665 SystemDictionaryShared::update_shared_entry(ik, id); 666 bool created; 667 id2klass_table()->put_if_absent(id, ik, &created); 668 if (!created) { 669 error("Duplicated ID %d for class %s", id, _class_name); 670 } 671 if (id2klass_table()->maybe_grow()) { 672 log_info(cds, hashtables)("Expanded id2klass_table() to %d", id2klass_table()->table_size()); 673 } 674 } 675 676 return klass; 677 } 678 679 bool ClassListParser::is_loading_from_source() { 680 return (_source != nullptr); 681 } 682 683 InstanceKlass* ClassListParser::lookup_class_by_id(int id) { 684 InstanceKlass** klass_ptr = id2klass_table()->get(id); 685 if (klass_ptr == nullptr) { 686 error("Class ID %d has not been defined", id); 687 } 688 assert(*klass_ptr != nullptr, "must be"); 689 return *klass_ptr; 690 } 691 692 693 InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) { 694 if (!is_loading_from_source()) { 695 return nullptr; 696 } 697 698 InstanceKlass* k = lookup_class_by_id(super()); 699 if (super_name != k->name()) { 700 error("The specified super class %s (id %d) does not match actual super class %s", 701 k->name()->as_klass_external_name(), super(), 702 super_name->as_klass_external_name()); 703 } 704 return k; 705 } 706 707 InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) { 708 if (!is_loading_from_source()) { 709 return nullptr; 710 } 711 712 const int n = _interfaces->length(); 713 if (n == 0) { 714 error("Class %s implements the interface %s, but no interface has been specified in the input line", 715 _class_name, interface_name->as_klass_external_name()); 716 ShouldNotReachHere(); 717 } 718 719 int i; 720 for (i=0; i<n; i++) { 721 InstanceKlass* k = lookup_class_by_id(_interfaces->at(i)); 722 if (interface_name == k->name()) { 723 return k; 724 } 725 } 726 727 // interface_name is not specified by the "interfaces:" keyword. 728 print_specified_interfaces(); 729 error("The interface %s implemented by class %s does not match any of the specified interface IDs", 730 interface_name->as_klass_external_name(), _class_name); 731 ShouldNotReachHere(); 732 return nullptr; 733 }