Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extending an inner interface can cause a bounds mismatch error #1069

Open
niloc132 opened this issue May 17, 2023 · 10 comments
Open

Extending an inner interface can cause a bounds mismatch error #1069

niloc132 opened this issue May 17, 2023 · 10 comments
Assignees

Comments

@niloc132
Copy link

Steps to reproduce:

Compile these two classes using the JDT compiler:

public interface ParentInterface<U extends ParentInterfaceHandler> {

  interface ParentInterfaceHandler {

  }
}
public interface ChildInterface extends ParentInterface<ChildInterfaceHandler> {

  interface ChildInterfaceHandler extends ParentInterfaceHandler {
  }
}

For example, using this maven pom.xml and running mvn clean verify:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>9829-test-case</groupId>
  <artifactId>9829-test-case</artifactId>
  <version>1.0-SNAPSHOT</version>

  <properties>
    <maven.compiler.source>11</maven.compiler.source>
    <maven.compiler.target>11</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.11.0</version>
        <configuration>
          <compilerId>eclipse</compilerId>
        </configuration>
        <dependencies>
          <dependency>
            <groupId>org.codehaus.plexus</groupId>
            <artifactId>plexus-compiler-eclipse</artifactId>
            <version>2.13.0</version>
          </dependency>
        </dependencies>
      </plugin>
    </plugins>
  </build>
</project>

Expected

Interfaces should compile to .class files with no errors

Actual

[INFO] Compiling with eclipse [debug target 11] to target/classes
[INFO] -------------------------------------------------------------
[ERROR] COMPILATION ERROR : 
[INFO] -------------------------------------------------------------
[ERROR] /home/colin/workspace/gwt/9829-test-case/src/main/java/org/dominokit/test/ChildInterface.java:[5,57] Bound mismatch: The type org.dominokit.test.ChildInterface.ChildInterfaceHandler is not a valid substitute for the bounded parameter <U extends org.dominokit.test.ParentInterface.ParentInterfaceHandler> of the type org.dominokit.test.ParentInterface<U>
[ERROR] /home/colin/workspace/gwt/9829-test-case/src/main/java/org/dominokit/test/ChildInterface.java:[7,43] ParentInterfaceHandler cannot be resolved to a type
[INFO] 2 errors 
[INFO] -------------------------------------------------------------

Workaround

Changing the ChildInterfaceHandler definition to be ParentInterface.ParentInterfaceHandler instead of simply ParentInterfaceHandler (as inherited by being an inner type within ChildInterface extends ParentInterface<..>) seems to function as a workaround.

@srikanth-sankaran
Copy link
Contributor

I don't know about maven/pom parts, but compiling the test case in the top with javac produces identical errors:

 javac ParentInterface.java ChildInterface.java
ParentInterface.java:1: error: cannot find symbol
public interface ParentInterface<U extends ParentInterfaceHandler> {
                                           ^
  symbol: class ParentInterfaceHandler
ChildInterface.java:1: error: cannot find symbol
public interface ChildInterface extends ParentInterface<ChildInterfaceHandler> {
                                                        ^
  symbol: class ChildInterfaceHandler
2 errors

I don't see a compiler bug here - At the point (both) the compilers are complaining about the names are not in scope unless qualified with the enclosing types (which themselves are in scope)

Unless further clarifications are offered that points to a real compiler problem, I will close this in a day or two with no action.

Let me know if I misunderstand something in the picture. TIA

@niloc132
Copy link
Author

niloc132 commented May 18, 2023

I'm afraid I'm not following, or can't reproduce the error in javac as you have it. I've made a git repo to demonstrate this, with a simple profile to switch between jdt and javac.

https://github.com/niloc132/9829-test-case

Can also confirm with this that javac (tested 11.0.19+7), there are no errors:

➜  9829-test-case git:(main) java -version
openjdk version "11.0.19" 2023-04-18
OpenJDK Runtime Environment (build 11.0.19+7)
OpenJDK 64-Bit Server VM (build 11.0.19+7, mixed mode)
➜  9829-test-case git:(main) mkdir out
➜  9829-test-case git:(main) javac -d out src/main/java/org/dominokit/test/*
➜  9829-test-case git:(main) find out
out
out/org
out/org/dominokit
out/org/dominokit/test
out/org/dominokit/test/ChildInterface.class
out/org/dominokit/test/ParentInterface$ParentInterfaceHandler.class
out/org/dominokit/test/ParentInterface.class
out/org/dominokit/test/ChildInterface$ChildInterfaceHandler.class

@srikanth-sankaran
Copy link
Contributor

srikanth-sankaran commented May 23, 2023

See https://bugs.eclipse.org/bugs/show_bug.cgi?id=577041

I am still not convinced there is an ECJ issue here. If you are able to show case a code snippet that compiles with javac and fails with ECJ that would help - outside of any scaffolds (such as maven)

@niloc132
Copy link
Author

I am still not convinced there is an ECJ issue here. If you are able to show case a code snippet that compiles with javac and fails with ECJ that would help - outside of any scaffolds (such as maven)

That's the second example I gave, please see the javac call from my last comment - the last code snippet is using bash+javac, with no involvement from the pom.xml, and correctly compiles both .java files into four .class files. It only uses the git repo as a way to share the same files. Are you not able to reproduce this? If not, I'll try on a few more machines*versions and see if there is some specific set of versions required.

@srikanth-sankaran srikanth-sankaran self-assigned this May 23, 2023
@srikanth-sankaran
Copy link
Contributor

OK, the sources inside the github example project have import statements which are missing in the example in the top in this ticket. That is one source of confusion.

I can observe the difference in behavior now, I'll investigate

@niloc132
Copy link
Author

Glad you got it working - I'll try to avoid this confusion next time, by starting with a full example project.

@srikanth-sankaran
Copy link
Contributor

Minimal single file example that still illustrates the problem and compiles with javac and fails to compile with ECJ:

public interface X<T> {
	interface I {
	}
}

interface Y extends X<Y.J> {
	interface J extends I {
	}
}

@srikanth-sankaran
Copy link
Contributor

@srikanth-sankaran
Copy link
Contributor

@srikanth-sankaran
Copy link
Contributor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants