Java/SML# interface tool. @author YAMATODANI Kiyoshi @version $Id: README.txt,v 1.2 2010/04/23 12:56:11 kiyoshiy Exp $ This tool consists of two components. - Java library This SML library defines interface layer on JNI. - java2sml.sh command This command generates SML code to access Java class and its instances. -------------------- Build and install. $ make $ make install java2sml.sh and java2sml.jar are installed. -------------------- Generate wrapper SML code for Java class. java2sml.sh command generates a wrapper SML code for Java classes. java2sml.sh [--namespace NAMESPACE] [-o FILENAME] CLASSNAME ... Assume a sample Java class C generated from C.java. public class C { public C(){} public boolean z; public Object f(Object x){return x;} } java2sml.sh generates C.sml which defines a wrapper code for C. $ java2sml.sh -o ./C.sml C -------------------- Use generated wrapper code. ----- Java/SML# interface requires JVM dll. JVM dll is installed with JDK/JRE. If Java/SML# interface cannot find JVM dll on your environment, you have to specify JVM dll manually. Assume JVM dll is installed at /usr/local/jdk/jre/lib/i386/client/libjvm.so . Specify environment JVM_DLL $ JVM_DLL=/usr/local/jdk/jre/lib/i386/client/libjvm.so $ export JVM_DLL or LD_LIBRARY_PATH $ LD_LIBRARY_PATH=/usr/local/jdk/jre/lib/i386/client/:${LD_LIBRARY_PATH} $ export LD_LIBRARY_PATH ----- Start SML#. $ smlsharp SML# 0.30 (2007-10-23 22:50:27) Load Java/SML# interface library. # use "Java.sml"; Load the generated wrapper code. # use "./C.sml"; Following code is for convenience. # val $ = Java.call; # val $$ = Java.this; First, initialize Java/SML# interface. # val _ = Java.initialize []; Then, initialize class C. # val _ = C.static(); Create an instance of class C. # val obj = C.new(); Invoke 'f' method on 'obj', with an argument 'obj' itself. # $obj#f($$obj); val it = - : Java.Value.Object '$$' is necessary to convert a ML value to a Java object reference which can be passed to JVM. Retrieve 'z' field of obj. # val z = $obj#get'z(); val z = true : bool Change 'z' field of obj. # val _ = $obj#set'z(not z); The field has been changed. # val z = $obj#get'z(); val z = false : bool -------------------- Generated SML codes. ---------- Overload. In generated SML code, overloaded methods are renamed by appending a single quotation and type descriptors of method parameters. If a method has no parameter, it is not renamed. Descriptors of base types are single characters. boolean: Z byte: B char: C short: S int: I long: J float: F double: D For example, int f(long x, int y, short z); is renamed as f'JIS. For array of type T, its descriptor is the descriptor of T followed by 's'. void f(char[][] a); is renamed as f'Css. For object reference type, its class name, not including package names, is used. void f(java.util.Set c, java.util.List c); is renamed as f'SetList This descriptor defined here is different from defined in JVM specification. And, name confliction is possible. class D{ void f(foo.C); void f(bar.C); } Both f have same descriptor: C. In that case, index number is appended. These fs are renamed as f'C'1 f'C'2. ---------- Initialize function. ----- Initialization of Java/SML#. You must call the initialize function before using Java/SML# functionality. use "Java.sml"; val _ = Java.initialize []; Arguments to 'initialize' are passed to JVM. val _ = Java.initialize [ "-Xbootclasspath/a:./csvjdbc.jar", "-Djdbc.drivers=org.relique.jdbc.csv.CsvDriver" ]; ----- Class initialization. And, you must call initialize functions for structures generated by java2sml. ML structures generated for Java classes have an initialize function, 'static'. structure C = struct : fun static () = ... end; And ML structures generated for packages have also a 'static' function. These package 'static' functions call all 'static' functions of classes and subpackages which the package contains. structure foo = struct structure bar = struct structure C = struct : fun static () = ... end structure D = struct : fun static () = ... end fun static () = (C.static (); D.static()) end fun static () = bar.static () end Before using C or D, you must call the toplevel initialize function foo.static (); or, call initialize functions of classes you use. foo.bar.C.static(); foo.bar.D.static(); --------------------