Skip to content

Inconsistent Handling of Method Resolution Between javac and ECJ #3994

Description

@yingquanzhao

Environment:

ECJ Version:

Eclipse Compiler for Java(TM) v20250319-0432, 3.41.100, Copyright IBM Corp 2000, 2020. All rights reserved.

Java Version:

openjdk version "11.0.27" 2025-04-15
OpenJDK Runtime Environment Temurin-11.0.27+6 (build 11.0.27+6)
OpenJDK 64-Bit Server VM Temurin-11.0.27+6 (build 11.0.27+6, mixed mode)

openjdk version "17.0.15" 2025-04-15
OpenJDK Runtime Environment Temurin-17.0.15+6 (build 17.0.15+6)
OpenJDK 64-Bit Server VM Temurin-17.0.15+6 (build 17.0.15+6, mixed mode, sharing)

openjdk version "21.0.7" 2025-04-15 LTS
OpenJDK Runtime Environment Temurin-21.0.7+6 (build 21.0.7+6-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.7+6 (build 21.0.7+6-LTS, mixed mode, sharing)

Javac Version:

javac 11.0.27
javac 17.0.15
javac 21.0.7

Description:

Hi, We have identified a test program that triggers inconsistent behavior between javac and ECJ. The minimal reproducible version of the program is as follows:

public class Test {
    public static void main(String[] args) {
        java.lang.StackWalker walker = java.lang.StackWalker.getInstance(java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE);
        java.lang.System.getLogger("AnyLogger").log(java.lang.System.Logger.Level.DEBUG, walker.walk(s -> s.collect(java.util.stream.Collectors.toList())));
    }
}

When compiling this code with javac of JDK 11, 17, or 21, the compiler throws the following errors:

>>>pathToJDK21/javac Test.java

Test.java:4: error: reference to log is ambiguous
        java.lang.System.getLogger("AnyLogger").log(java.lang.System.Logger.Level.DEBUG, walker.walk(s -> s.collect(java.util.stream.Collectors.toList())));
                                               ^
  both method log(Level,String) in Logger and method log(Level,Supplier<String>) in Logger match
Test.java:4: error: incompatible types: inference variable T#1 has incompatible bounds
        java.lang.System.getLogger("AnyLogger").log(java.lang.System.Logger.Level.DEBUG, walker.walk(s -> s.collect(java.util.stream.Collectors.toList())));
                                                                                                    ^
    upper bounds: String,Object
    lower bounds: List<T#2>,R
  where T#1,T#2,R,A,T#3 are type-variables:
    T#1 extends Object declared in method <T#1>walk(Function<? super Stream<StackFrame>,? extends T#1>)
    T#2 extends Object declared in method <T#2>toList()
    R extends Object declared in method <R,A>collect(Collector<? super T#3,A,R>)
    A extends Object declared in method <R,A>collect(Collector<? super T#3,A,R>)
    T#3 extends Object declared in interface Stream
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
2 errors

However, when compiling the same program using ECJ (version 4.36) with --release 21, no error is reported, and the class file is generated successfully:

>>>java -jar ecj-4.36.jar --release 21 -d . Test.java

Would appreciate your insights into this issue. Thanks!

Steps to Reproduce:

Compile the test program using Javac and ECJ:

>>>javac Test.java

>>>java -jar ecj-4.36.jar --release 21 -d . Test.java
  • Expected behavior: ECJ should reject the test program with a compilation error.
  • Actual behavior: ECJ compiles the program without any errors and generates an executable file.

Metadata

Metadata

Labels

javacecj not compatible with javac

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions