#1477 Report error if mixin has native methods

tonsky Tue 5 Apr 2011

fan/CLTest.fan

native mixin CLTest {
  native Int testCl()
}

java/fan/test/CLTest.java

package fan.cltest;
public class CLTest {
  public static long testCl(){
    return 1L;
  }
}

test/CLTestTest.fan

class CLTestTest : Test, CLTest {
  Void test() {
    verifyEq(testCl(), 1)
  }
}

Then run

fan cltest/build.fan && fant cltest

and I’ve got

...
BUILD SUCCESS [4127ms]!

-- Run:  cltest::CLTestTest.testCl...
java.lang.StackOverflowError
  at sun.nio.cs.UTF_8.updatePositions(UTF_8.java:58)
  at sun.nio.cs.UTF_8$Encoder.encodeArrayLoop(UTF_8.java:392)
  at sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:447)
  at java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:544)
  at java.lang.StringCoding$StringEncoder.encode(StringCoding.java:240)
  at java.lang.StringCoding.encode(StringCoding.java:272)
  at java.lang.String.getBytes(String.java:946)
  at java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
  at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:228)
  at java.io.File.exists(File.java:733)
  at sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:999)
  at sun.misc.URLClassPath.getResource(URLClassPath.java:169)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:296)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:296)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
  at fan.sys.FanClassLoader.findFanClass(FanClassLoader.java:162)
  at fan.sys.FanClassLoader.findClass(FanClassLoader.java:92)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
  at fan.sys.FanClassLoader.findFanClass(FanClassLoader.java:162)
  at fan.sys.FanClassLoader.findClass(FanClassLoader.java:92)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
  at fan.sys.FanClassLoader.findFanClass(FanClassLoader.java:162)
  at fan.sys.FanClassLoader.findClass(FanClassLoader.java:92)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
  ...

brian Tue 5 Apr 2011

Promoted to ticket #1477 and assigned to brian

Interesting - especially since the trace down in some NIO UTF-8 decoding library. I will take a look for next build.

BTW, not sure I have done a lot of testing with native mixins, will need to look at that. In the meantime you can have your mixin route to static native methods (which is essentially what mixin do anyways).

tonsky Tue 5 Apr 2011

I think nio is just the place where stack depth exceeded.

vkuzkokov Wed 6 Apr 2011

As far as I remember, implementations of CLTest methods are routed to static methods of class CLTest$ which class loaders fail to find.

brian Fri 27 May 2011

Renamed from Native mixin infinitely loops classloader to Report error if mixin has native methods

brian Fri 27 May 2011

Ticket resolved in 1.0.59

Okay, I believe the original reported error is a little bit of a red herring because native methods should be in a Peer class. Creating a Java class with the same name as the actual Fantom class is why the classloader goes haywire.

But the question remains - should mixins be allowed to have native methods? I think not because mixins can't have state, so it would be difficult to fit them into the peer model used by natives. If you do need need to create a native implementation for a concrete native method, there are a couple easy work arounds:

  • just delegate to a static native method in a class
  • make the whole mixin native, in which case it can be fully implemented in Java, C#, JS, etc (this provides the most power and flexibility) - sys::Service is a good example of where the entire mixin is a native class

Login or Signup to reply.