#1849 method collision

KevinKelley Thu 22 Mar 2012

Looks like Fantom names are colliding with Java's:

class TestBug { 
  Void notify() {} 
  static Void main() {} 
}

gives this:

>fan bug.fan
java.lang.VerifyError: class fan.bug_0.TestBug overrides final method notify.()V

        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(Unknown Source)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at fan.sys.FanClassLoader.findPendingClass(FanClassLoader.java:130)
        at fan.sys.FanClassLoader.findClass(FanClassLoader.java:88)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at fan.sys.FanClassLoader.loadFan(FanClassLoader.java:57)
        at fan.sys.BootEnv.loadTypeClasses(BootEnv.java:265)
        at fan.sys.ClassType.emit(ClassType.java:490)
        at fan.sys.ClassType.finish(ClassType.java:544)
        at fan.sys.Method$MethodFunc.isStatic(Method.java:475)
        at fan.sys.Method$MethodFunc.callList(Method.java:191)
        at fan.sys.Method.callList(Method.java:138)
        at fanx.tools.Fan.callMain(Fan.java:173)
        at fanx.tools.Fan.executeFile(Fan.java:98)
        at fanx.tools.Fan.execute(Fan.java:37)
        at fanx.tools.Fan.run(Fan.java:298)
        at fanx.tools.Fan.main(Fan.java:336)
sys::Err: Method not mapped to java.lang.reflect correctly bug_0::TestBug.main
  fan.sys.Method$MethodFunc.isStatic (Method.java:482)
  fan.sys.Method$MethodFunc.callList (Method.java:191)
  fan.sys.Method.callList (Method.java:138)
  fanx.tools.Fan.callMain (Fan.java:173)
  fanx.tools.Fan.executeFile (Fan.java:98)
  fanx.tools.Fan.execute (Fan.java:37)
  fanx.tools.Fan.run (Fan.java:298)
  fanx.tools.Fan.main (Fan.java:336)

This seems to be new behavior in 1.0.62...

brian Thu 22 Mar 2012

Yeah one my original tickets (still open) was trying to figure out best way to deal with that. I don't understand why it would be a new problem in 1.0.62 though because java.lang.Object.notify is final so it could never be overridden.

Perhaps the only sane thing to do is to disallow clone, finalize, getClass, hashCode, notify, toString, and wait to be used as method names.

KevinKelley Thu 22 Mar 2012

Surprised me too; it's existing code that I updated to latest version, so it must have been working before... might check it w/ older versions this evening.

About the only alternative would be decorated names -- compiler emits name as XXXname for some encoding... but that messes up interop, or at least makes it difficult.

SlimerDude Sun 8 Mar 2015

Just to mention that method collision is still an issue - I'm using Java 1.6.0_45:

class Example {
    Void main() {
        echo(toString)
    }
	
    Str toString() {
        "wotever"
    }
}

java.lang.VerifyError: class fan.wotever.Example overrides final method toString.()Ljava/lang/String;
	at java.lang.ClassLoader.defineClass1(Native Method)
	at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
	at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
	at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
	at fan.sys.FanClassLoader.findPendingClass(FanClassLoader.java:134)
	at fan.sys.FanClassLoader.findClass(FanClassLoader.java:88)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	at fan.sys.FanClassLoader.loadFan(FanClassLoader.java:57)
	at fan.sys.BootEnv.loadTypeClasses(BootEnv.java:326)
	at fan.sys.Env.loadTypeClasses(Env.java:209)
	at fan.sys.ClassType.emit(ClassType.java:493)
	at fan.sys.ClassType.finish(ClassType.java:547)
	at fan.sys.Method$MethodFunc.isStatic(Method.java:475)
	at fan.sys.Method$MethodFunc.callList(Method.java:191)
	at fan.sys.Type.make(Type.java:246)
	at fan.sys.ClassType.make(ClassType.java:110)
	at fan.sys.Type.make(Type.java:236)
	at fanx.tools.Fan.callMain(Fan.java:175)
	at fanx.tools.Fan.executeType(Fan.java:140)
	at fanx.tools.Fan.execute(Fan.java:41)
	at fanx.tools.Fan.run(Fan.java:298)
	at fanx.tools.Fan.main(Fan.java:336)

Disallowing Java Object methods is a leaky abstraction but probably the easiest way to go. It's never bitten me until now.

brian Mon 9 Mar 2015

Yeah, that is one of the very first tickets 526. I guess one thing we could do is just add checks in compiler to disallow any slot name that might conflict with Java? Opinions?

Login or Signup to reply.