#2245 Java FFI: call overloaded method(short,int) / method(int,int)

kjauslin Wed 26 Feb 2014

Hi, I'm trying to call a java method which is overloaded with (short, int) and (int, int). Fantom reports the error

Ambiguous call createCell(sys::Int, sys::Int).

I guess this is because FFI maps java short to sys::Int. Is there any way to work around and call the java createCell(int, int) function? Since the method resides in the Apache POI library, I'd prefer a way without having to adapt the library.

SlimerDude Wed 26 Feb 2014

No, there's no way to call it directly from Fantom.

Your best option (which doesn't take much effort) is to create a native Java method in a peer class, which calls it for you. Then you call the native method instead. See Natives

kjauslin Thu 27 Feb 2014

Thanks, I tried to do this. However, somewhere there is a problem loading the peer class at runtime. Things compile fine, when running, I get the error message below.

Any idea what I could try?

sys::UnknownTypeErr: ApachePOI_0::HSSFWorkbookPeer
  fan.sys.Pod.type (Pod.java:284)
  fan.sys.FanClassLoader.findFanClass (FanClassLoader.java:174)
  fan.sys.FanClassLoader.findClass (FanClassLoader.java:92)
  java.lang.ClassLoader.loadClass (ClassLoader.java:425)
  java.lang.ClassLoader.loadClass (ClassLoader.java:358)
  ApachePOI_0::HSSFWorkbook.<init> (.../fan/ApachePOI.fan:12)

Folder structure in pod:

  • fan/ApachePOI.fan
  • java/HSSFWorkbookPeer.java (build.xml includes java/ as javaDir)

HSSFWorkbookPeer class:

package fan.poiPod;

import org.apache.poi.hssf.usermodel.*;
import java.io.FileInputStream;

public class HSSFWorkbookPeer {  
	public static HSSFWorkbookPeer make(HSSFWorkbook self) { 
		return new HSSFWorkbookPeer(); 
	}
}

ApachePOI.fan:

class HSSFWorkbook {
  native HSSFSheet getSheet(Str sheetName)
}
class HSSFSheet
{
  native HSSFSheet createRow(Int column)
}
class ApachePOI
{
  static Void test() { 
  HSSFWorkbook workbook := HSSFWorkbook.make() 
}

kjauslin Thu 27 Feb 2014

Solved. I called the runtime without the pod prefix.

Now I have the problem that I can only instantiate the java class with a parameter (new HSSFWorkbook(FileInputStream in). And I have no idea how to do this in the peer class. I don't know how to call the make with additional parameters (Invalid args make(), not ([java]java.io::FileInputStream))

Any idea?

brian Thu 27 Feb 2014

Now I have the problem that I can only instantiate the java class with a parameter (new HSSFWorkbook(FileInputStream in). And I have no idea how to do this in the peer

Are you trying to figure out how to map a Fan InStream to Java InputStream? Take a look at fanx.interop.Interop in sys.jar. It has all the utility methods to convert b/w Java I/O streams and Fantom I/O streams.

kjauslin Thu 27 Feb 2014

I tried to instantiate the java object in a peer class with a constructor parameter of type FileInputStream, like new HSSFWorkbook(in) or HSSFWorkbook.make(in). The problem is not related to the FileInputStream (I think). I used the Interop.toJava for another case and it worked nicely.

Anyway, I gave up wrapping the Apache POI library with peer classes because the overhead seems massive. Instead, I recompiled the POI library itself and threw out the deprecated methods which were causing the ambiguity problem. With this, I can now use plain FFI - which works much better.

Login or Signup to reply.