Skip to content

Ambiguous reference when invoking Properties.putAll() in Java 11 #10418

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

Closed
ijuma opened this issue Jul 19, 2017 · 12 comments · Fixed by scala/scala#7966
Closed

Ambiguous reference when invoking Properties.putAll() in Java 11 #10418

ijuma opened this issue Jul 19, 2017 · 12 comments · Fixed by scala/scala#7966
Assignees
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) jdk11
Milestone

Comments

@ijuma
Copy link

ijuma commented Jul 19, 2017

Java 8:

scala> import java.util.Properties
import java.util.Properties

scala> new Properties().putAll(new Properties)

Java 9:

scala> import java.util.Properties
import java.util.Properties

scala> new Properties().putAll(new Properties)
<console>:13: error: ambiguous reference to overloaded definition,
both method putAll in class Properties of type (x$1: java.util.Map[_, _])Unit
and  method putAll in class Hashtable of type (x$1: java.util.Map[_ <: Object, _ <: Object])Unit
match argument types (java.util.Properties)
       new Properties().putAll(new Properties)

The reason is that the following override was added in Java 9 in order to use a ConcurrentHashMap as the underlying implementation:

    @Override
    public synchronized void putAll(Map<?, ?> t) {
        map.putAll(t);
    }

scalac seems to think it's an overload instead of an override. The Hashtable method is defined as (K = Object and V = Object):

    public synchronized void putAll(Map<? extends K, ? extends V> t) {
        for (Map.Entry<? extends K, ? extends V> e : t.entrySet())
            put(e.getKey(), e.getValue());
    }

I found this while trying to compile Apache Kafka with Java 9.

Is it worth doing anything about this apart from documenting it somewhere?

@ijuma
Copy link
Author

ijuma commented Jul 19, 2017

Another somewhat subtle issue:

scala> import java.nio.ByteBuffer
import java.nio.ByteBuffer

scala> ByteBuffer.allocate(10)
res3: java.nio.ByteBuffer = java.nio.HeapByteBuffer[pos=0 lim=10 cap=10]

scala> res3.limit
<console>:15: error: ambiguous reference to overloaded definition,
both method limit in class ByteBuffer of type (x$1: Int)java.nio.ByteBuffer
and  method limit in class Buffer of type ()Int
match expected type ?
       res3.limit

The limit method was moved from ByteBuffer to the superclass Buffer and it can no longer be called without (). We may want to start a Java 9 migration notes or something.

@SethTisue
Copy link
Member

We may want to start a Java 9 migration notes or something

I've made a jdk9 label here in the tracker

@SethTisue
Copy link
Member

and see also the umbrella JDK 9 ticket at scala/scala-dev#139

@retronym retronym self-assigned this Jul 24, 2017
asfgit pushed a commit to apache/kafka that referenced this issue Aug 19, 2017
Compilation error fixes:
- Avoid ambiguity error when appending to Properties in Scala
code (scala/bug#10418)
- Use position() and limit() to fix ambiguity issue (
scala/bug#10418 (comment))
- Disable findBugs if Java 9 is used (
findbugsproject/findbugs#105)

Compilation warning fixes:
- Avoid deprecated Class.newInstance in Utils.newInstance
- Silence a few Java 9 deprecation warnings
- var -> val and unused fixes

Runtime error fixes:
- Introduce Base64 class that works in Java 7 and Java 9

Also:
- Set --release option if building with Java 9

Note that tests involving EasyMock (easymock/easymock#193)
or PowerMock (powermock/powermock#783)
will fail as neither supports Java 9 currently.

Author: Ismael Juma <ismael@juma.me.uk>

Reviewers: Jason Gustafson <jason@confluent.io>

Closes #3647 from ijuma/kafka-4501-support-java-9
@paulp
Copy link

paulp commented Oct 4, 2017

Please note the first bug exists in all versions of scala/java. Java 9 just happens to hit it with the change.

// J.java
package j;

interface Bippy<A> {
  public void f(Bippy<? extends A> t);
}
class J implements Bippy<Object> {
  public void f(Bippy<?> t) { }
}
// S.scala
package j

class S {
  new J f new J
}
// a.scala:4: error: ambiguous reference to overloaded definition,
// both method f in class J of type (x$1: j.Bippy[_])Unit
// and  method f in trait Bippy of type (x$1: j.Bippy[_ <: Object])Unit
// match argument types (j.J)
//   new J f new J
//         ^
// one error found

Failing this way makes no sense because even if those types were distinct, you couldn't overload on them because they have the same erasure. But j.Bippy[_] is equivalent to j.Bippy[_ <: Any], and in Java there is no distinction between Object and Any.

We have seen overriding-as-overloading over the imaginary distinction between Any and Object in the past, most prominently that def ==(x: Any) and def ==(x: Object) were seen as overloaded methods until ~3 years ago, something which was discovered in an impressively indirect way because type inference proceeds differently when calling an overloaded method.

@ijuma
Copy link
Author

ijuma commented Oct 4, 2017

Thanks Paul. I realise that the issue has existed for a while, but I thought it was worth pointing out that working Scala code breaks when upgrading to Java 9 due to this issue.

@paulp
Copy link

paulp commented Oct 4, 2017

@ijuma Oh, absolutely. I know you would already have known based on the nature of the bug that it wasn't specific to java 9, and tying it to java 9 is probably the way to get it fixed, but I didn't want the overall takeaway to be that it's a java 9 bug.

@sjrd
Copy link
Member

sjrd commented Oct 10, 2017

This issue prevents the Scala.js test suite from being compiled, with zillions of issues of the form

[error] /localhome/doeraene/projects/scalajs/test-suite/shared/src/test/scala/org/scalajs/testsuite/niobuffer/ByteBufferTest.scala:37: ambiguous reference to overloaded definition,
[error] both method position in class ByteBuffer of type (x$1: Int)java.nio.ByteBuffer
[error] and  method position in class Buffer of type ()Int
[error] match expected type ?
[error]     assertEquals(2, buf.position)
[error]                         ^

This used to compile because position(int) was not redefined in ByteBuffer. It was only defined in Buffer, alongside position(). This apparently was enough to give position() a higher priority when called as position(). But now that position(int) is redefined in a subclass, there is an ambiguity.

Writing buf.position() instead of buf.position works around the issue, but I'm not sure I want to change 85 call sites in my test suite :s I guess I have no other choice, though.

Independent reproduction:

$ ~/opt/scala-2.12.3/bin/scala
Welcome to Scala 2.12.3 (Java HotSpot(TM) 64-Bit Server VM, Java 9).
Type in expressions for evaluation. Or try :help.

scala> val b = java.nio.ByteBuffer.allocate(5)
b: java.nio.ByteBuffer = java.nio.HeapByteBuffer[pos=0 lim=5 cap=5]

scala> b.position
<console>:13: error: ambiguous reference to overloaded definition,
both method position in class ByteBuffer of type (x$1: Int)java.nio.ByteBuffer
and  method position in class Buffer of type ()Int
match expected type ?
       b.position
         ^

scala> b.position()
res1: Int = 0

scala> val c: java.nio.Buffer = b
c: java.nio.Buffer = java.nio.HeapByteBuffer[pos=0 lim=5 cap=5]

scala> c.position
res2: Int = 0

whereas on Java 8:

$ ~/opt/scala-2.12.3/bin/scala
Welcome to Scala 2.12.3 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_40).
Type in expressions for evaluation. Or try :help.

scala> val b = java.nio.ByteBuffer.allocate(5)
b: java.nio.ByteBuffer = java.nio.HeapByteBuffer[pos=0 lim=5 cap=5]

scala> b.position
res0: Int = 0

scala> b.position()
res1: Int = 0

scala> val c: java.nio.Buffer = b
c: java.nio.Buffer = java.nio.HeapByteBuffer[pos=0 lim=5 cap=5]

scala> c.position
res2: Int = 0

sjrd added a commit to sjrd/scala-js that referenced this issue Oct 10, 2017
First, several methods of `nio.Buffer` are now overridden in
specific subclasses so that they return a more specific type. For
example, `Buffer.position(int)` is overridden in `ByteBuffer` to
return a `ByteBuffer`, allowing chained invocations.

This obviously means we had to add those overrides in our javalib,
so that they can link. Indeed, the overrides have a different
binary signature.

In addition, because of scala/bug#10418,
we also have to call `position()` and `limit()` instead of
`position` and `limit`, respectively.

Lastly, the methods `slice()` and `duplicate()` now have an
abstract definition in `Buffer`, which broken source compatibility
of the `BufferAdapter`s in our test suite. We fix this by renaming
the methods to `sliceChain()` and `duplicateChain()` in the
adapters.
sjrd added a commit to sjrd/scala-js that referenced this issue Oct 11, 2017
First, several methods of `nio.Buffer` are now overridden in
specific subclasses so that they return a more specific type. For
example, `Buffer.position(int)` is overridden in `ByteBuffer` to
return a `ByteBuffer`, allowing chained invocations.

This obviously means we had to add those overrides in our javalib,
so that they can link. Indeed, the overrides have a different
binary signature.

In addition, because of scala/bug#10418,
we also have to call `position()` and `limit()` instead of
`position` and `limit`, respectively.

Lastly, the methods `slice()` and `duplicate()` now have an
abstract definition in `Buffer`, which broken source compatibility
of the `BufferAdapter`s in our test suite. We fix this by renaming
the methods to `sliceChain()` and `duplicateChain()` in the
adapters.
@retronym
Copy link
Member

retronym commented Oct 13, 2017

We have a special case in matchesType that tries to gloss over the fact that Any and AnyRef are one and the same in Java, but this is too shallow to deal with the references to the type parameters.

gmethvin pushed a commit to playframework/playframework that referenced this issue Jan 18, 2018
* Using non-deprecated valueOf

Constructors for boxing types were mostly deprecated. For example:

http://download.java.net/java/jdk9/docs/api/java/lang/Integer.html#Integer-int-

* Remove uses os deprecated Class.newInstance

See http://download.java.net/java/jdk9/docs/api/java/lang/Class.html#newInstance--

* Exception check compatible with Java 8 and 9

In Java 8 we get a java.net.SocketException but in Java 9
we got a more specific javax.net.ssl.SSLException with a
SocketException as the cause.

* Fix ambiguous call to putAll

See scala/bug#10418
retronym added a commit to retronym/scala that referenced this issue Jun 7, 2018
retronym added a commit to retronym/scala that referenced this issue Jun 7, 2018
lrytz pushed a commit to retronym/scala that referenced this issue Jun 7, 2018
See: scala/scala-asm#5

Upstream changes in ASM:

  scala/scala-asm@ASM_6_0...ASM_6_2
  http://asm.ow2.io/versions.html

The motivations, other than just keeping current, are:

  - support for Java 9/10/11 updates to the classfile format.
  - reducing needless String => Array[Char] conversions thanks
    to internal changes in ASM.

This PR will fail to build until we publish artifact
from scala/scala-asm.

Includes a workaround for scala/bug#10418
retronym added a commit to retronym/scala that referenced this issue Jun 20, 2018
See: scala/scala-asm#5

Upstream changes in ASM:

  scala/scala-asm@ASM_6_0...ASM_6_2
  http://asm.ow2.io/versions.html

The motivations, other than just keeping current, are:

  - support for Java 9/10/11 updates to the classfile format.
  - reducing needless String => Array[Char] conversions thanks
    to internal changes in ASM.

This PR will fail to build until we publish artifact
from scala/scala-asm.

Includes a workaround for scala/bug#10418
retronym added a commit to retronym/scala that referenced this issue Jun 20, 2018
See: scala/scala-asm#5

Upstream changes in ASM:

  scala/scala-asm@ASM_6_0...ASM_6_2
  http://asm.ow2.io/versions.html

The motivations, other than just keeping current, are:

  - support for Java 9/10/11 updates to the classfile format.
  - reducing needless String => Array[Char] conversions thanks
    to internal changes in ASM.

This PR will fail to build until we publish artifact
from scala/scala-asm.

Includes a workaround for scala/bug#10418
retronym added a commit to retronym/scala that referenced this issue Jun 20, 2018
See: scala/scala-asm#5

Upstream changes in ASM:

  scala/scala-asm@ASM_6_0...ASM_6_2
  http://asm.ow2.io/versions.html

The motivations, other than just keeping current, are:

  - support for Java 9/10/11 updates to the classfile format.
  - reducing needless String => Array[Char] conversions thanks
    to internal changes in ASM.

This PR will fail to build until we publish artifact
from scala/scala-asm.

Includes a workaround for scala/bug#10418
retronym added a commit to retronym/scala that referenced this issue Jun 20, 2018
See: scala/scala-asm#5

Upstream changes in ASM:

  scala/scala-asm@ASM_6_0...ASM_6_2
  http://asm.ow2.io/versions.html

The motivations, other than just keeping current, are:

  - support for Java 9/10/11 updates to the classfile format.
  - reducing needless String => Array[Char] conversions thanks
    to internal changes in ASM.

This PR will fail to build until we publish artifact
from scala/scala-asm.

Includes a workaround for scala/bug#10418
retronym added a commit to retronym/scala that referenced this issue Jun 20, 2018
See: scala/scala-asm#5

Upstream changes in ASM:

  scala/scala-asm@ASM_6_0...ASM_6_2
  http://asm.ow2.io/versions.html

The motivations, other than just keeping current, are:

  - support for Java 9/10/11 updates to the classfile format.
  - reducing needless String => Array[Char] conversions thanks
    to internal changes in ASM.

This PR will fail to build until we publish artifact
from scala/scala-asm.

Includes a workaround for scala/bug#10418
isaacl pushed a commit to isaacl/scala that referenced this issue Jul 2, 2018
See: scala/scala-asm#5

Upstream changes in ASM:

  scala/scala-asm@ASM_6_0...ASM_6_2
  http://asm.ow2.io/versions.html

The motivations, other than just keeping current, are:

  - support for Java 9/10/11 updates to the classfile format.
  - reducing needless String => Array[Char] conversions thanks
    to internal changes in ASM.

This PR will fail to build until we publish artifact
from scala/scala-asm.

Includes a workaround for scala/bug#10418
@roottraveller
Copy link

@ijuma
as per the info present here https://kafka.apache.org/downloads, I don't see any kafka version which uses scala 2.13

Current stable release 2.3.0 is based on scala 2.12

dongjoon-hyun added a commit to apache/spark that referenced this issue Sep 10, 2019
…eference

### What changes were proposed in this pull request?

This PR aims to recover the JDK11 compilation with a workaround.
For now, the master branch is broken like the following due to a [Scala bug](scala/bug#10418) which is fixed in `2.13.0-RC2`.
```
[ERROR] [Error] /spark/sql/core/src/main/scala/org/apache/spark/sql/execution/SQLExecutionRDD.scala:42: ambiguous reference to overloaded definition,
both method putAll in class Properties of type (x$1: java.util.Map[_, _])Unit
and  method putAll in class Hashtable of type (x$1: java.util.Map[_ <: Object, _ <: Object])Unit
match argument types (java.util.Map[String,String])
```

- https://github.com/apache/spark/actions (JDK11 build monitoring)

### Why are the changes needed?

This workaround recovers JDK11 compilation.

### Does this PR introduce any user-facing change?

No.

### How was this patch tested?

Manual build with JDK11 because this is JDK11 compilation fix.
- Jenkins builds with JDK8 and tests with JDK11.
- GitHub action will verify this after merging.

Closes #25738 from dongjoon-hyun/SPARK-28939.

Authored-by: Dongjoon Hyun <dhyun@apple.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
PavithraRamachandran pushed a commit to PavithraRamachandran/spark that referenced this issue Sep 15, 2019
…eference

### What changes were proposed in this pull request?

This PR aims to recover the JDK11 compilation with a workaround.
For now, the master branch is broken like the following due to a [Scala bug](scala/bug#10418) which is fixed in `2.13.0-RC2`.
```
[ERROR] [Error] /spark/sql/core/src/main/scala/org/apache/spark/sql/execution/SQLExecutionRDD.scala:42: ambiguous reference to overloaded definition,
both method putAll in class Properties of type (x$1: java.util.Map[_, _])Unit
and  method putAll in class Hashtable of type (x$1: java.util.Map[_ <: Object, _ <: Object])Unit
match argument types (java.util.Map[String,String])
```

- https://github.com/apache/spark/actions (JDK11 build monitoring)

### Why are the changes needed?

This workaround recovers JDK11 compilation.

### Does this PR introduce any user-facing change?

No.

### How was this patch tested?

Manual build with JDK11 because this is JDK11 compilation fix.
- Jenkins builds with JDK8 and tests with JDK11.
- GitHub action will verify this after merging.

Closes apache#25738 from dongjoon-hyun/SPARK-28939.

Authored-by: Dongjoon Hyun <dhyun@apple.com>
Signed-off-by: Dongjoon Hyun <dhyun@apple.com>
rijad-nuridini pushed a commit to derrickoswald/CIMApplication that referenced this issue Jul 6, 2020
add round brackets to call on mark and position.
With java 1.9+ methods that used to only be in the Buffer class are now also in the ByteBuffer class.
This leads to ambiguous reference in scala.
Problem description: scala/bug#10418
fixed it analogous to https://git.uni-due.de/embedded-systems-public/spark/commit/f41c0a93fd3913ad93e55ddbfd875229872ecc97
rijad-nuridini pushed a commit to derrickoswald/CIMSpark that referenced this issue Jul 6, 2020
add round brackets to call on mark and position.
With java 1.9+ methods that used to only be in the Buffer class are now also in the ByteBuffer class.
This leads to ambiguous reference in scala.
Problem description: scala/bug#10418
fixed it analogous to https://git.uni-due.de/embedded-systems-public/spark/commit/f41c0a93fd3913ad93e55ddbfd875229872ecc97
wcbarksdale added a commit to PagerDuty/scheduler that referenced this issue Feb 25, 2022
TylerHorth pushed a commit to TylerHorth/playframework that referenced this issue Feb 12, 2024
* Using non-deprecated valueOf

Constructors for boxing types were mostly deprecated. For example:

http://download.java.net/java/jdk9/docs/api/java/lang/Integer.html#Integer-int-

* Remove uses os deprecated Class.newInstance

See http://download.java.net/java/jdk9/docs/api/java/lang/Class.html#newInstance--

* Exception check compatible with Java 8 and 9

In Java 8 we get a java.net.SocketException but in Java 9
we got a more specific javax.net.ssl.SSLException with a
SocketException as the cause.

* Fix ambiguous call to putAll

See scala/bug#10418
gemelen added a commit to gemelen/sbt-pom-reader that referenced this issue Mar 12, 2024
Scala bug workaround, see scala/bug#10418
HyukjinKwon pushed a commit to apache/spark that referenced this issue Dec 1, 2024
### What changes were proposed in this pull request?
This PR uses the `putAll` method of `Properties` class in place of `put`.

### Why are the changes needed?
In Scala 2.13, scala/bug#10418 has been fixed.
So we can avoid the workaround.

### Does this PR introduce _any_ user-facing change?
No

### How was this patch tested?
There is no change in functionality.
Existing tests suffice.

### Was this patch authored or co-authored using generative AI tooling?
No

Closes #48993 from tedyu/put-all.

Authored-by: Zhihong Yu <yuzhihong@gmail.com>
Signed-off-by: Hyukjin Kwon <gurwls223@apache.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed in Scala 3 This issue does not exist in the Scala 3 compiler (https://github.com/lampepfl/dotty/) jdk11
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants