#763 Classloader issue

tcolar Mon 28 Sep 2009

I'm trying to use a java Jar from Fan (FFI), this jar makes use of a native library.

Anyway I'm having some issue with classloading:

My JcoCon3 class is importing an external java class (FFI) and one of those class is trying to load the Jco3ConPeer class (not my class, but in the external jar), anyway, I can see the Fan classloader is trying to load this within the current pod (netColarJco), and that's failing, which i guess is normal since that class is not in the pod but in an external jar(in the vm classpath).

Now what seems odd to me is that it fails at FanClassLoader.java:168 (which does pod.findType(typeName, true)) ... now this is called as a checked exception so whne the class is not found it just throws the exception.

Now the next step in FanClassLoader.java is to call the system class loader as a fallback (findSystemClass(name);) ... but it will not be called.

Now that I look a bit more at the code, FanClassLoader.java:168 should only be called if name.startsWith("fan.") and I don't think this should be the case ?

sys::UnknownTypeErr: netColarJco::Jco3ConPeer
  fan.sys.Pod.findType (Pod.java:268)
  fan.sys.FanClassLoader.findClass (FanClassLoader.java:168)
  java.lang.ClassLoader.loadClass (ClassLoader.java:307)
  java.lang.ClassLoader.loadClass (ClassLoader.java:252)
  java.lang.ClassLoader.loadClassInternal (ClassLoader.java:320)
  netColarJco::Jco3Con.<init> (Jco3Con.fan)
  netColarJco::Jco3Con.make (Jco3Con.fan)
  netColarJco::FanJcoUtils.ping (FanJcoUtils.fan:17)
  netColarJco::Main.main (Main.fan:20)
  sun.reflect.NativeMethodAccessorImpl.invoke0 (NativeMethodAccessorImpl.java)
  sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39)
  sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25)
  java.lang.reflect.Method.invoke (Method.java:597)
  fan.sys.Method.invoke (Method.java:536)
  fan.sys.Method$MethodFunc.callList (Method.java:182)
  fan.sys.Method.callList (Method.java:147)
  fanx.tools.Fan.callMain (Fan.java:136)
  fanx.tools.Fan.executeType (Fan.java:103)
  fanx.tools.Fan.execute (Fan.java:39)
  fanx.tools.Fan.run (Fan.java:241)

Code here if that helps: http://svn.colar.net/netColarJco/trunk/fan/

Any ideas ?

brian Mon 28 Sep 2009

Now that I look a bit more at the code, FanClassLoader.java:168 should only be called if name.startsWith("fan.") and I don't think this should be the case ?

Right now the Fan classloader has a simple model:

  1. if name matches "fan.pod.Type", then load "pod::Type"
  2. delegate to system class loader

So your peer classes must use same package structure as other Fan classes.

tcolar Mon 28 Sep 2009

I'm not sure I'm understanding.

The peer class is not mine, it's part of the external sap jar (jco.jar) so i have no control over it or it's name/package.

In this case here it did not delegate to the system cl because FanClassLoader.java:168 threw a checked exception and it ends there.

I seems to me it should try the system classloader but it does not.

KevinKelley Mon 28 Sep 2009

You've got a Fan class, Jco3Con, that has native fields; therefore there needs to be a Jco3ConPeer.java class, compiled into your pod, that implements them. Way I read your code and the error stack, it's telling you that it can't find your peer class to implement the native fields

internal native JCoRepository repo
internal native JCoDestination? destination

I think those probably shouldn't be natives. They're holding java objects, but they're still Fan slots.

tcolar Tue 29 Sep 2009

Thanks, I had misunderstood native. Works now.

tcolar Tue 29 Sep 2009

Just to confirm: Are there any reasons to use "native" anymore, or is that completely obsolete ?

Thanks.

brian Tue 29 Sep 2009

I would recommend using Java FFI instead of native unless you plan to multiple implementations (Java, C#, JavaScript)

Login or Signup to reply.