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

SIP-47 Clause Interleaving + Java = bad class file error #21346

Closed
SethTisue opened this issue Aug 7, 2024 Discussed in #21195 · 1 comment · Fixed by #21709
Closed

SIP-47 Clause Interleaving + Java = bad class file error #21346

SethTisue opened this issue Aug 7, 2024 Discussed in #21195 · 1 comment · Fixed by #21709
Assignees
Milestone

Comments

@SethTisue
Copy link
Member

Discussed in #21195

Originally posted by xuwei-k July 15, 2024
Is this expected behavior? or we should/can fix this error? 🤔

A.scala

package example

class A {
  def f[B](b: B)[C](c: C): (B, C) = (b, c)
}

build.sbt

scalaVersion := "3.6.0-RC1-bin-20240712-97a711c-NIGHTLY"

X.java

package j;

import example.A;

class X {
  A a = new A();
}

sbt compile

[error] example-project-dir/X.java:3:1: cannot access example.A
[error]   bad class file: example-project-dir/target/scala-3.6.0-RC1-bin-20240712-97a711c-NIGHTLY/classes/example/A.class
[error]     undeclared type variable: C
[error]     Please remove or make sure it appears in the correct subdirectory of the classpath.

javap -v A.class

  public <B extends java.lang.Object> scala.Tuple2<B, C> f(B);
    descriptor: (Ljava/lang/Object;Ljava/lang/Object;)Lscala/Tuple2;

getGenericParameterTypes and getGenericReturnType

Welcome to Scala 3.6.0-RC1-bin-20240712-97a711c-NIGHTLY-git-97a711c (11.0.23, Java OpenJDK 64-Bit Server VM).
Type in expressions for evaluation. Or try :help.
                                                                                                                                             
scala> val f = classOf[example.A].getMethods.find(_.getName == "f").get
val f: java.lang.reflect.Method = public scala.Tuple2 example.A.f(java.lang.Object,java.lang.Object)
                                                                                                                                             
scala> f.getGenericParameterTypes
val res0: Array[java.lang.reflect.Type] = Array(B)
                                                                                                                                             
scala> f.getGenericReturnType
java.lang.NullPointerException
  at java.base/sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.toString(ParameterizedTypeImpl.java:229)
  at scala.runtime.ScalaRunTime$.inner$1(ScalaRunTime.scala:258)
  at scala.runtime.ScalaRunTime$.stringOf(ScalaRunTime.scala:263)
  at scala.runtime.ScalaRunTime.stringOf(ScalaRunTime.scala)
  at jdk.internal.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  at dotty.tools.repl.Rendering.poorStringOf$1$$anonfun$1(Rendering.scala:64)
  at dotty.tools.repl.Rendering.poorStringOf$1$$anonfun$adapted$1(Rendering.scala:64)
  at dotty.tools.repl.Rendering.stringOfMaybeTruncated$1(Rendering.scala:68)
  at dotty.tools.repl.Rendering.classLoader$$anonfun$1(Rendering.scala:77)
  at dotty.tools.repl.Rendering.classLoader$$anonfun$adapted$1(Rendering.scala:76)
  at dotty.tools.repl.Rendering.replStringOf(Rendering.scala:105)
  at dotty.tools.repl.Rendering.valueOf$$anonfun$2(Rendering.scala:123)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.Rendering.valueOf(Rendering.scala:123)
  at dotty.tools.repl.Rendering.renderVal(Rendering.scala:160)
  at dotty.tools.repl.ReplDriver.$anonfun$7(ReplDriver.scala:402)
  at scala.runtime.function.JProcedure1.apply(JProcedure1.java:15)
  at scala.runtime.function.JProcedure1.apply(JProcedure1.java:10)
  at scala.collection.immutable.List.foreach(List.scala:334)
  at dotty.tools.repl.ReplDriver.extractAndFormatMembers$1(ReplDriver.scala:402)
  at dotty.tools.repl.ReplDriver.renderDefinitions$$anonfun$2(ReplDriver.scala:440)
  at scala.Option.map(Option.scala:242)
  at dotty.tools.repl.ReplDriver.renderDefinitions(ReplDriver.scala:439)
  at dotty.tools.repl.ReplDriver.compile$$anonfun$2(ReplDriver.scala:342)
  at scala.util.Either.fold(Either.scala:197)
  at dotty.tools.repl.ReplDriver.compile(ReplDriver.scala:324)
  at dotty.tools.repl.ReplDriver.interpret(ReplDriver.scala:283)
  at dotty.tools.repl.ReplDriver.loop$1(ReplDriver.scala:196)
  at dotty.tools.repl.ReplDriver.runUntilQuit$$anonfun$1(ReplDriver.scala:199)
  at dotty.tools.repl.ReplDriver.withRedirectedOutput(ReplDriver.scala:238)
  at dotty.tools.repl.ReplDriver.runBody$$anonfun$1(ReplDriver.scala:212)
  at dotty.tools.runner.ScalaClassLoader$.asContext(ScalaClassLoader.scala:80)
  at dotty.tools.repl.ReplDriver.runBody(ReplDriver.scala:212)
  at dotty.tools.repl.ReplDriver.runUntilQuit(ReplDriver.scala:199)
  at xsbt.ConsoleInterface.run(ConsoleInterface.java:52)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.base/java.lang.reflect.Method.invoke(Method.java:566)
  at sbt.internal.inc.AnalyzingCompiler.invoke(AnalyzingCompiler.scala:329)
  at sbt.internal.inc.AnalyzingCompiler.console(AnalyzingCompiler.scala:233)
  at sbt.Console.console0$1(Console.scala:65)
  at sbt.Console.$anonfun$apply$5(Console.scala:75)
  at sbt.Run$.executeSuccess(Run.scala:187)
  at sbt.Console.$anonfun$apply$4(Console.scala:75)
  at sbt.internal.util.Terminal.withRawInput(Terminal.scala:146)
  at sbt.internal.util.Terminal.withRawInput$(Terminal.scala:144)
  at sbt.internal.util.Terminal$ProxyTerminal$.withRawInput(Terminal.scala:424)
  at sbt.Console.$anonfun$apply$3(Console.scala:75)
  at sbt.internal.util.Terminal$TerminalImpl.withRawOutput(Terminal.scala:1028)
  at sbt.internal.util.Terminal$ProxyTerminal$.withRawOutput(Terminal.scala:463)
  at sbt.Console.apply(Console.scala:72)
  at sbt.Console.apply(Console.scala:50)
  at sbt.Console.apply(Console.scala:42)
  at sbt.Defaults$.$anonfun$consoleTask$1(Defaults.scala:2287)
  at sbt.Defaults$.$anonfun$consoleTask$1$adapted(Defaults.scala:2273)
  at scala.Function1.$anonfun$compose$1(Function1.scala:49)
  at sbt.internal.util.$tilde$greater.$anonfun$$u2219$1(TypeFunctions.scala:63)
  at sbt.std.Transform$$anon$4.work(Transform.scala:69)
  at sbt.Execute.$anonfun$submit$2(Execute.scala:283)
  at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:24)
  at sbt.Execute.work(Execute.scala:292)
  at sbt.Execute.$anonfun$submit$1(Execute.scala:283)
  at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
  at sbt.CompletionService$$anon$2.call(CompletionService.scala:65)
  at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
  at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
  at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
  at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
  at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
  at java.base/java.lang.Thread.run(Thread.java:829)
```</div>
@SethTisue
Copy link
Member Author

at #20861 (comment) , @sjrd wrote:

I don't think [this is a blocker for SIP-47]. It only affects new code combined with Java code. It cannot break anyone immediately. We should fix it, though, for sure, but not a blocker IMO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants