changeset 15763:56239ff815a3

build: Overhaul auto-detection of Java when JAVA_HOME is not set. * build-aux/OctJavaQry.class: Compiled code to help configure determine installation directories. Exported in tarball. * build-aux/OctJavaQry.java: Java code to help configure determine installation directories. * Makefile.am: Export OctJavaQry.class code in tarball. * configure.ac: If JAVA_HOME is unset, attempt to find a Java executable. Use java executable and Java code to try and determine necessary directories. * libinterp/octave-value/ov-java.cc: Use JAVA_LDPATH variable to find libjvm.
author Rik <rik@octave.org>
date Mon, 10 Dec 2012 13:15:08 -0800
parents a5475ba0d199
children 0a27a0e157a6
files Makefile.am build-aux/OctJavaQry.class build-aux/OctJavaQry.java configure.ac libinterp/octave-value/ov-java.cc
diffstat 5 files changed, 152 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.am	Sun Dec 09 18:27:58 2012 -0500
+++ b/Makefile.am	Mon Dec 10 13:15:08 2012 -0800
@@ -43,6 +43,7 @@
   build-aux/mk-opts.pl \
   build-aux/mkinstalldirs \
   build-aux/move-if-change \
+  build-aux/OctJavaQry.class \
   etc/NEWS.1 \
   etc/NEWS.2 \
   etc/NEWS.3 \
Binary file build-aux/OctJavaQry.class has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/build-aux/OctJavaQry.java	Mon Dec 10 13:15:08 2012 -0800
@@ -0,0 +1,19 @@
+// Code used by configure script to locate Java installation variables.
+// Only compiled code, OctJavaQry.class, is distributed.
+public class OctJavaQry
+{
+  public static void main (String[] args)
+  {
+    if (args.length > 0)
+    {
+      if (args[0].equals ("JAVA_HOME"))
+      {
+        System.out.println (System.getProperty ("java.home"));
+      }
+      else if (args[0].equals ("JAVA_LDPATH"))
+      {
+        System.out.println (System.getProperty ("java.library.path"));
+      }
+    }
+  }
+}
--- a/configure.ac	Sun Dec 09 18:27:58 2012 -0500
+++ b/configure.ac	Mon Dec 10 13:15:08 2012 -0800
@@ -2221,130 +2221,154 @@
 HAVE_JAVA=no
 ## Grab JAVA_HOME from environment variable if it exists
 AC_ARG_VAR([JAVA_HOME], [path to Java JDK installation])
-JAVA_ARCH=
+JAVA_LDPATH=
+JAVA=
 JAVAC=
 JAR=
 JAVA_CPPFLAGS=
 JAVA_LIBS=
 
-if test $build_java = true; then
-
-  warn_java=
-
+## Fake loop so that "break" can be used to skip code blocks
+while test $build_java = true
+do
+  ## Warn if JAVA_HOME is unset.  It is *strongly* advised to specify JAVA_HOME.
   if test -z "$JAVA_HOME"; then
     AC_MSG_WARN([JAVA_HOME environment variable not initialized.])
     AC_MSG_WARN([Auto-detection will proceed but is unreliable.])
   fi
 
+  ## Search for a viable Java executable
   if test -z "$JAVA_HOME"; then
-    AC_CHECK_PROG(JAVA, java, java)
-    AC_CHECK_PROG(JAVAC, javac, javac)
-    AC_CHECK_PROG(JAR, jar, jar)
+    JAVA_PATH=$PATH
+  else
+    JAVA_PATH=${JAVA_HOME}$PATH_SEPARATOR${JAVA_HOME}/jre/bin$PATH_SEPARATOR${JAVA_HOME}/bin$PATH_SEPARATOR${JAVA_HOME}/../bin$PATH_SEPARATOR${PATH}
+  fi
+  AC_PATH_PROG(JAVA, java, [], [$JAVA_PATH])
+
+  if test -z "$JAVA"; then
+    AC_MSG_WARN([No Java executable found.  Octave will not be able to call Java methods.])   
+    break
+  fi
+
+  if test -z "$JAVA_HOME"; then
+    ## Find JAVA_HOME for JRE by running java and querying properties
+    JAVA_TMP_HOME=`$JAVA -classpath ${srcdir}/build-aux OctJavaQry JAVA_HOME`  
+    ## Strip directory back to top-level installation dir (JAVA_HOME for JDK) 
+    JAVA_HOME=`echo $JAVA_TMP_HOME | sed -e "s|/bin/\?$||" -e "s|/jre/\?$||"`
+  fi
+
+  ## Amend search path for JAVAC and JAR.
+  if test -z JAVA_HOME; then
+    JAVA_PATH=$PATH
   else
-    AC_PATH_PROG(JAVA, java, [], [$JAVA_HOME/bin$PATH_SEPARATOR$PATH])
-    AC_PATH_PROG(JAVAC, javac, [], [$JAVA_HOME/bin$PATH_SEPARATOR$PATH])
-    AC_PATH_PROG(JAR, jar, [], [$JAVA_HOME/bin$PATH_SEPARATOR$PATH])
+    JAVA_PATH=${JAVA_HOME}$PATH_SEPARATOR${JAVA_HOME}/bin$PATH_SEPARATOR${JAVA_HOME}/../bin$PATH_SEPARATOR${PATH}
+  fi
+
+  AC_PATH_PROG(JAVAC, javac, [], [$JAVA_PATH])
+  AC_PATH_PROG(JAR, jar, [], [$JAVA_PATH])
+
+  if test -z "$JAVAC" || test -z "$JAR"; then
+    AC_MSG_WARN([No javac compiler or jar executable found.  Octave will not be able to call Java methods.])
+    break
+  fi
+
+  ## Check Java version is recent enough.
+  AC_MSG_CHECKING([for Java version])
+  java_version=[`$JAVA -version 2>&1 | sed -n -e 's/^java version[^0-9"]*"\([^"]*\)"/\1/p'`]
+  AC_MSG_RESULT($java_version)
+  java_major=[`echo $java_version | sed -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\..*$/\1/'`]
+  java_minor=[`echo $java_version | sed -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\..*$/\2/'`]
+  if test $java_major -ge 1 && test $java_minor -ge 5; then
+    :  # Version is ok.  Do nothing.
+  else
+    AC_MSG_WARN([Java version is too old (< 1.5).  Octave will not be able to call Java methods.])
+    break
   fi
-  if test -n "$JAVAC" && test -n "$JAR"; then
-    AC_MSG_CHECKING([for Java version])
-    java_version=[`$JAVA -version 2>&1 | sed -n -e 's/^java version[^0-9"]*"\([^"]*\)"/\1/p'`]
-    AC_MSG_RESULT($java_version)
-    java_major=[`echo $java_version | sed -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\..*$/\1/'`]
-    java_minor=[`echo $java_version | sed -e 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\)\..*$/\2/'`]
-    if test $java_major -ge 1 && test $java_minor -ge 5; then
-      case $canonical_host_type in
-        *-msdosmsvc*)
-          HAVE_JAVA=yes
-          JAVA_LIBS=-ladvapi32
-        ;;
-        *-*-darwin*)
-          if test -z "$JAVA_HOME"; then
-            ## This is the location of Java on an OS X box. In this
-            ## directory we can find the various versions of a JavaVMs.
-            ## Check for the newest version set the JAVA_HOME variable.
-            if test -d "/System/Library/Frameworks/JavaVM.framework"; then
-              JAVA_TEMP="/System/Library/Frameworks/JavaVM.framework"
-              JAVA_HOME="${JAVA_TEMP}/Home"
-              JAVA_ARCH="${JAVA_TEMP}/Libraries/libjvm_compat.dylib"
-            fi
-          fi
-          JAVA_HOME=[`echo $JAVA_HOME | sed -e 's|/$||'`]
-          if test -z "$JAVA_ARCH"; then
-            if test -d "${JAVA_HOME}/jre/lib/mac"; then
-              JAVA_ARCH="mac"
-            elif test -d "${JAVA_HOME}/jre/lib/maci"; then
-              JAVA_ARCH="maci"
-            fi
-          fi
-          if test -n "$JAVA_ARCH"; then
-            HAVE_JAVA=yes
-            ## Sneak the -framework flag into mkoctfile via LFLAGS
-            LFLAGS="$LFLAGS -framework JavaVM"
-            ## According to: http://developer.apple.com/unix/crossplatform.html
-            ## one must explicitly set the include path
-            JAVA_CPPFLAGS="-I${JAVA_HOME}/include"
-            JAVA_LIBS="-framework JavaVM"
-          fi
-        ;;
-        *)
-          if test -z "$JAVA_HOME"; then
-            ## This is the Debian default path
-            if test -d "/usr/lib/jvm/default-java"; then
-              JAVA_HOME=/usr/lib/jvm/default-java
-            ## This is the path of java 6 on debian
-            elif test -d "/usr/lib/jvm/java-6-sun"; then
-              JAVA_HOME=//usr/lib/jvm/java-6-sun
-            else
-              JAVA_HOME=/usr/lib/jvm
-            fi
-          fi
-          JAVA_HOME=[`echo $JAVA_HOME | sed -e 's|/$||'`]
-          if test -z "$JAVA_ARCH"; then
-            if test -d "${JAVA_HOME}/jre/lib/i386"; then
-              JAVA_ARCH="i386";
-            elif test -d "${JAVA_HOME}/jre/lib/amd64"; then
-              JAVA_ARCH="amd64"
-            elif test -d "${JAVA_HOME}/jre/lib/solaris"; then
-              JAVA_ARCH="solaris"
-            elif test -d "${JAVA_HOME}/jre/lib/solarisv9"; then
-              JAVA_ARCH="solarisv9"
-            fi
-          fi
-          if test -n "$JAVA_ARCH"; then
-            HAVE_JAVA=yes
-            case $canonical_host_type in
-              *-mingw* | *-cygwin*)
-                JAVA_CPPFLAGS="-I${JAVA_HOME}/include -I${JAVA_HOME}/include/win32"
-                JAVA_LIBS=-ladvapi32
-              ;;
-              *)
-                JAVA_CPPFLAGS="-I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux"
-              ;;
-            esac
-          fi
-        ;;
-      esac
-      if test $HAVE_JAVA = yes; then
-        AC_DEFINE(HAVE_JAVA, 1,
-          [Define to 1 if Java is available and is at least version 1.5])
-      fi
-    else
-      warn_java="Java 1.5 or later not found.  Octave will not be able to call Java methods."
-    fi
+
+  ## At this point Win32 systems have enough configuration data.
+  case $canonical_host_type in
+    *-msdosmsvc*)
+      HAVE_JAVA=yes
+      JAVA_LIBS=-ladvapi32
+      AC_DEFINE(HAVE_JAVA, 1,
+        [Define to 1 if Java is available and is at least version 1.5])
+      break
+    ;;
+  esac
+
+  ## Run Java to try and determine library path to libjvm.so.
+  JAVA_TMP_LDPATH=`$JAVA -classpath ${srcdir}/build-aux OctJavaQry JAVA_LDPATH`
+  JAVA_TMP_LDPATH=`echo $JAVA_TMP_LDPATH | sed -e 's/^://' -e 's/:$//' -e 's/:/ /g'`
+	for dir in $JAVA_TMP_LDPATH; do
+    case $canonical_host_type in
+      *-*-darwin*)
+        if test -f "$dir/libjvm.dylib"; then
+          JAVA_LDPATH=$dir
+          break
+        fi
+      ;;
+      *)
+        if test -f "$dir/libjvm.so"; then
+          JAVA_LDPATH=$dir
+          break
+        fi
+      ;;
+    esac
+  done
+  if test -z "$JAVA_LDPATH"; then
+    AC_MSG_WARN([Library libjvm not found.  Octave will not be able to call Java methods.])
+    break
   fi
-fi
+
+  ## Java and JVM found.  Set up flags.
+  case $canonical_host_type in
+    *-*-darwin*)
+      ## Sneak the -framework flag into mkoctfile via LFLAGS
+      LFLAGS="$LFLAGS -framework JavaVM"
+      ## According to: http://developer.apple.com/unix/crossplatform.html
+      ## one must explicitly set the include path
+      JAVA_CPPFLAGS="-I${JAVA_HOME}/include"
+      JAVA_LIBS="-framework JavaVM"
+    ;;
+    *-mingw* | *-cygwin*)
+      JAVA_CPPFLAGS="-I${JAVA_HOME}/include -I${JAVA_HOME}/include/win32"
+      JAVA_LIBS=-ladvapi32
+    ;;
+    *)
+      JAVA_CPPFLAGS="-I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux"
+    ;;
+  esac
+
+  ## Search for jni.h include file.
+	JNI_PATH=`echo $JAVA_CPPFLAGS | sed -e "s/-I//g"`
+  have_jni=false
+	for dir in $JNI_PATH; do 
+	  if test -f "${dir}/jni.h"; then have_jni=true; break; fi
+	done
+  if test $have_jni = false; then
+    AC_MSG_WARN([Include file <jni.h> not found.  Octave will not be able to call Java methods.])
+    break
+  fi
+
+  ## Passed all configuration tests.  A workable Java installation was found.
+  HAVE_JAVA=yes    
+  AC_DEFINE(HAVE_JAVA, 1,
+    [Define to 1 if Java is available and is at least version 1.5])
+  break
+done
 
 ## For later reporting in configure summary
 if test $HAVE_JAVA = no; then
   build_java=false
 fi
 AM_CONDITIONAL([AMCOND_HAVE_JAVA], [test $HAVE_JAVA = yes])
+AC_SUBST(JAVA)
 AC_SUBST(JAVAC)
 AC_SUBST(JAR)
 AC_SUBST(JAVA_CPPFLAGS)
 AC_SUBST(JAVA_LIBS)
-AC_DEFINE_UNQUOTED([JAVA_HOME], ["$JAVA_HOME"], [Java home.])
-AC_DEFINE_UNQUOTED([JAVA_ARCH], ["$JAVA_ARCH"], [Java arch.])
+AC_DEFINE_UNQUOTED([JAVA_HOME], ["$JAVA_HOME"], [Java home (top-level installation dir)])
+AC_DEFINE_UNQUOTED([JAVA_LDPATH], ["$JAVA_LDPATH"], [Java library path (libjvm)])
 
 ### GUI/Qt related tests.
 
@@ -2706,7 +2730,7 @@
   HDF5 LDFLAGS:                $HDF5_LDFLAGS
   HDF5 libraries:              $HDF5_LIBS
   Java home:                   $JAVA_HOME
-  Java arch:                   $JAVA_ARCH
+  Java JVM path:               $JAVA_LDPATH
   Java CPPFLAGS:               $JAVA_CPPFLAGS
   Java libraries:              $JAVA_LIBS
   LAPACK libraries:            $LAPACK_LIBS
--- a/libinterp/octave-value/ov-java.cc	Sun Dec 09 18:27:58 2012 -0500
+++ b/libinterp/octave-value/ov-java.cc	Mon Dec 10 13:15:08 2012 -0800
@@ -449,9 +449,14 @@
         throw std::string ("unable to find Java Runtime Environment");
     }
 
+#else  // Not Win32 system
+  
+  // JAVA_LDPATH determined by configure and set in config.h
+#if defined (__APPLE__)
+  std::string jvm_lib_path = JAVA_LDPATH + std::string ("/libjvm.dylib");
 #else
-
-  std::string jvm_lib_path = JAVA_HOME + std::string ("/jre/lib/") + JAVA_ARCH + "/server/libjvm.so";
+  std::string jvm_lib_path = JAVA_LDPATH + std::string ("/libjvm.so");
+#endif
 
 #endif