Skip to content

"Reference to X is ambiguous" compiling Java code #13106

Closed
@ignasi35

Description

@ignasi35

The Akka codebase includes some Java code resulting from code generation using protoc from .protobuf files. This Java code is kept under SCM (git) so it is not regenerated over and over.

A particular protobuf file uses protobuf inner messages that result into generating inner classes when producing Java classes for the protobuf messages. Each of the generated classes includes a Builder inner class.

Compiling code that uses those Builder classes produces the following compiler error:

[error] -- [E049] Reference Error: /Users/ignasi/git/github/akka/akka/akka-persistence-scala3/akka-persistence/src/main/java/akka/persistence/serialization/MessageFormats.java:4113:16 
[error] 4113 |      protected Builder newBuilderForType(
[error]      |                ^^^^^^^
[error]      |            Reference to Builder is ambiguous,
[error]      |            it is both defined in object AtLeastOnceDeliverySnapshot
[error]      |            and inherited subsequently in class UnconfirmedDelivery

when compiling this code.
NOTE: this error is a sample, there are a few more identical to that one.

I already tried compiling java sources first as suggested offline by some colleagues (@lrytz) but that workaround is not feasible in this particular codebase, unfortunately, since there are other parts of the build that require compiling Scala first. Using Mixed compile ordering doesn't work around the issue.

Compiler version

3.0.1-RC1

Minimized code

public final class MessageFormats {
    public  static final class AtLeastOnceDeliverySnapshot extends ... {
         public static final class Builder extends ... {
         }
         public  static final class UnconfirmedDelivery extends ... {
             public static final class Builder extends ... {
             }
             // code referring to `Builder` in this block will no longer 
             // compile in scala3
             @java.lang.Override
             protected Builder newBuilderForType(...) {
                  Builder builder = new Builder(parent);
                  return builder;
             }
             ...
         }
    }
}

Or probably smaller:

public final class A {
  public static final class C { }
  public static final class D {
    public static final class C { }
    public C foo() { return new C(); }
  }
}

Expectation

The compile can compile the Java code as it did in 2.13 and previous versions.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions