Re: [Pharo-users] [ANN] JNIPort for Pharo 3.0 alpha

2014-04-05 Thread Joachim Geidel
Am 31.03.2014 um 21:25 schrieb Tudor Girba :
> Now, the next question. I saw that it is possible to enable callbacks, but I 
> could not find an example of how it works.
> 
> For example, could we model this:
> 
> - in a JavaClassOriginator class we have a method like
> execute(JavaClassTargetInterface target) { target.m() }
> - In Pharo we create PharoClassTargetImplementation as an implementation of 
> JavaClassTargetInterface
> - passing an instance of PharoClassTargetImplementation to 
> JavaClassOriginator results in calling PharoClassTargetImplementation>>m
> 
> ?
> 
> 
> Cheers,
> Doru

Hi Doru,

it’s not completely straightforward, but also not really complicated. Chris 
Uppal’s JNIPort documentation contains examples, and you can also get some 
information from the test cases for callbacks. You will need the jniport.jar 
file which can be downloaded from http://jniport.wikispaces.com/Downloads (it 
is contained in JNIPort_Extras.zip). The Java classes needed for callback 
support have names starting with „Dolphin“ - they come directly from Chris’ 
implementation for Dolphin Smalltalk.

A simple example: To set up sending a simple notification without parameters to 
a Smalltalk object, you need a Java class similar to the following:

-
package my.package;
import org.metagnostic.jniport.*;
public class MyClass
{
private static final Object notifyTag = new 
String("MyClass.sendNotification()“); 
public static Object notifyTag () { return notifyTag; }
public void sendNotification()
throws RequestNotHandedException
{
new DolphinNotification(notifyTag, this).send();
}
}
-

You have to install the callback in Smalltalk:

-
NotificationHandler := … "the object which receives the notifications"
classStatic := jvm findClass: 'my.package.MyClass'.
jvm callbackRegistry
setCallback: classStatic notifyTag "the tag can be an arbitrary String"
handler: [:this :param | NotificationHandler handleNotificationFor: 
this].
-

When you send sendNotification() to an instance of MyClass, NotificationHandler 
should receive the message #handleNotificationFor:.

In the example code, the tag is a static variable in MyClass. Of course, you 
can also give every instance of MyClass its own tag. In this case, you have to 
set up a callback in Smalltalk for every tag which is used. 

The example is a short version of the test code for handling notifications in 
JNIPortCallbackNotificationsTest and the corresponding Java class 
org.metagnostic.jniport.test.regression.Notifications. The source code of this 
Java class is in the archive JNIPort-Tests.zip which is contained in 
JNIPort_Extras.zip.

If you need an example for a notification which has parameters and where the 
Smalltalk code returns  a result, have a look at 
JNIPortCallbackRequestsTest>>testCallbackWithOneParameterAndReturn and the 
corresponding Java class org.metagnostic.jniport.test.regression.Callbacks.

In the Java class, you need something like this (copied from Callbacks and 
simplified) which enables a callback taking an int parameter and returning an 
instance of the Java class Integer:

 private static final Object callbackTag = new String(„callback with 
parameters"), 

// callback with return value
public int callbackAndReturn(int i)
throws Throwable
{
Object returnValue = new DolphinRequest(callbackTag, this, 
i).value();
return ((Integer) returnValue).intValue();
}

A DolphinRequest is created with the tag which identifies the callback in 
Smalltalk, the object sending the callback (this), and an arbitrary number of 
parameters. For example, the following creates a DolphinRequest with two 
parameters:

DolphinRequest dr = new DolphinRequest(
s_callbackTag,
this,
new Integer(i),
new Double(d));

Calling the value() method of the DolphinRequest sends the request to 
VisualWorks and returns the result of the Smalltalk callback block.

In Smalltalk, you can create callbacks accepting parameters like this (see 
JNIPortCallbackRequestsTest):

"No parameters"
jvm callbackRegistry setCallback: classStatic callbackTag 
handler: [:this :param | self handleCallbackFor: this].

"One parameter"
jvm callbackRegistry setCallback: classStatic callbackTag 
handler: [:this :param | self handleCallbackFor: this 
with: param].

"Arbitrary number of parameters"
jvm callbackRegistry setCallback: classStatic callbackTag 
handler: [:this :params | self handleCallbackFor: this 
withArguments: params asArray].

If the callback has a 

Re: [Pharo-users] [ANN] JNIPort for Pharo 3.0 alpha

2014-04-05 Thread Igor Stasenko
On 25 March 2014 19:59, Joachim Geidel  wrote:

> Hi everybody,
>
> JNIPort for Pharo 3.0 alpha is now available at SmalltalkHub.
>
> JNIPort is a Smalltalk library which allows Java code to be invoked from
> Smalltalk. It acts as a bridge between the world of Smalltalk objects and a
> Java Virtual Machine (JVM) where Java code is executing.
>
> When I first ported JNIPort to Squeak and Pharo 1.x, I used Alien as the
> FFI
> library. As NativeBoost has superseded Alien, the interface to the Java
> Native Interface library had to be rewritten. There are still some
> undocumented and obscure parts in NativeBoost, so this has taken some time.
>
> If you want to try it, load it via the ConfigurationOfJNIPort. I hope this
> works. If it does not, load the packages individually in the order in which
> they appear in the ConfigurationOfJNIPort.
> http://www.smalltalkhub.com/#!/~JNIPort/JNIPort
> The next step is to read the documentation at
> http://jniport.wikispaces.com/
> Otherwise, you won't know what to do next. ;-)
> Download the extra files from the download page at Wikispaces, you will
> need
> two jar files from there.
>
> Start a Java VM attached to Pharo by adapting and executing the following
> code snippet:
>
> 
> | jvmSettings |
>  "You can set the path to the Java VM library by editing the path as
> needed."
> JNIPortJNIInterface libraryFile:
>
> '/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries/libclient.dylib'
> .
> "JNIPortJNIInterface libraryFile:
> 'C:\Programme\Java\jre7\bin\client\jvm.dll' ."
>
>  jvmSettings := JVMSettings new.
>  jvmSettings usesGhosts: true.
>  jvmSettings supportsCallbacks: true.
>  jvmSettings jniPortSettings  useJNIHelperLibrary: false.
> jvmSettings ghostClassSettings retainMethodSource: true.
>
>  "On Mac OS X and Linux, class path entries are separated by colons."
>  "On Windows, you have to use semicolons instead. Edit the following line
> as
> needed."
> jvmSettings runtimeSettings classpath:
> '.:/Users/myname/JNIPort.jar:/Users/myname/JNIPort-Tests.jar'.
> " jvmSettings runtimeSettings classpath:
> '.;.\JNIPort.jar;.\JNIPort-Tests.jar'."
>
>  "Uncomment the following if you want the Java VM to emit verbose messages.
>   How to access these messages depends on your platform.
>   On Mac OS X, they are visible in the Console application."
> "jvmSettings runtimeSettings addOption: '-verbose:jni'; addOption:
> '-verbose:gc'; addOption: '-verbose:class'."
> Cursor execute showWhile: [JVM newWithSettings: jvmSettings].
> 
>
> Then the fun starts:
>
> 
> | zfClass zipfile entries |
> zfClass := JVM current findClass: #'java.util.zip.ZipFile'.
> zipfile := zfClass new_String: 'JNIPort.jar'.
> zipfile size. "--> answers an Integer"
> entries := zipfile entries.
> entries asAnEnumeration do: [:each | Transcript cr; print: each].
> 
>
> And now to the ugly little secret reason why I call it an alpha version:
>
> While everything seems to work, it is *much* slower than it used to be in
> Pharo 1.2 with Alien. And when I compare it with VisualWorks, I wonder if
> the Pharo version secretly does some additional work for SETI:
> - Starting the JVM:
> VisualWorks 0.7 seconds
> Pharo 7 to 8 seconds
> - A benchmark using some methods of java.io.BufferedReader and
> java.util.StringTokenizer:
> VisualWorks 114 milliseconds
> Pharo 12 to 13 seconds
>
>
profiled a bit.. this:
===
| jvmSettings |
 "You can set the path to the Java VM library by editing the path as
needed."
JNIPortJNIInterface libraryFile:
'/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Libraries/libclient.dylib'
.
"JNIPortJNIInterface libraryFile:
'C:\Programme\Java\jre7\bin\client\jvm.dll' ."

 jvmSettings := JVMSettings new.
 jvmSettings usesGhosts: true.
 jvmSettings supportsCallbacks: true.
 jvmSettings jniPortSettings  useJNIHelperLibrary: false.
jvmSettings ghostClassSettings retainMethodSource: true.

JVM newWithSettings: jvmSettings
==
and got this:

**Leaves**
22.8% {925ms} StaticJavaLangClassLoader(JavaStatic)>>knownJavaSubclasses
19.9% {804ms} JVMWithCallbacks(JVM)>>findClassFor:
5.9% {240ms} OrderedCollection>>do:
5.1% {206ms} Metaclass(Behavior)>>registerLocalSelector:
3.0% {120ms} JNIPortJNIEnv>>return:onException:
2.2% {91ms} CompiledMethod>>methodClass:
2.2% {88ms} OrderedCollection>>add:
2.1% {84ms} Array(SequenceableCollection)>>do:
2.0% {81ms} WordArray class(Behavior)>>new:
2.0% {79ms} WeakArray class>>finalizationProcess
1.3% {52ms}
JNIPortJNIInterfaceForMacOSX(JNIPortJNIInterface)>>checkReturnCode:
1.1% {46ms} Heap>>updateObjectIndex:

-
findClassFor: aJNIObject
"private -- find/make the JavaStatic that will wrap aJNIObject"

"we have to ensure that the ref is converted to global if necessary
*before* the class
lookup, since that might take considerable time during which callbacks
might happen
(especially if new ghost classes have to be construc

[Pharo-users] [ANN] WIP iStoa

2014-04-05 Thread Hilaire Fernandes
Hello,

For those who want to give a try to work in progress iStoa on Linux, an
Interactive math exercises book.

https://launchpad.net/istoa/alpha/14.04/+download/iStoa.app-14.04a.zip

Hilaire

-- 
Dr. Geo http://drgeo.eu




Re: [Pharo-users] [ANN] JNIPort for Pharo 3.0 alpha

2014-04-05 Thread Pharo4Stef
Joachim 

would you be interested to write a little Chpater for the Pharo for the 
entreprise book?
I can help.

Ste

On 05 Apr 2014, at 14:32, Joachim Geidel  wrote:

> Am 31.03.2014 um 21:25 schrieb Tudor Girba :
>> Now, the next question. I saw that it is possible to enable callbacks, but I 
>> could not find an example of how it works.
>> 
>> For example, could we model this:
>> 
>> - in a JavaClassOriginator class we have a method like
>> execute(JavaClassTargetInterface target) { target.m() }
>> - In Pharo we create PharoClassTargetImplementation as an implementation of 
>> JavaClassTargetInterface
>> - passing an instance of PharoClassTargetImplementation to 
>> JavaClassOriginator results in calling PharoClassTargetImplementation>>m
>> 
>> ?
>> 
>> 
>> Cheers,
>> Doru
> 
> Hi Doru,
> 
> it’s not completely straightforward, but also not really complicated. Chris 
> Uppal’s JNIPort documentation contains examples, and you can also get some 
> information from the test cases for callbacks. You will need the jniport.jar 
> file which can be downloaded from http://jniport.wikispaces.com/Downloads (it 
> is contained in JNIPort_Extras.zip). The Java classes needed for callback 
> support have names starting with „Dolphin“ - they come directly from Chris’ 
> implementation for Dolphin Smalltalk.
> 
> A simple example: To set up sending a simple notification without parameters 
> to a Smalltalk object, you need a Java class similar to the following:
> 
> -
> package my.package;
> import org.metagnostic.jniport.*;
> public class MyClass
> {
>   private static final Object notifyTag = new 
> String("MyClass.sendNotification()“); 
>   public static Object notifyTag () { return notifyTag; }
>   public void sendNotification()
>   throws RequestNotHandedException
>   {
>   new DolphinNotification(notifyTag, this).send();
>   }
> }
> -
> 
> You have to install the callback in Smalltalk:
> 
> -
> NotificationHandler := … "the object which receives the notifications"
> classStatic := jvm findClass: 'my.package.MyClass'.
> jvm callbackRegistry
>   setCallback: classStatic notifyTag "the tag can be an arbitrary String"
>   handler: [:this :param | NotificationHandler handleNotificationFor: 
> this].
> -
> 
> When you send sendNotification() to an instance of MyClass, 
> NotificationHandler should receive the message #handleNotificationFor:.
> 
> In the example code, the tag is a static variable in MyClass. Of course, you 
> can also give every instance of MyClass its own tag. In this case, you have 
> to set up a callback in Smalltalk for every tag which is used. 
> 
> The example is a short version of the test code for handling notifications in 
> JNIPortCallbackNotificationsTest and the corresponding Java class 
> org.metagnostic.jniport.test.regression.Notifications. The source code of 
> this Java class is in the archive JNIPort-Tests.zip which is contained in 
> JNIPort_Extras.zip.
> 
> If you need an example for a notification which has parameters and where the 
> Smalltalk code returns  a result, have a look at 
> JNIPortCallbackRequestsTest>>testCallbackWithOneParameterAndReturn and the 
> corresponding Java class org.metagnostic.jniport.test.regression.Callbacks.
> 
> In the Java class, you need something like this (copied from Callbacks and 
> simplified) which enables a callback taking an int parameter and returning an 
> instance of the Java class Integer:
> 
>private static final Object callbackTag = new String(„callback with 
> parameters"), 
> 
>   // callback with return value
>   public int callbackAndReturn(int i)
>   throws Throwable
>   {
>   Object returnValue = new DolphinRequest(callbackTag, this, 
> i).value();
>   return ((Integer) returnValue).intValue();
>   }
> 
> A DolphinRequest is created with the tag which identifies the callback in 
> Smalltalk, the object sending the callback (this), and an arbitrary number of 
> parameters. For example, the following creates a DolphinRequest with two 
> parameters:
> 
>   DolphinRequest dr = new DolphinRequest(
>   s_callbackTag,
>   this,
>   new Integer(i),
>   new Double(d));
> 
> Calling the value() method of the DolphinRequest sends the request to 
> VisualWorks and returns the result of the Smalltalk callback block.
> 
> In Smalltalk, you can create callbacks accepting parameters like this (see 
> JNIPortCallbackRequestsTest):
> 
>   "No parameters"
>   jvm callbackRegistry setCallback: classStatic callbackTag 
>   handler: [:this :param | self handleCallbackFor: this].
> 
>   "One parameter"
>   jvm callbackRegistry setCallback: classStatic callbackTag 
>   

Re: [Pharo-users] [ANN] JNIPort for Pharo 3.0 alpha

2014-04-05 Thread Joachim Geidel
Hi Igor, 

thanks a lot, your analysis is correct, and it helped.

Am 05.04.2014 um 17:05 schrieb Igor Stasenko:
> so, without going deep into implementation details, just by reading comment
> i can already see potential bottleneck - using #become: operation which is 
> veery slow.

Yes, #become: is *very* slow in Pharo. No problem at all in VisualWorks or 
Dolphin Smalltalk or Pharo 1.2, though! 

Time millisecondsToRun: [1000 timesRepeat: [String new become: String new ]] 

Pharo 3.0 (and also in 2.0 and 1.4):
 3948 3495 2891 2532 3162

Pharo 1.2 with the Squeak 4.2.5beta1U VM:
 90 89 82 90 72

VisualWorks 7.9.1: note that this is measured in microseconds: 
Time microsecondsToRun: [1000 timesRepeat: [String new become: String new ]] 
 211 208 222 212 208

That’s a factor of more than 10.000! IMHO, someone should have a look at the 
primitives involved.

> also, by tracking senders of #knownJavaSubclasses , i see there's also uses 
> of #become operation.. 
> 
> So, my first verdict is: 
>- excessive use of #become ==> slow performance
> :)
> 
> (sure, i have no idea if you can avoid using become or not, but my bet this  
> is main reason of low performance)

Well, given the measurements above, I wouldn’t say that the reason is excessive 
use of #become:, but the extremely slow implementation of #become: in Pharo 
since 1.4. However, I managed to remove the need for sending #become: in 
#findClassFor:, but not in the second place. This reduces the time to start a 
Java VM to 5-6 seconds on my aged machine (2.4 GHz Intel Core 2 Duo from early 
2008). The benchmark which I mentioned in my announcement and which took 12 
seconds came down to less than 0.2 seconds. That's a little more than the 0.11 
seconds in VisualWorks, but at least in the same order of magnitude.

Thanks again!
Joachim