Scala+Java compilation fails during some Moon Phases

91 vues
Accéder directement au premier message non lu

Sasha Kazachonak

non lue,
17 mai 2012, 11:24:0217/05/2012
à scala-user
Hello!

It is probably a bug. But it might be me missing something about Scala-
Java interop (which usually works perfectly!).
Let's write 2 classes in Java.

public class J<T> {
public class Inner {}

public void call(Inner i) {
System.out.println("ja");
}
}

public class J2<T> extends J<T> {
public void call(Inner i) {
System.out.println("va");
}
}

Now let's extend them in Scala.

class S extends J[String] {
override def call(i: J[String]#Inner) = println("sca")
}

class S2 extends J2[String] {
override def call(i: J[String]#Inner) = println("la")
}

Compilation fails.
[info] Compiling 1 Scala source and 2 Java sources to D:\dev\my\lazer
\target\sca
la-2.9.1\classes...
[error] D:\dev\my\lazer\S.scala:2: method call overrides nothing
[error] override def call(i: J[String]#Inner) = println("sca")
[error] ^
[error] D:\dev\my\lazer\S.scala:6: method call overrides nothing
[error] override def call(i: J[String]#Inner) = println("la")
[error] ^
[error] two errors found

Ok. Now we change scala code in two places from
override def call(i: J[String]#Inner)
to
override def call(i: Inner)

Compilation succeeds.
[info] Compiling 1 Scala source and 2 Java sources to D:\dev\my\lazer
\target\sca
la-2.9.1\classes...

Now wait for a full moon and change scala file in any way. Let's just
add a newline in the end.
Compilation fails.
[info] Compiling 1 Scala source to D:\dev\my\lazer\target
\scala-2.9.1\classes...
[error] D:\dev\my\lazer\S.scala:2: method call overrides nothing
[error] override def call(i: Inner) = println("sca")
[error] ^
[error] D:\dev\my\lazer\S.scala:6: method call overrides nothing
[error] override def call(i: Inner) = println("la")
[error] ^
[error] two errors found

Ok. Now we change scala code in two places from
override def call(i: Inner)
to
override def call(i: J[String]#Inner)

Compilation fails.
[info] Compiling 1 Scala source to D:\dev\my\lazer\target
\scala-2.9.1\classes...
[error] D:\dev\my\lazer\S.scala:6: name clash between defined and
inherited memb
er:
[error] method call:(i: J[String]#Inner)Unit and
[error] method call:(x$1: J[T]#Inner)Unit in class J2
[error] have same type after erasure: (i: J#Inner)Unit
[error] override def call(i: J[String]#Inner) = println("la")
[error] ^
[error] one error found

So it seems like we have different compiler behavior depending on
whether it uses java source or class files.

This problem prevents people from using Hadoop with Google App Engine:
http://groups.google.com/group/scala-user/browse_thread/thread/77eedf7ec579224

The questions:

1) What is the supposed way to use Java inner classes in Scala
subclasses? I thought it was
override def call(i: J[String]#Inner)
But I succeeded only compiling
override def call(i: Inner)

2) Why class S compiles with
override def call(i: J[String]#Inner)
but class S2 is not?

--
Sasha

OlegYch

non lue,
18 mai 2012, 16:51:5918/05/2012
à scala...@googlegroups.com
This looks like an xsbt bug (although the same happens with fsc). Compiling with maven\scalac works fine.

Dzmitry Lazerka

non lue,
18 mai 2012, 20:54:2918/05/2012
à scala...@googlegroups.com
It was reproducible with Maven for me.

Sasha Kazachonak

non lue,
21 mai 2012, 15:48:2621/05/2012
à scala-user
I just checked. This works with scalac the same way as with xsbt:

Depending on whether you compile scala+java sources together or
separately compiler forces you to use either
JavaInnerClass
or
JavaClass[TypeParam]#JavaInnerClass
But "JavaClass[TypeParam]#JavaInnerClass" form doesn't work at all
when there is an intermediate Java class inherited.

There seems to be an old related bug in Scala:
https://issues.scala-lang.org/browse/SI-1409
> >http://groups.google.com/group/scala-user/browse_thread/thread/77eedf...
Répondre à tous
Répondre à l'auteur
Transférer
0 nouveau message