diff --git a/libinterp/octave-value/ov-java.cc b/libinterp/octave-value/ov-java.cc
--- a/libinterp/octave-value/ov-java.cc
+++ b/libinterp/octave-value/ov-java.cc
@@ -493,16 +493,37 @@ initial_class_path (void)
 
 #if defined (OCTAVE_USE_WINDOWS_API)
 // Declare function defined in sysdep.cc
 extern LONG
 get_regkey_value (HKEY h_rootkey, const std::string subkey,
                   const std::string name, octave_value& value);
 #endif
 
+static std::string
+find_jvm_lib_dir_under_java_home (std::string java_home_path)
+{
+#  if defined (__APPLE__)
+  std::string dylib_extension = std::string ("dylib");
+#  else
+  std::string dylib_extension = std::string ("so");
+#  endif
+  // This assumes that whatever architectures are installed are appropriate for this machine
+  std::string subdirs[] = { "jre/lib/server", "jre/lib", "lib/client", "lib/server", 
+    "jre/lib/amd64/client", "jre/lib/amd64/server", "jre/lib/i386/client", "jre/lib/i386/server" };
+  for (int i = 0; i < 8; i++)
+    {
+      std::string candidate_dir = java_home_path + "/" + subdirs[i];
+      octave::sys::file_stat libjvm_dll_exists (candidate_dir + "/libjvm." + dylib_extension);
+      if (libjvm_dll_exists)
+        return candidate_dir;
+    }
+  return "";
+}
+
 //! Initialize the java virtual machine (jvm) and field #jvm if necessary.
 //!
 //! If the jvm exists and is initialized, #jvm points to it, i.e. is not 0
 //! and there is nothing to do.
 //!
 //! If #jvm is 0 and if at least one jvm exists, attach the current thread to
 //! it by setting #jvm_attached.  Otherwise, create a #jvm with some hard-
 //! coded options:
@@ -531,26 +552,33 @@ initialize_jvm (void)
   if (jvm)
     return;
 
   JNIEnv *current_env;
   const char *static_locale = setlocale (LC_ALL, nullptr);
   const std::string locale (static_locale);
 
   octave::dynamic_library lib ("");
-  std::string jvm_lib_path = "linked in or loaded libraries";
+  std::string jvm_lib_path = "";
 
   // Check whether the Java VM library is already loaded or linked in.
   JNI_CreateJavaVM_t create_vm = reinterpret_cast<JNI_CreateJavaVM_t>
                                  (lib.search ("JNI_CreateJavaVM"));
   JNI_GetCreatedJavaVMs_t get_vm = reinterpret_cast<JNI_GetCreatedJavaVMs_t>
                                    (lib.search ("JNI_GetCreatedJavaVMs"));
 
-  if (! create_vm || ! get_vm)
+  if ( create_vm && get_vm )
+    jvm_lib_path = "linked in or loaded libraries";
+  else 
     {
+#  if defined (__APPLE__)
+      std::string dylib_extension = std::string ("dylib");
+#  else
+      std::string dylib_extension = std::string ("so");
+#  endif
 #if defined (OCTAVE_USE_WINDOWS_API)
       // In Windows, find the location of the JRE from the registry
       // and load the symbol from the dll.
       std::string key, jversion, value;
 
       // First search for JRE >= 9
       key = R"(software\javasoft\jre)";
 
@@ -596,22 +624,30 @@ initialize_jvm (void)
       jvm_lib_path = regval.xstring_value (
             "initialize_jvm: registry value \"%s\" at \"%s\" must be a string",
             value.c_str (), key.c_str ());
 
       if (jvm_lib_path.empty ())
         error ("unable to find Java Runtime Environment: %s::%s",
                key.c_str (), value.c_str ());
 #else
-      // JAVA_LDPATH determined by configure and set in config.h
-#  if defined (__APPLE__)
-      jvm_lib_path = JAVA_LDPATH + std::string ("/libjvm.dylib");
-#  else
-      jvm_lib_path = JAVA_LDPATH + std::string ("/libjvm.so");
-#  endif
+      // JAVA_HOME environment variable takes precedence
+      std::string java_home_env = octave::sys::env::getenv ("JAVA_HOME");
+      if (!java_home_env.empty ())
+        {
+          std::string jvm_lib_dir = find_jvm_lib_dir_under_java_home (java_home_env);
+          if (!jvm_lib_dir.empty ())
+            jvm_lib_path = jvm_lib_dir + "/libjvm." + dylib_extension;
+        }
+
+      // Fall back to JAVA_LDPATH determined by configure and set in config.h
+      if (jvm_lib_path.empty ())
+        {
+          jvm_lib_path = std::string (JAVA_LDPATH) + "/libjvm." + dylib_extension;
+        }
 #endif
       lib = octave::dynamic_library (jvm_lib_path);
 
       if (! lib)
         error ("unable to load Java Runtime Environment from %s",
                jvm_lib_path.c_str ());
 
       create_vm = reinterpret_cast<JNI_CreateJavaVM_t>
