void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
                                            KlassHandle resolved_klass,
                                            Symbol* method_name,
                                            Symbol* method_signature,
                                            KlassHandle current_klass,
                                            bool check_access,
                                            bool nostatics, TRAPS) {

  // check if klass is interface
  if (!resolved_klass->is_interface()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

  // lookup method in this interface or its super, java.lang.Object
  // JDK8: also look for static methods
  lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);

  if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
    // lookup method in all the super-interfaces
    lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
  }

  if (resolved_method.is_null()) {
    // no method found
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
              Method::name_and_sig_as_C_string(resolved_klass(),
                                                      method_name,
                                                      method_signature));
  }

  if (check_access) {
    // JDK8 adds non-public interface methods, and accessability check requirement
    assert(current_klass.not_null() , "current_klass should not be null");

    // check if method can be accessed by the referring class
    check_method_accessability(current_klass,
                               resolved_klass,
                               KlassHandle(THREAD, resolved_method->method_holder()),
                               resolved_method,
                               CHECK);

    check_method_loader_constraints(resolved_method, resolved_klass, method_name,
                                    method_signature, current_klass, "interface method", CHECK);
  }

  if (nostatics && resolved_method->is_static()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
                 Method::name_and_sig_as_C_string(resolved_klass(),
                 resolved_method->name(), resolved_method->signature()));
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

  if (TraceItables && Verbose) {
    ResourceMark rm(THREAD);
    tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
                   (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
                   (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
                   Method::name_and_sig_as_C_string(resolved_klass(),
                                                    resolved_method->name(),
                                                    resolved_method->signature()),
                   resolved_method->method_holder()->internal_name()
                  );
    resolved_method->access_flags().print_on(tty);
    if (resolved_method->is_default_method()) {
      tty->print("default ");
    }
    if (resolved_method->is_overpass()) {
      tty->print("overpass");
    }
    tty->cr();
  }
}
void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
                                            KlassHandle resolved_klass,
                                            Symbol* method_name,
                                            Symbol* method_signature,
                                            KlassHandle current_klass,
                                            bool check_access,
                                            bool nostatics, TRAPS) {

   
  if (!resolved_klass->is_interface()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

   
   
  lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);

  if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
     
    lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
  }

  if (resolved_method.is_null()) {
     
    ResourceMark rm(THREAD);
    THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
              Method::name_and_sig_as_C_string(resolved_klass(),
                                                      method_name,
                                                      method_signature));
  }

  if (check_access) {
     
    assert(current_klass.not_null() , "current_klass should not be null");

     
    check_method_accessability(current_klass,
                               resolved_klass,
                               KlassHandle(THREAD, resolved_method->method_holder()),
                               resolved_method,
                               CHECK);

    check_method_loader_constraints(resolved_method, resolved_klass, method_name,
                                    method_signature, current_klass, "interface method", CHECK);
  }

  if (nostatics && resolved_method->is_static()) {
    ResourceMark rm(THREAD);
    char buf[200];
    jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
                 Method::name_and_sig_as_C_string(resolved_klass(),
                 resolved_method->name(), resolved_method->signature()));
    THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  }

  if (TraceItables && Verbose) {
    ResourceMark rm(THREAD);
    tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
                   (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
                   (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
                   Method::name_and_sig_as_C_string(resolved_klass(),
                                                    resolved_method->name(),
                                                    resolved_method->signature()),
                   resolved_method->method_holder()->internal_name()
                  );
    resolved_method->access_flags().print_on(tty);
    if (resolved_method->is_default_method()) {
      tty->print("default ");
    }
    if (resolved_method->is_overpass()) {
      tty->print("overpass");
    }
    tty->cr();
  }
}