JDK-7013170 : varargs: accessibility check missing from JLS 15.12.{2,4}
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: unknown
  • Submitted: 2011-01-19
  • Updated: 2014-03-07
  • Resolved: 2011-07-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 rcFixed
Related Reports
Relates :  
Relates :  
Description
Quoting from 6313164:

"As written, the specification supports the implemented behavior. It would seem
reasonable to expect a compile-time error if the type of a var-arg formal parameter were
inaccessible. One might debate if, in such a circumstance, the method should even be
considered applicable.

However, the only sane path is to consider the call equivalent to its translation,
not only at run time (which it already is), but at compile time.

This may lead to difficulties with generic methods. It is therefore necessary to
specify he check explicitly. In JLS 15.12.4.3, one would add the check:

If all of the following conditions hold

a. The compile-time declaration of the method invocation is a variable arity method m.
b. The inferred type of the final formal parameter of m for this invocation is T[].
c. m is invoked with actual argument expressions (e1 ... en-1, en, ..., ek)
d. m is being invoked with k != n actual argument expressions, or, 
   m is being invoked with k = n actual argument expressions and the type of the
   kth argument expressions is not assignment compatible with T[]

then it is a compile time error if the erasure of T is not accessible at the point of invocation."

Comments
EVALUATION Here is the case from 6313164: "suppose class A is package private, class B is public and in the same package as A and extends A, a public method on B has the signature of foo(A... args). class C is in a different package, and has an invocation of foo(new B(), new B()) class C will compile, but the resulting byte code does not run (gets an java.lang.IllegalAccessError), since javac would generate a new A[] call for class C for the varargs invocation." Method resolution does not check accessibility of formal parameter types explicitly. Accessibility is checked implicitly at compile-time when the actual parameter type B is checked to be a subtype of the formal parameter type A. But that's accessibility of A from B's perspective (success), not accessibility of A from C's perspective (which would fail). Since C needs to perform 'new A[]', an explicit compile-time check is necessary. This is truly a varargs issue; if B.foo simply took an A, then A does not need to be accessible to C at compile-time or even at runtime. JLS 15.12.4 describes runtime behavior so I don't think it's the right place for a compile-time error. (There is only one compile-time error in 15.12.4 today, and it is already ill-formed because it mentions an _instance_ in a compile-time context.) I propose to put the new check near the end of 15.12.2.4, where we already know that Sn to be the final element type of the varargs formal parameter. (Specifically, we know Fn=T[] and Sn=T. No mention is made of 'new Sn[] {..}' here. Note that Sn could itself be an array type.) "The method m is an applicable variable-arity method if and only if all ***four*** of the following conditions hold: ... - 1<=i<n: the type of ei, Ai, can be converted by method invocation conversion to Si. - k>=n: the type of ei, Ai, can be converted by method invocation conversion to the component type of Sn. - [actual/inferred type arguments are compatible with formal type parameters] ****- if k!=n, or if k=n and Ak cannot be converted by method invocation conversion to Sn[], then the erasure of Sn is accessible at the point of invocation.****" Thus a variable-arity method is applicable only if the statically-known array type is accessible.
19-01-2011