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

Scala 2.13.6 Breaks Compilation of Extending Java Interfaces Defining Clone as public #12466

Closed
jrduncans opened this issue Sep 30, 2021 · 4 comments

Comments

@jrduncans
Copy link

jrduncans commented Sep 30, 2021

reproduction steps

using Scala 2.13.6,

object CloneTest extends javax.naming.directory.Attribute {
  override def getAll(): javax.naming.NamingEnumeration[_ <: Object] = ???
  override def get(): Object = ???
  override def size(): Int = ???
  override def getID(): String = ???
  override def contains(x$1: Object): Boolean = ???
  override def add(x$1: Object): Boolean = ???
  override def remove(x$1: Object): Boolean = ???
  override def clear(): Unit = ???
  override def getAttributeSyntaxDefinition(): javax.naming.directory.DirContext = ???
  override def getAttributeDefinition(): javax.naming.directory.DirContext = ???
  override def isOrdered(): Boolean = ???
  override def get(x$1: Int): Object = ???
  override def remove(x$1: Int): Object = ???
  override def add(x$1: Int, x$2: Object): Unit = ???
  override def set(x$1: Int, x$2: Object): Object = ???
}

results in

[error] ...weaker access privileges in overriding
[error] def clone(): Object (defined in trait Attribute)
[error]   override should be public;
[error]   (note that def clone(): Object (defined in trait Attribute) is abstract,
[error]   and is therefore overridden by concrete protected[package lang] def clone(): Object (defined in class Object))
[error] object CloneTest extends Attribute {

problem

In Scala 2.13.5 this compiles successfully. The above is a minimal reproduction; I actually face this problem using ScalaMock to mock javax.naming.directory.Attribute.

@SethTisue
Copy link
Member

SethTisue commented Sep 30, 2021

Please have a look at scala/scala#9525 and let us know what you think afterwards. cc @lrytz @kynthus

@jrduncans
Copy link
Author

If it's caused by that, it seems to be an unintentional impact. Unlike the statement "They are all about overriding public or package-private Java members with protected, protected[something] or private[something] in Scala.", this is caused by the Java interface setting the visibility to public, contravening the Object type as protected. And unlike the fixes found for community builds, I don't see any way to work around this while still extending such a Java interface.

@lrytz
Copy link
Member

lrytz commented Oct 4, 2021

Java

interface A {
  public Object clone();
}

Scala

class C extends A
Test.scala:1: error: weaker access privileges in overriding
def clone(): Object (defined in trait A)
  override should be public;
  (note that def clone(): Object (defined in trait A) is abstract,
  and is therefore overridden by concrete protected[package lang] def clone(): Object (defined in class Object))
class C extends A
      ^
1 error

The mssage seems correct to me, the concrete method overrides the abstract one, and it cannot have weaker access privileges. Java agrees, with

public class B implements A { }

you get

B.java:1: error: clone() in Object cannot implement clone() in A
public class B implements A {
       ^
  attempting to assign weaker access privileges; was public
1 error

@lrytz lrytz closed this as completed Oct 4, 2021
@jrduncans
Copy link
Author

I see now, I'll file a bug with ScalaMock to produce something that compiles.

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

3 participants