Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8276963

NoSuchMethod error when library updates return type to more specific class

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Not an Issue
    • Affects Version/s: 11
    • Fix Version/s: None
    • Component/s: hotspot
    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      ADDITIONAL SYSTEM INFORMATION :
      Tested in Linux using java 11 but it probably happens in all versions of java

      A DESCRIPTION OF THE PROBLEM :
      If a library has a method with return type T and changes it to return type T2 that extends T (i.e. T2 IS-A T by definition of inheritance), Java throws a NoSuchMethodError

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create 2 versions of a given lib (source code in the source code section).
      - Compile and create a lib_v1.jar
      - Compile and create a lib_v2.jar

      Now, lets create an application that uses the lib.

      import lib.*;

      public class Main {
        public static void main(String args[]) {
          A a = new A();
          a.get().m();
        }
      }

      Compile using lib_v1.jar. It will execute correctly. Without recompiling, execute using lib_v2.jar.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      It should execute and show "Extended Base class" in the console
      ACTUAL -
      Exception in thread "main" java.lang.NoSuchMethodError: 'lib.BaseClass lib.A.get()'
      at Main.main(Main.java:6)


      ---------- BEGIN SOURCE ----------
      lib v1:

      package lib;

      public class BaseClass {
        public void m() {
          System.out.println("Base class");
        }
      }

      package lib;

      public class A {
        public BaseClass get() {
          return new BaseClass();
        }
      }


      lib v2:

      package lib;

      public class A {
        public ExtendedBaseClass get() {
          return new ExtendedBaseClass();
        }
      }


      package lib;

      public class BaseClass {
        public void m() {
          System.out.println("Base class");
        }
      }


      Create a new application that uses that lib:

      import lib.*;

      public class Main {
        public static void main(String args[]) {
          A a = new A();
          a.get().m();
        }
      }

      package lib;

      public class ExtendedBaseClass extends BaseClass {
        public void m() {
          System.out.println("Extended Base class");
        }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      If we have access to the source code, recompile against the new version of the lib. But if we don't it means we can't upgrade the library (could be a library used by another library).

      FREQUENCY : always


        Attachments

          Activity

            People

            Assignee:
            Unassigned Unassigned
            Reporter:
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: