scala3 icon indicating copy to clipboard operation
scala3 copied to clipboard

Compiler should not allow to access Java protected static method defined in different package

Open WojciechMazur opened this issue 1 year ago • 3 comments

Compiler version

All Scala 3 versions

Minimized code

The snippet below can be compiled with Scala 2 leading to runtime failure.

// Task.java
package foo;

public abstract class Task{
  protected static Task poll(){ return null; }
}
@main def Test = {
  val task = foo.Task.poll()
  println(task)
}

Output

Exception in thread "main" java.lang.IllegalAccessError: class main$package$ tried to access protected method 'foo.Task foo.Task.poll()' (main$package$ and foo.Task are in unnamed module of loader 'app')
        at main$package$.Test(main.scala:1)
        at Test.main(main.scala:1)

Expectation

Typer should prevent access to protected static method which cannot be accessed. Scala 2 handles this case correctly

WojciechMazur avatar Aug 23 '23 10:08 WojciechMazur

Obvious after morning coffee, but it should say Scala 2 refuses to compile, but Scala 3 fails at runtime.

Scala 2 messaging:

i18446.scala:5: error: method poll in class Task cannot be accessed as a member of object foo.Task from class Subtask
 Access to protected method poll not permitted because
 enclosing class Subtask is not a subclass of
 class Task in package foo where target is defined

som-snytt avatar Aug 23 '23 15:08 som-snytt

@bracevac would that seem like an appropriate spree issue to you? For example for tomorrow? 🙂

mbovel avatar Jul 01 '24 11:07 mbovel

This issue was picked for the Scala Issue Spree of tomorrow, July 2nd. @bracevac and @hamzaremmal will be working on it! If you have any insight into the issue or guidance on how to fix it, please leave it here.

mbovel avatar Jul 01 '24 12:07 mbovel

Preliminary conclusions after the spree:

  • The culprit appears to be this line in core/SymDenotations.scala which makes the protected static method public.
  • An ad hoc fix makes the example fail at compile time, as intended, but then we lose the ability to access poll from classes inheriting from Task that reside outside of the foo package. Java allows us to do that.
  • We're investigating if there is a relatively straightforward way to support Java's semantics for protected static.
  • We should also check that the positive Java interop test cases do not exhibit similar runtime crashes.

bracevac avatar Jul 02 '24 20:07 bracevac