Class invoking method which exists as default on interface and private on super
Michael Rasmussen
Michael.Rasmussen at roguewave.com
Tue Feb 13 16:33:43 UTC 2018
Hi
If I try to invoke a method that has a default implementation on an implementing interface, and a private implementation on the super class, the compilation passes, yet at runtime running the code produces an IllegalAccessError, trying to invoke the private method.
In the code below, the first line of Test.run compiles into an invokeinterface, and the second compiles into invokevirtual.
(javac from 8u152, 9.0.1 and 10-ea43 all produce that).
Running the code (on the Oracle builds listed above) those throws an IllegalAccessError when running the invokeinterface; presumably trying to invoke the private method on C.
Similarly, if commenting out the first line, the invokevirtual call fails with a similar IllegalAccessError.
For comparison, compiling it with IBM J9 8.0.5.5, it produces the same bytecode, but at runtime, the invokeinterface calls the default interface method, and the invokevirtual call fails with IllegalAccessError.
Seeing that the code compiles without warning, yet fails at runtime, I don't know if this should have been a compiler error instead?
Or in case this is an issue with the method lookup at runtime, which list would be appropriate to forward this to?
Kind regards
Michael Rasmussen
// -- app1/pkg/C.java
package app1.pkg;
public class C {
private void foo() {
System.out.println("C.foo");
}
}
// -- app1/pkg/I.java
package app1.pkg;
public interface I {
public default void foo() {
System.out.println("I.foo");
}
}
// -- app1/pkg/Test.java
package app1.pkg;
public class Test extends C implements I {
public void run() {
((I)this).foo();
foo();
}
public static void main(String[] args) {
new Test().run();
}
}
More information about the compiler-dev
mailing list