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

2.10 regression: broken static forwarders for non-public methods generated when extending class from different package #6063

Closed
scabug opened this issue Jul 11, 2012 · 10 comments
Assignees
Milestone

Comments

@scabug
Copy link

@scabug scabug commented Jul 11, 2012

As an example, take java.lang.Throwable as our superclass.

% cat O.scala
object O extends Throwable
% scalac29 -version
Scala compiler version 2.9.2 -- Copyright 2002-2011, LAMP/EPFL
% scalac29 O.scala
% cat J.java
public class J {
  public static void main(String[] args) {
    O.getStackTraceDepth();
  }
}
% javac -version
javac 1.6.0_33
% javac -classpath .:/usr/local/scala-2.9.2/lib/scala-library.jar J.java
J.java:3: cannot find symbol
symbol  : method getStackTraceDepth()
location: class O
    O.getStackTraceDepth();
     ^
1 error

2.10.0-M4 does generate a forwarder, but woe to she who attempts to actually use it:

% rm *.class
% scalac210 -version
Scala compiler version 2.10.0-M4 -- Copyright 2002-2011, LAMP/EPFL
% scalac210 O.scala
% javac -classpath .:/usr/local/scala-2.9.2/lib/scala-library.jar J.java
% java -classpath .:/usr/local/scala-2.9.2/lib/scala-library.jar J
Exception in thread "main" java.lang.IllegalAccessError: tried to access method java.lang.Throwable.getStackTraceDepth()I from class O
	at O.getStackTraceDepth(O.scala)
	at J.main(J.java:3)

A quick look with javap shows that the body of the forwarder is confused about the static-ness of the method it's trying to forward to:

% javap -c -classpath .:/usr/local/scala-2.9.2/lib/scala-library.jar O
...
public static int getStackTraceDepth();
  Code:
   0:	getstatic	; //Field O$.MODULE$:LO$;
   3:	invokevirtual	; //Method O$.getStackTraceDepth:()I
   6:	ireturn
...

My examples don't have package declarations, but I don't think that matters because I hit this in real code and in the real code everything was in packages.

It's true you can avoid the runtime error by simply not attempting to use the broken static forwarder, but I'm afraid that doesn't really solve it because the invalid forwarders may confuse tools. For example, they cause ProGuard to abort and exit when processing my real code.

This appears related to #3452 (which itself has many related tickets).

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 11, 2012

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 11, 2012

@SethTisue said:
Ugh, I can't edit the description of my own ticket. Please replace "the body of the forwarder is confused about the static-ness of the method it's trying to forward to" with "the body of the forwarder is attempting to call a non-public method".

The forwarder should not be generated at all, since O isn't in the java.lang package so the method is inaccessible.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 11, 2012

@SethTisue said:
I checked and the same thing still happens on master as of two days ago:

% rm *.class                                                          
% ~/scala/dists/latest/bin/scalac -version
Scala compiler version 2.10.0-20120709-094806-e9afc228fd -- Copyright 2002-2011, LAMP/EPFL
% ~/scala/dists/latest/bin/scalac O.scala
% javac -classpath ~/scala/dists/latest/lib/scala-library.jar:. J.java
% java -classpath ~/scala/dists/latest/lib/scala-library.jar:. J      
Exception in thread "main" java.lang.IllegalAccessError: tried to access method java.lang.Throwable.getStackTraceDepth()I from class O
	at O.getStackTraceDepth(O.scala)
	at J.main(J.java:3)
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 11, 2012

@magarciaEPFL said:
The thing is that j.l.Throwable.getStackTraceDepth() is package-protected, and the following program doesn't compile:

object O extends Throwable

object Test {
  def main(args: Array[String]) {
    O.getStackTraceDepth()
  }
}

The error reads

error: method getStackTraceDepth in class Throwable cannot be accessed in object O
    O.getStackTraceDepth()
      ^
one error found
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 11, 2012

@SethTisue said:
right. so no static forwarder should be generated.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 11, 2012

@paulp said:
Protected symbols are already excluded from getting forwarders; I can only guess that the symbol isn't marked protected anymore for some reason. Or possibly that we're getting wrong flags due to it not being initialized (a tragic possibility.)

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 11, 2012

@paulp said:
No, I see the problem; due to the confusing encoding of access, checking for PRIVATE and PROTECTED is still not enough. Also have to check !m.hasAccessBoundary.

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Jul 16, 2012

@SethTisue said:
may I suggest this be marked critical for 2.10 since it's a regression?

@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Aug 7, 2012

@scabug scabug closed this Aug 7, 2012
@scabug

This comment has been minimized.

Copy link
Author

@scabug scabug commented Aug 7, 2012

@SethTisue said:
awesome — thank you

@scabug scabug added the critical label Apr 7, 2017
@scabug scabug added this to the 2.10.0-M6 milestone Apr 7, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.