-
Notifications
You must be signed in to change notification settings - Fork 21
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
Calling overridden vararg method from Java causes AbstractMethodError #1459
Comments
Imported From: https://issues.scala-lang.org/browse/SI-1459?orig=1
|
Harri Kulmala (hkulmala) said: |
Anders Bach Nielsen [X] (nielsen) said: |
Reuben (catdogboy) said (edited by @paulp on Feb 21, 2013 10:15:23 PM UTC):
|
@dubochet said:
Should there be a Java bridge method for every star-parameter method that is inherited from Java? |
Matt Hellige (hellige) said: Java: public interface Test {
public void foo(String... args);
} Scala: class Foo extends Test {
def foo(args: String*) = println(args)
}
new Foo().foo("hi") // fine
(new Foo(): Test).foo("hi") // AbstractMethodError This is particularly dangerous, of course, because you have no idea where the error will actually occur... |
Pavol Vaskovic (pali-at-pali.sk) said: |
Pavol Vaskovic (pali-at-pali.sk) said: This is also impacting the ability to override java methods that use varargs. The overriden methods are never invoked, even though the code compiles without errors. Running the testcase attached above produces: JavaPrinter: one two three
JavaPrinter: one two three
Exception in thread "main" java.lang.AbstractMethodError
at Main.doYourThing(Main.java:12)
at Main.main(Main.java:8) Expected result: JavaPrinter: one two three
InheritingPrinter extends JavaPrinter: one two three
ScalaPrinter: one two three |
Pavol Vaskovic (pali-at-pali.sk) said:
|
Coda Hale (codahale) said: |
Pavol Vaskovic (pali-at-pali.sk) said: |
Pavol Vaskovic (pali-at-pali.sk) said: |
joe (barillari) said: |
joe (barillari) said: I just tried hkulmala's example and it ran without a hitch. But when I Here is AbstractBase.java: public abstract class AbstractBase<T> {
abstract void doStuff(T... params);
void callDoStuff(T... params) {
doStuff(params);
} Concrete.scala: class Concrete extends AbstractBase[java.lang.Integer] {
override def doStuff(params:java.lang.Integer*) = println("doStuff invoked")
} Invoker.scala: object Invoker {
def main(args: Array[String]) {
val impl = new Concrete
impl.callDoStuff(1,2,3)
}
} If I compile and run with: javac *.java && scalac *.scala && scala Invoker The result is: java.lang.AbstractMethodError: AbstractBase.doStuff([Ljava/lang/Object;)V
at AbstractBase.callDoStuff(AbstractBase.java:5)
at Invoker$$.main(Invoker.scala:4)
at Invoker.main(Invoker.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at scala.tools.nsc.util.ScalaClassLoader$$$$anonfun$$run$$1.apply(ScalaClassLoader.scala:81)
at scala.tools.nsc.util.ScalaClassLoader$$class.asContext(ScalaClassLoader.scala:24)
at scala.tools.nsc.util.ScalaClassLoader$$URLClassLoader.asContext(ScalaClassLoader.scala:86)
at scala.tools.nsc.util.ScalaClassLoader$$class.run(ScalaClassLoader.scala:81)
at scala.tools.nsc.util.ScalaClassLoader$$URLClassLoader.run(ScalaClassLoader.scala:86)
at scala.tools.nsc.MainGenericRunner$$.main(MainGenericRunner.scala:83)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala) Interestingly, if you replace java.lang.Integer with java.lang.Object For the record, I'm running: $$ scala -version
javaScala code runner version 2.8.1.final -- Copyright 2002-2010, LAMP/EPFL
$$ java -version
java version "1.6.0_18"
OpenJDK Runtime Environment (IcedTea6 1.8.2) (6b18-1.8.2-4ubuntu2)
OpenJDK Server VM (build 16.0-b13, mixed mode)
I have attached a .zip file containing a directory called "object", |
Charles Beyer (cjbeyer) said: The bug isn't triggered if I change the java abstract method definition from package private (no qualifier) to public. Also, in my program, the java method doesn't have to be abstract. If I have a dumb generic implementation, the java implementation will get called when I call the method from java, while the scala overriding implementation gets called from scala. So the bug seems to be related to problems with the visibility qualifiers. |
@paulp said (edited on Dec 29, 2011 7:05:35 AM UTC):
Referring to joe's comment above mine, this: public abstract class AbstractBase<T> {
abstract void doStuff(T... params);
} What happens is that after uncurry that method looks like doStuff(Array[Object]), and so the overriding pair checks during erasure which would insert the necessary bridge do not recognize that the methods have the same signature, because the override's parameter is Array[Integer], not Array[Object]. I put a shameful hack here which makes the problem go away in this instance: https://github.com/paulp/scala/tree/ticket/SI-1459 But I can't commit that so it's only there for reference. |
François-Xavier Thomas (frx) said: |
Philippe Sam-Long (pulsation) said: E/AndroidRuntime( 1320): FATAL EXCEPTION: AsyncTask #1
E/AndroidRuntime( 1320): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime( 1320): at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime( 1320): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
E/AndroidRuntime( 1320): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
E/AndroidRuntime( 1320): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
E/AndroidRuntime( 1320): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime( 1320): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
E/AndroidRuntime( 1320): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
E/AndroidRuntime( 1320): at java.lang.Thread.run(Thread.java:841)
E/AndroidRuntime( 1320): Caused by: java.lang.AbstractMethodError: abstract method not implemented
E/AndroidRuntime( 1320): at android.os.AsyncTask.doInBackground(AsyncTask.java)
E/AndroidRuntime( 1320): at android.os.AsyncTask$2.call(AsyncTask.java:287)
E/AndroidRuntime( 1320): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
E/AndroidRuntime( 1320): ... 4 more Here is a workaround for this specific case: https://www.assembla.com/code/scala-eclipse-toolchain/git/nodes/ad17dd4047ac25b167496db84f4272795eb93c3e/docs/android-examples/android-sdk/Wiktionary/src/com/example/android/wiktionary/MyAsyncTask.java |
Kirill Lastovirya (kirhgoff) said: void on(java.lang.String s, io.socket.IOAcknowledge ioAcknowledge, java.lang.Object... objects); and scala compiler gives the following error: Tried a lot of variants, most reasonable (but still failing) one is |
@skyluc said: |
Arjun Panday (joune) said: => Exception in thread "main" java.lang.AbstractMethodError: Impl.h(Ljava/lang/Object;[Ljava/lang/String;)Ljava/lang/String; It seems to work if I remove either the type parameter or the varargs. Java(TM) SE Runtime Environment (build 1.8.0_25-b17) |
@adriaanm said: |
To see this error in action, just unzip the attachment and run compile.bat followed with run.bat.
I have a base class (Java) with one method:
I create an implementation for it in scala:
Finally, I have a Caller class (Java) which just calls the abovementioned method, as follows:
Now, a direct call succeeds:
whereas the following fails
javac -version gives "1.6.0"
scalac -version gives "Scala compiler version 2.7.2.RC4"
I am running on Windows XP SP2 with scala 2.7.2.RC4.
The text was updated successfully, but these errors were encountered: