[m-rev.] for review: add example of calling Mercury libraries from Java

Julien Fischer jfischer at opturion.com
Fri Dec 5 13:44:13 AEDT 2014


For review by anyone.

------------------------------

Add an example of calling Mercury libraries from Java.

In particular, demonstrate how to invoke any module-local finalisers and
retrieve the exit status.

samples/java_interface/standalone_java/Makefile:
samples/java_interface/standalone_java/JavaMain.java:
samples/java_interface/standalone_java/mercury_lib.m:
 	As above.

samples/java_interface/README:
 	Describe the new directory.

Julien.

diff --git a/samples/java_interface/README b/samples/java_interface/README
index d4bc3b8..f44da10 100644
--- a/samples/java_interface/README
+++ b/samples/java_interface/README
@@ -1,10 +1,11 @@
-
  This directory contains some examples of mixed Mercury/Java programs using
  the Java interface.

-mercury_calls_java		A detailed example of Mercury code
-				calling Java code.
+mercury_calls_java              A detailed example of Mercury code
+                                calling Java code.

-java_calls_mercury		A detailed example of Java code calling
-				Mercury code.
+java_calls_mercury              A detailed example of Java code calling
+                                Mercury code.

+standalone_java                 An example of how to call a Mercury library
+                                from a Java program.
diff --git a/samples/java_interface/standalone_java/JavaMain.java b/samples/java_interface/standalone_java/JavaMain.java
new file mode 100644
index 0000000..814f917
--- /dev/null
+++ b/samples/java_interface/standalone_java/JavaMain.java
@@ -0,0 +1,53 @@
+// vim: ts=4 sw=4 et
+
+// The JavaInternal class in the jmercury.runtime package provides various
+// Mercury runtime services that we may require.
+// All Mercury runtime and generated Java code lives in the jmercury package.
+//
+import jmercury.runtime.JavaInternal;
+
+// The mercury_lib class is generated by the compiler when we build
+// mercury_lib library.
+//
+import jmercury.mercury_lib;
+
+import static java.lang.System.out;
+
+public class JavaMain {
+
+    public static void main(String[] args)
+    {
+        // We do not need to do anything to initialise the Java version of the
+        // Mercury runtime.  It will be automatically initialised as the
+        // relevant classes are loaded by the JVM.
+
+        out.println("JavaMain: start main");
+
+        // This is a call to an exported Mercury procedure that does some I/O.
+        // The mercury_lib class contains a static method for each procedure
+        // that is foreign exported to Java.
+        //
+        mercury_lib.writeHello();
+
+        // This is a call to an exported Mercury function.
+        //
+        out.println("3^3 = " + mercury_lib.cube(3));
+
+        // When we have finished calling Mercury procedures then we need to
+        // invoke any finalisers specified using ':- finalise' declarations in
+        // the set of Mercury libraries we are using. 
+        // The static method run_finalisers() in the JavaInternal class does
+        // this.  It will also perform any Mercury runtime finalisation that
+        // may be needed.
+        //
+        JavaInternal.run_finalisers();
+
+        // The Mercury exit status (as set by io.set_exit_status/1) may be read
+        // from the static field 'exit_status' in the JavaInternal class.
+        //
+        out.println("JavaMain: Mercury exit status = "
+            + JavaInternal.exit_status);
+ 
+        out.println("JavaMain: end main");
+   }
+}
diff --git a/samples/java_interface/standalone_java/Makefile b/samples/java_interface/standalone_java/Makefile
new file mode 100644
index 0000000..407104a
--- /dev/null
+++ b/samples/java_interface/standalone_java/Makefile
@@ -0,0 +1,34 @@
+#-----------------------------------------------------------------------------#
+# This source file is hereby placed in the public domain.
+#-----------------------------------------------------------------------------#
+
+MMC = mmc
+JAVAC = javac
+JAVA = java
+
+# We need to tell javac about the Mercury libraries.
+GRADE = java
+MER_LIB_DIR = $(dir $(shell which mmc))../lib/mercury/lib/$(GRADE)
+MER_JARS = $(MER_LIB_DIR)/mer_std.jar:$(MER_LIB_DIR)/mer_rt.jar
+
+.PHONY: all
+all: run
+
+JavaMain.class: JavaMain.java mercury_lib.jar
+	$(JAVAC) JavaMain.java -cp $(MER_JARS):Mercury/classs -d .
+
+libmercury_lib.jar: mercury_lib.m
+	$(MMC) --grade $(GRADE) --make libmercury_lib
+
+.PHONY: run
+run: JavaMain.class
+	$(JAVA) -cp $(MER_JARS):./mercury_lib.jar:. JavaMain
+
+.PHONY: clean
+clean:
+	$(MMC) --make mercury_lib.realclean
+	$(RM) -f mercury_lib.jar JavaMain.class
+	$(RM) -rf Mercury
+
+.PHONY: realclean
+realclean: clean
diff --git a/samples/java_interface/standalone_java/mercury_lib.m b/samples/java_interface/standalone_java/mercury_lib.m
new file mode 100644
index 0000000..4fcdacc
--- /dev/null
+++ b/samples/java_interface/standalone_java/mercury_lib.m
@@ -0,0 +1,70 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+
+:- module mercury_lib.
+:- interface.
+
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+
+    % Write "Hello World" to the current Mercury text output stream.
+    %
+:- pred write_hello(io::di, io::uo) is det.
+
+    % cube(X) returns X * X * X.
+    %
+:- func cube(int) = int.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module int.
+:- import_module list.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+:- pragma foreign_export("Java", write_hello(di, uo),
+    "writeHello").
+
+write_hello(!IO) :-
+    io.print_line("Hello World", !IO).
+
+%-----------------------------------------------------------------------------%
+
+:- pragma foreign_export("Java", cube(in) = out,
+    "cube").
+
+cube(X) = X * X * X.
+
+%-----------------------------------------------------------------------------%
+%
+% Initialiser for this library
+%
+
+:- initialise initialiser/2.
+
+:- pred initialiser(io::di, io::uo) is det.
+
+initialiser(!IO) :-
+    io.print_line("mercury_lib: the initialiser has now been invoked.", !IO).
+
+%-----------------------------------------------------------------------------%
+%
+% Finaliser for this library
+%
+
+:- finalise finaliser/2.
+
+:- pred finaliser(io::di, io::uo) is det.
+
+finaliser(!IO) :-
+    io.print_line("mercury_lib: the finaliser has now been invoked.", !IO).
+
+%-----------------------------------------------------------------------------%
+:- end_module mercury_lib.
+%-----------------------------------------------------------------------------%



More information about the reviews mailing list