Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 481186

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: CoreAssignee: 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:
Description Flags
Sample program none

Description Felipe Pontes CLA 2015-11-01 08:57:57 EST
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
Comment 1 Jay Arthanareeswaran CLA 2015-11-02 00:07:05 EST
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?
Comment 2 Sasikanth Bharadwaj CLA 2015-11-23 04:18:23 EST
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
Comment 3 Sasikanth Bharadwaj CLA 2015-12-09 23:34:20 EST
*** Bug 483958 has been marked as a duplicate of this bug. ***
Comment 4 Stephan Herrmann CLA 2015-12-10 11:37:14 EST
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).
Comment 5 Stephan Herrmann CLA 2015-12-10 11:41:25 EST
BTW, generics don't seem to be required to reproduce the issue(s):

	private void y(Object t) {
	}
Comment 6 Eclipse Genie CLA 2019-12-21 18:07:27 EST
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.