[m-rev.] for review: add MercuryFatalError exception to the Java runtime

Julien Fischer jfischer at opturion.com
Thu Jan 18 14:53:30 AEDT 2024


For review by anyone.

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

Add MercuryFatalError exception to the Java runtime.

Add MercuryFatalError, a new Java exception that is intended to be used for a
similar purpose to the C runtime's MR_fatal_error() function.

Throw a MercuryFatalError exception instead of calling System.exit() in a spot.
Calling exit() is fine for executables, but for code that is deployed in an
application server calling exit() may shut down the entire server.

java/runtime/MercuryFatalError.java:
     Add the new exception.

java/runtime/MercuryOptions.java:
     Do not call System.exit() when we encounter an unrecognized
     option in MERCURY_OPTIONS, throw a MercuryFatalError exception
     instead.

     Refactor the process() method in order to avoid indentation.

     Catch NumberFormatExceptions thrown when attempting to convert
     integer option values; rethrow them as MercuryFatalErrors.
     (XXX the C version of the runtime just ignores this error.)

java/runtime/JavaInternal.java:
     Catch and report MercuryFatalErrors in the runMain() method.

java/runtime/MercuryWorkerThread.java:
     Add an XXX about a call to System.exit() here.

Julien.

diff --git a/java/runtime/JavaInternal.java b/java/runtime/JavaInternal.java
index 584757b..fc8e675 100644
--- a/java/runtime/JavaInternal.java
+++ b/java/runtime/JavaInternal.java
@@ -77,7 +77,17 @@ public class JavaInternal {
       */
      public static void runMain(Runnable main)
      {
-        getThreadPool().runMain(main);
+        try {
+            getThreadPool().runMain(main);
+        } catch (jmercury.runtime.MercuryFatalError e) {
+            System.out.flush();
+            System.err.println("Mercury runtime: " + e.getMessage());
+            System.err.flush();
+
+            if (exit_status == 0) {
+                exit_status = 1;
+            }
+        }
      }

      /**
diff --git a/java/runtime/MercuryFatalError.java b/java/runtime/MercuryFatalError.java
index e69de29..54628ca 100644
--- a/java/runtime/MercuryFatalError.java
+++ b/java/runtime/MercuryFatalError.java
@@ -0,0 +1,23 @@
+// vim: ts=4 sw=4 expandtab ft=java
+//
+// Copyright (C) 2024 The Mercury Team.
+// This file is distributed under the terms specified in COPYING.LIB.
+//
+// This exception is for when fatal errors in the Mercury runtime.
+
+package jmercury.runtime;
+
+public class MercuryFatalError extends java.lang.Error {
+
+    public MercuryFatalError(String message) {
+        super(message);
+    }
+
+    public MercuryFatalError(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public MercuryFatalError(Throwable cause) {
+        super(cause);
+    }
+}
diff --git a/java/runtime/MercuryOptions.java b/java/runtime/MercuryOptions.java
index a27b01a..9353da9 100644
--- a/java/runtime/MercuryOptions.java
+++ b/java/runtime/MercuryOptions.java
@@ -1,9 +1,8 @@
  // vim: ts=4 sw=4 expandtab ft=java
  //
-// Copyright (C) 2014, 2016, 2018 The Mercury Team
+// Copyright (C) 2014, 2016, 2018, 2024 The Mercury Team.
  // This file is distributed under the terms specified in COPYING.LIB.
  //
-
  package jmercury.runtime;

  import java.util.List;
@@ -27,28 +26,32 @@ public class MercuryOptions {

      public void process()
      {
-        String          options;
-
-        options = System.getenv("MERCURY_OPTIONS");
-        if (options != null) {
-            Getopt getopt = new Getopt(options);
-            List<String> args;
+        String options = System.getenv("MERCURY_OPTIONS");
+        if (options == null) {
+            return;
+        }

-            for (Getopt.Option option : getopt) {
-                if (option.optionIs("P")) {
+        Getopt getopt = new Getopt(options);
+        for (Getopt.Option option : getopt) {
+            if (option.optionIs("P")) {
+                try {
                      num_processors = option.getValueInt();
-                } else {
-                    System.err.println("Unrecognized option: " + option);
-                    System.exit(1);
+                } catch (java.lang.NumberFormatException e) {
+                    throw new MercuryFatalError(
+                        "the value of the -P option must be " +
+                        "a non-negative integer", e);
                  }
-            }
-            args = getopt.getArguments();
-            if (args.size() > 0) {
-                System.err.println(
-                    "Error parsing MERCURY_OPTIONS environment variable,"
-                    + " unexpected: " + args.get(0));
+            } else {
+                throw new MercuryFatalError("Unrecognized option: " + option);
              }
          }
+
+        List<String> args = getopt.getArguments();
+        if (args.size() > 0) {
+            throw new MercuryFatalError(
+                "Error parsing MERCURY_OPTIONS environment variable,"
+                 + " unexpected: " + args.get(0));
+        }
      }

      /**
@@ -57,5 +60,4 @@ public class MercuryOptions {
      public int getNumProcessors() {
          return num_processors;
      }
-
  }
diff --git a/java/runtime/MercuryWorkerThread.java b/java/runtime/MercuryWorkerThread.java
index d685831..5bc6f7d 100644
--- a/java/runtime/MercuryWorkerThread.java
+++ b/java/runtime/MercuryWorkerThread.java
@@ -61,7 +61,8 @@ public class MercuryWorkerThread extends MercuryThread
                          // Make the thread exit after throwing an exception.
                          break;
                      } catch (Throwable e) {
-                        // Some other error occured. bail out.
+                        // Some other error occured, bail out.
+                        // XXX We should avoid calling exit() here.
                          System.err.println("Uncaught exception: " +
                              e.toString());
                          System.err.println(e.getMessage());






More information about the reviews mailing list