| Summary: | ECJ and Java Oracle JDK different compilation results when a private method is searched via super and outer | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Felipe Pontes <felipepontes> | ||||
| Component: | Core | Assignee: | JDT-Core-Inbox <jdt-core-inbox> | ||||
| Status: | CLOSED WONTFIX | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | P3 | CC: | jarthana, stephan.herrmann | ||||
| Version: | 4.4.2 | ||||||
| Target Milestone: | --- | ||||||
| Hardware: | PC | ||||||
| OS: | Windows 8 | ||||||
| Whiteboard: | stalebug | ||||||
| Attachments: |
|
||||||
From my understanding, I don't see any version of y that takes Object as an argument. I think Javac is correct here. Stephan, can you confirm, please? The method Y(T t) in A is private, but as B is a member type, we allow access to A's method in B and do not report an error where as javac reports the error. Changing the invocation to super.y(new Object()) causes javac to accept the code as well which makes me think that it is a bug in javac. Couldn't yet find what the spec says about accessing private methods in member types *** Bug 483958 has been marked as a duplicate of this bug. *** Some more ways to let javac accept:
//--- (1) ---
public class A {
private <T extends Object> void y(T t) {
}
public class B extends A {
public void x(Long a) { // name change
y(new Object());
}
}
}
//---
//--- (2) ---
public class A {
private <T extends Object> void y(T t) {
}
public class B extends A {
public void y(Long a) {
A.this.y(new Object()); // explicit receiver
}
}
}
//---
It seems that javac, upon seeing a method with matching name (not checking signatures) decides to look in B's hierarchy and is locked to this decision.
ECJ by contrast resolves comment 0 just like variant (2).
There's still one more issue to the equation, the following is rejected also by ECJ:
//--- (3) ---
public class A {
private <T extends Object> void y(T t) {
}
public class B { // no inheritance
public void y(Long a) {
y(new Object());
}
}
}
//---
It seems that ECJ in the original version *finds* A.y(T) via hierarchy search, but then *re-interprets* the found method as being invoked on an outer instance. If that's the reason why we accept comment 0 then this looks bogus, indeed.
When looking at the super.y(new Object()) variant, I start to believe that both compilers generate the synthetic accessor for the private outer method, and then happily use this accessor even in non-outer invocations (sometimes).
BTW, generics don't seem to be required to reproduce the issue(s):
private void y(Object t) {
}
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. |
Created attachment 257668 [details] Sample program The following sample program presents different compilation results when compiling in ECJ and in Oracle JDK. Should it be compilable? Program public class A { private <T extends Object> void y(T t) { } public class B extends A { public void y(Long a) { y(new Object()); } } } Results ECJ: No compilation errors. Java Oracle JDK: A.java:8: error: method y in class A.B cannot be applied to given types; y(new Object()); ^ required: Long found: Object reason: argument mismatch; Object cannot be converted to Long 1 error Configuration Software O.S.: Windows 8.1 64bits Java Oracle JDK: java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b15) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode) ECJ: org.eclipse.jdt.core_3.10.2.v20150120-1634.jar (Eclipse Luna 4.4.2) Hardware: Intel Core i5-2410M 2.3 GHz