#2203 How to wait for completion of asynchronous Java function?

lel4866 Tue 12 Nov 2013

I am using a Java library that calls a Java function when a long running operation (initiated on the main thread by calling a Java function) is complete. This callback function is not on the main thread. I have successfully wrapped these functions with Fantom functions.

What I can't figure out is how to actually perform the wait or integrate this into the Actor subsystem. I suppose I could add a function to the Java library to do the wait() and have the callback function in Java do a notify(), but I was wondering if there was someway to get this done in Fantom itself

Any suggestions would be appreciated.

lel4866 Tue 12 Nov 2013

So, saying:

using [java] java.lang::Object
.
.
Object waitObj:= Object()
.
.
waitObj.wait

in callback routine:

waitObj.notify

seems to work, at least syntax wise

lel4866 Tue 12 Nov 2013

Well, maybe not. I get an IllegalMonitorStateException when I execute the waitObj.wait. According to Java docs, this is:

Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.

sys::Err: java.lang.IllegalMonitorStateException
  java.lang.Object.wait (Object.java)
  java.lang.Object.wait (Object.java:503)
  fan.sys.FanObj.wait (FanObj.java:226)
  DownloadIBData::DownloadIBData.requestHistoricalData (DownloadIBData.fan:143)
  DownloadIBData::DownloadIBData.run (DownloadIBData.fan:115)
  DownloadIBData::DownloadIBData.main (DownloadIBData.fan:54)
  java.lang.reflect.Method.invoke (Unknown)
  fan.sys.Method.invoke (Method.java:559)
  fan.sys.Method$MethodFunc.callList (Method.java:198)
  fan.sys.Method.callList (Method.java:138)
  fanx.tools.Fan.callMain (Fan.java:173)
  fanx.tools.Fan.executeType (Fan.java:140)
  fanx.tools.Fan.execute (Fan.java:41)
  fanx.tools.Fan.run (Fan.java:298)
  fanx.tools.Fan.main (Fan.java:336)

Any suggestions?

SlimerDude Tue 12 Nov 2013

To use Java's Object.wait() you need to be in a synchronized block. As the keyword doesn't exist in fantom, you'll have to do this is part in a separate Java class, and call it from your fantom class.

lel4866 Tue 12 Nov 2013

Thanks SlimerDude. I was hoping to do as much as possible in Fantom, but I understand.

brian Tue 12 Nov 2013

As a general rule, I would suggest not mixing the two. If you have to do something with synchronized, then do it in Java. But if at all possible try to use Actors on Fantom side. Actors are just so much better for building robust concurrent code.

lel4866 Tue 12 Nov 2013

Brian -

I understand about Actors, but I'm stuck with the Java library I was given. At least I can't figure out how to get it into the Actor framework without rewriting the Java side. It's got a ton of synchronized callbacks for tcp/ip stuff

Based on what SlimerDude said, on the Java side, I implemented:

public synchronized void synchronizedWait() throws InterruptedException { wait(); }
public synchronized void synchronizedNotifyAll() throws InterruptedException { notifyAll(); }

and it works fine now.

BTW, one thing I've really got to compliment you on, which I think is overlooked in reviews of Fantom, is the Duration stuff. It's the best solution I've seen for making time a first class object. My Fantom code is much more readable than the Java equivalent with Joda.

Login or Signup to reply.