JDK-6805143 : javac doesn't compile static method invocation in UTF_8_new
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6u10
  • Priority: P3
  • Status: Closed
  • Resolution: Not an Issue
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2009-02-13
  • Updated: 2011-02-16
  • Resolved: 2009-02-13
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.6.0_03"
Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Windows XP SR-2

A DESCRIPTION OF THE PROBLEM :
javac doesn't compile static method invocation written without class identifier:
    underflow(src, mark);
in line 179 of source code.


ERROR MESSAGES/STACK TRACES THAT OCCUR :
C:\Projects\nio_charset\test\sun\nio\cs\UTF_8_new.java:180: cannot find symbol
symbol  : method underflow(java.nio.ByteBuffer,int)
location: class sun.nio.cs.UTF_8_new.Decoder
            return underflow(src, mark);


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
See:
https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/trunk/test/sun/nio/cs/UTF_8_new.java?diff_format=s&rev=624&view=markup
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
UTF_8_new.underflow(src, mark);

Comments
EVALUATION This is a simplified test case: class Test { static void m() {} static class Inner { static void m(int i1) {} //1 static void m(int i1, int i2) {} //2 static void test() { m(); //error } } } If you compile this you get: TestX.java:8: cannot find symbol symbol : method m() location: class Test.Inner m(); //error ^ 1 error Which I agree is abit counter-intuitive (there are at least 3 methods named m() accessible from Inner. But this is a javac diagnostic bug which is described in 5088624. If you remove (1), then the message become more intelligible: maurizio@maurizio-laptop:~/Desktop$ javac TestX.java TestX.java:8: m(int) in Test.Inner cannot be applied to () m(); //error ^ 1 error Which makes it clear that javac is only considering methods declared inside Inner. On the other hand, if you remove both //1 and //2, the program compiles without errors. This behavior is justified by JLS3, section 15.12.1 (Determoine class of interface to search): "If the form is MethodName, then there are three subcases: * If it is a simple name, that is, just an Identifier, then the name of the method is the Identifier. If the Identifier appears within the scope (��6.3) of a visible method declaration with that name, then there must be an enclosing type declaration of which that method is a member. Let T be the innermost such type declaration. The class or interface to search is T." Which means that if only a simple name N is specified, the class/interface to search for applicable methods is the one in which scope there are methods with the same name as N. Which means that, both in the first and second case, since a method named 'm' is found inside Inner, Inner becomes the class to be searched for methods. In the third case, since there are no methods 'm' declared in Inner, then the innermost lexically enclosing scope is searched, so that Test.m() is retrieved. BTW, the output you'd get once 5088624 will be fixed will be: TestX.java:8: no suitable method found for m() m(); //error ^ inapplicable method found: Inner.m(int,int) (actual and formal argument lists differ in length) inapplicable method found: Inner.m(int) (actual and formal argument lists differ in length) 1 error Which will make it clearer to understand that only methods declared within Inner have been consider during overload resolution.
13-02-2009