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

javac prefers method argument errors over visibility errors

XMLWordPrintable

    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      When code calls a method with the wrong arguments (wrong type or wrong number of args) and that method is also inaccessible to the caller, then javac prefers reporting the argument errors over the visibility error.

      This can be rather confusing. Instead, javac should prefer (respectively only) report the visibility error in this case because it is likely the more important error.

      Relates to JDK-8255968

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Consider this example:
      ```
      // A.java
      class A {
          private static void dofoo(boolean b) {
          }

          public static void doFoo(String s) {
          }
      }

      // B.java
      class B {
          public static void main(String... args) {
              // error 1: argument mismatch
              A.dofoo("a");
              // error 2: actual and formal argument lists differ in length
              A.dofoo();

              // error 3: has private access
      A.dofoo(true);
          }
      }
      ```

      Try to compile this with `javac B.java`

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      javac should always prefer reporting visibility errors first, even if there are argument errors as well.

      Otherwise it is just confusing if the compiler tells the user that their arguments are incorrect if the method is inaccessible to the user anyway, especially if the user made a typo in the method name and the javac error now refers to an internal method for which the user can see no documentation and has no clue what javac is referring to.
      ACTUAL -
      Error 1 and 2 are unexpected: They complain about wrong arguments even though the method is inaccessible. Only when provided with the correct arguments, javac reports that the method is inaccessible, as expected (error 3).
      Now consider that this happens to a new Java user who made a typo and wrote a lowercase "f" in "dofoo" instead of "doFoo", and that class A is a library class. Then the compiler error in cases 1 and 2 refers to some internal method which the user cannot see, and they will be rather confused.

      An example for this can also be seen in JDK 17 with `java.io.Console` (not in newer versions due to internal refactoring, but other classes in the JDK or external libraries will probably have similar situations):
      `System.console().readline("my message")`
      This fails with "incompatible types: String cannot be converted to boolean". Why? Because there is a typo, the call uses a lowercase "l" in "readline" instead of uppercase "readLine", so this refers to an internal method instead of the public one. But the javac error is completely misleading.

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

              Created:
              Updated:
              Resolved: