You are viewing a plain text version of this content. The canonical link for it is here.
Posted to pylucene-dev@lucene.apache.org by Bill Janssen <ja...@parc.com> on 2009/10/15 04:34:30 UTC

finding Java on Linux

Andi Vajda <va...@apache.org> wrote:

> The same approach could be used for figuring out the Java stuff. Have
> a small class running in Java tell us.

You would think, wouldn't you?  But then you'll often end up with gcj.
The JDK/JRE distinction is another killer.

> On Linux, every distro has its own, incompatible, way of telling where
> java is. I just experienced this going from Gentoo to Fedora Core 11.

Oh, yeah, I've got another script, figure-linux-java.py, that locates
the Java SDK on Linux boxes.  If you're curious, you can pull it out of
one of the UpLib tarballs at http://uplib.parc.com/.  (Just updated it
today to handle the latest Ubuntu...)

Bill

Re: finding Java on Linux

Posted by Andi Vajda <va...@apache.org>.
On Thu, 15 Oct 2009, Bill Janssen wrote:

> Andi Vajda <va...@apache.org> wrote:
>
>> I was making suggestions in the context of simplifying the common
>> case: PyLucene users don't care (they're Python users first) what Java
>> version they use or have and just want it to work (tm). They're happy
>> to just have one version of Java installed and put it on their PATH. I
>> could be wrong, of course with 'happy', of course.
>
> Will gcj support PyLucene these days?  If so, you're fine.

I doubt it. Just including the headers fails.
Also, supporting gcj via JNI would make me cringe since it has a much better 
C++ interface into Java. It would need custom code to take advantage of it.
Does gcj have a future, is it worth the effort ?

> If not, the Java-ignorant folks you're postulating will be receiving a
> package that will be broken more often than not

No, only on RedHat, and they're moving to OpenJDK like everyone else.

> and will have a hard
> time understanding why that's the case.  Wouldn't you rather have
> something that works more often than not?

The error message would clearly state that they're using a version of Java 
that is not supported. I don't understand why they couldn't understand it.

> Maybe the state of Java-on-Linux is quite different by now.  I worked
> all this out a couple of years ago, when all my Linux users kept
> tripping over the default Java being gcj.

It's still common on RedHat. On other distros, either Sun JDK or OpenJDK is 
there. I just hit that on Fedora Core 11.

Andi..

Re: finding Java on Linux

Posted by Bill Janssen <ja...@parc.com>.
Andi Vajda <va...@apache.org> wrote:

> I was making suggestions in the context of simplifying the common
> case: PyLucene users don't care (they're Python users first) what Java
> version they use or have and just want it to work (tm). They're happy
> to just have one version of Java installed and put it on their PATH. I
> could be wrong, of course with 'happy', of course.

Will gcj support PyLucene these days?  If so, you're fine.

If not, the Java-ignorant folks you're postulating will be receiving a
package that will be broken more often than not, and will have a hard
time understanding why that's the case.  Wouldn't you rather have
something that works more often than not?

Maybe the state of Java-on-Linux is quite different by now.  I worked
all this out a couple of years ago, when all my Linux users kept
tripping over the default Java being gcj.

Bill

Re: finding Java on Linux

Posted by Andi Vajda <va...@apache.org>.
On Oct 15, 2009, at 9:40, Bill Janssen <ja...@parc.com> wrote:

> Andi Vajda <va...@apache.org> wrote:
>
>> Emit an error message that says "sorry, gcj is not supported, please
>> use OpenJDK or Sun JDK" and abort.
>
> Right.  That's the problem, as I see it.  If you have Sun Java
> installed, it's not necessarily first on your path.  But you want to
> find it, even if it's masked by gcj.  You don't want to abort.

This goes beyond what I had in mind.
The case where you want to use a Java not on the PATH is advanced  
enough for either your scripts to handle or the manual edits in  
setup.py and Makefile required today.

I was making suggestions in the context of simplifying the common  
case: PyLucene users don't care (they're Python users first) what Java  
version they use or have and just want it to work (tm). They're happy  
to just have one version of Java installed and put it on their PATH. I  
could be wrong, of course with 'happy', of course.

Andi..

>
>
>> JAVA_HOME is returned by System.getProperty('java.home'). Java should
>> know best. If you can build and run that class, it means you have a
>> JDK and you can now ask it to tell you about itself.
>
> Right.  Now, suppose it tells you it's not the right Java, not a Java
> that will allow you to use it.  What next?  I don't see a good
> alternative to having some script that has a number of likely search
> paths in it, and which searches each possible location until it  
> finds a
> suitable Java.  In which case, using Java to find "java.home" isn't  
> much
> use -- you're already looking in some specific spot.  Might as well  
> use
> the locate db to find all instances of javac, and search each  
> directory
> you find there.
>
> Bill

Re: finding Java on Linux

Posted by Bill Janssen <ja...@parc.com>.
Andi Vajda <va...@apache.org> wrote:

> Emit an error message that says "sorry, gcj is not supported, please
> use OpenJDK or Sun JDK" and abort.

Right.  That's the problem, as I see it.  If you have Sun Java
installed, it's not necessarily first on your path.  But you want to
find it, even if it's masked by gcj.  You don't want to abort.

> JAVA_HOME is returned by System.getProperty('java.home'). Java should
> know best. If you can build and run that class, it means you have a
> JDK and you can now ask it to tell you about itself.

Right.  Now, suppose it tells you it's not the right Java, not a Java
that will allow you to use it.  What next?  I don't see a good
alternative to having some script that has a number of likely search
paths in it, and which searches each possible location until it finds a
suitable Java.  In which case, using Java to find "java.home" isn't much
use -- you're already looking in some specific spot.  Might as well use
the locate db to find all instances of javac, and search each directory
you find there.

Bill

Re: finding Java on Linux

Posted by Andi Vajda <va...@apache.org>.
On Wed, 14 Oct 2009, Bill Janssen wrote:

> Andi Vajda <va...@apache.org> wrote:
>
>> On Wed, 14 Oct 2009, Bill Janssen wrote:
>>
>>> Andi Vajda <va...@apache.org> wrote:
>>>
>>>> The same approach could be used for figuring out the Java stuff. Have
>>>> a small class running in Java tell us.
>>>
>>> You would think, wouldn't you?  But then you'll often end up with gcj.
>>
>> And it would tell you by looking at System.getProperties(), no ?
>
> Sure.  But what do you do then?

Emit an error message that says "sorry, gcj is not supported, please use 
OpenJDK or Sun JDK" and abort.

>>> The JDK/JRE distinction is another killer.
>>
>> Indeed but then trying to compile that small class would fail telling
>> us that there is no JDK.
>
> Maybe I'm just dense, but my requirements may be more extreme than
> PyLucene's.  I need "jar", "keytool" and "jarsigner", too.

So, if these things are in the JDK, then so is javac and building this small 
class works. If javac is not there, no JDK is there and the build aborts.
If someone has a doctored Java install, with javac but not these other 
tools, they're on their own.

> Here's the fragment of UpLib's configure.in I use for Java configuation:
>
> # it would be nice to know where JAVA_HOME is

JAVA_HOME is returned by System.getProperty('java.home'). Java should know 
best. If you can build and run that class, it means you have a JDK and you 
can now ask it to tell you about itself.

Andi..

>
> AC_ARG_WITH(javahome, [  --with-javahome=JAVA_HOME_PATH], java_home=$with_javahome, java_home="")
> if test "x$java_home" != "x"; then
>  AC_MSG_CHECKING(JAVA_HOME value)
>  if test -d "$java_home"; then
>    JAVAHOME=$java_home
>    AC_SUBST(JAVAHOME)
>    AC_MSG_RESULT([$JAVAHOME])
>  else
>    AC_MSG_ERROR([Invalid non-directory value specified for --with-javahome])
>  fi
> fi
> if test "x$JAVAHOME" = "x"; then
>  if test "$OS_TARGET" = "Linux"; then
>     AC_MSG_CHECKING(for JAVA_HOME)
>     JAVAHOME=`$PYTHON unix/linux/figure-linux-java.py`
>     if test "$JAVAHOME" != ""; then
>        AC_MSG_RESULT($JAVAHOME)
>     else
>        AC_MSG_ERROR(No java installation found on this machine.)
>     fi
>  elif test "$OS_TARGET" = "Darwin"; then
>     if test -x /usr/libexec/java_home; then
>        JAVAHOME=`/usr/libexec/java_home -v 1.5`
>     else
>        JAVAHOME=/Library/Java/Home
>     fi
>  elif test "$OS_TARGET" = "win32"; then
>     AC_MSG_CHECKING(for JAVA_HOME)
>     JAVAHOME=`"$PYTHON" win32/find-javahome.py`
>     if test "$JAVAHOME" != ""; then
>        AC_MSG_RESULT($JAVAHOME)
>     else
>        AC_MSG_ERROR(No java installation found on this machine.)
>     fi
>  else
>     AC_PATH_PROG(JAVAC, "javac")
>     AC_PATH_PROG(JAVA, "java")
>     if test "x$JAVAC" = "x" -o "x$JAVA" = "x"; then
>       AC_ERROR([No value for Java home, and either "java" or "javac" can't be found on the path.])
>     fi
>     AC_MSG_CHECKING(for JAVA_HOME)
>     result=`["$JAVAC" -classpath ./java ./java/testProperty.java; "$JAVA" -classpath ./java testProperty home.java]`
>     if test -d "$result"; then
>       JAVAHOME=$result
>       AC_MSG_RESULT([$JAVAHOME])
>     else
>       AC_MSG_ERROR([Can't find JAVA_HOME; use --with-javahome=PATH to specify the path for JAVA_HOME])
>     fi
>  fi
> fi
> AC_PATH_PROG(JAVA, "java", , [ "$JAVAHOME/jre/bin" "$JAVAHOME/bin" $PATH ])
> AC_PATH_PROG(JAVAC, "javac", , [ "$JAVAHOME/bin" $PATH ])
> AC_PATH_PROG(JAR, "jar", , [ "$JAVAHOME/bin" $PATH ])
> AC_PATH_PROG(KEYTOOL, "keytool", , [ "$JAVAHOME/jre/bin" "$JAVAHOME/bin" $PATH ])
> AC_PATH_PROG(JARSIGNER, "jarsigner", , [ "$JAVAHOME/jre/bin" "$JAVAHOME/bin" $PATH ])
>
> # what version of java?
> java_version=`"$JAVA" -version 2>&1 | head -1 | sed -e 's/java version //g' -e 's/"//g'`
> AC_SUBST(JAVA_MAJOR_VERSION)
> AC_SUBST(JAVA_MINOR_VERSION)
> AC_SUBST(JAVA_MICRO_VERSION)
> AC_MSG_RESULT([looking at Java version $java_version...])
> JAVA_MAJOR_VERSION=[`"$PYTHON" -c "\
> import sys, re
> print re.split('[\.\_]', '$java_version')[0]"`]
> JAVA_MINOR_VERSION=[`"$PYTHON" -c "\
> import sys, re
> print re.split('[\.\_]', '$java_version')[1]"`]
> JAVA_MICRO_VERSION=[`"$PYTHON" -c "\
> import sys, re
> print re.split('[\.\_]', '$java_version')[2]"`]
> JAVA_BUILD_VERSION=[`"$PYTHON" -c "\
> import sys, re
> splits=re.split('[\.\_]', '$java_version')
> print ((len(splits) > 3) and splits[3]) or 5"`]
> AC_SUBST(JAVA_HOTSPOT_FLAGS)
> JAVA_HOTSPOT_FLAGS=""
> if test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -eq 6 -a $JAVA_MICRO_VERSION -eq 0 -a $JAVA_BUILD_VERSION -gt 3 -a $JAVA_BUILD_VERSION -lt 11 ; then
>  JAVA_HOTSPOT_FLAGS="-Xint"
>  AC_MSG_RESULT([This version of Java ($java_version) contains a Hotspot bug which causes corrupt Lucene indices.  JIT compilation will be disabled.])
> fi
> AC_SUBST(JAVA_COMPAT_FLAG)
> AC_SUBST(JAVA_HAS_COOKIE_HANDLING)
> JAVA_COMPAT_FLAG=""
> JAVA_HAS_COOKIE_HANDLING=yes
> if test $JAVA_MAJOR_VERSION -ge 1 -a $JAVA_MINOR_VERSION -gt 4 ; then
>  if test "$need1dot4" = "yes" ; then
>    JAVA_COMPAT_FLAG="-source 1.4 -target 1.4"
>    JAVA_HAS_COOKIE_HANDLING=no
>    AC_MSG_RESULT(Java version is $java_version; using JAVA_COMPAT_FLAG of "$JAVA_COMPAT_FLAG")
>  else
>    AC_MSG_RESULT(Java version is $java_version; no JAVA_COMPAT_FLAG needed)
>  fi
> elif test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -lt 4; then
>  AC_MSG_ERROR(Java version is $java_version; we need at least 1.4.2.)
> elif test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -eq 4 -a $JAVA_MICRO_VERSION -lt 2; then
>  AC_MSG_ERROR(Java version is $java_version; we need at least 1.4.2.)
> else
>  if test $JAVA_MINOR_VERSION -lt 5; then
>    JAVA_HAS_COOKIE_HANDLING=no
>  fi
>  AC_MSG_RESULT(Java version is $java_version; no JAVA_COMPAT_FLAG needed)
> fi
> if test "$JAVA_HAS_COOKIE_HANDLING" = "no"; then
>  AC_MSG_RESULT([No cookie handling in Java clients; password must be passed on each call])
> fi
>
> # check for Java debug flags
> AC_MSG_CHECKING(for Java debug)
> AC_ARG_ENABLE(java-debug, [  --enable-java-debug], JAVADEBUGFLAGS="$enableval", JAVADEBUGFLAGS="-g")
> AC_SUBST(JAVADEBUGFLAGS)
> if test "$JAVADEBUGFLAGS" = "no"; then
>  AC_MSG_RESULT(no)
>  JAVADEBUGFLAGS=""
> elif test "$JAVADEBUGFLAGS" = "yes"; then
>  JAVADEBUGFLAGS="-g"
>  AC_MSG_RESULT(yes:  $JAVADEBUGFLAGS)
> else
>  if test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -eq 4; then
>    JAVADEBUGFLAGS="$JAVADEBUGFLAGS -deprecation"
>  fi
>  AC_MSG_RESULT(yes:  $JAVADEBUGFLAGS)
> fi
>
> AC_MSG_CHECKING(for Java classpath separator character)
> AC_SUBST(JAVACLASSPATHSEP)
> if test "$OS_TARGET" = "win32"; then
>  JAVACLASSPATHSEP=";"
> else
>  JAVACLASSPATHSEP=":"
> fi
> AC_MSG_RESULT($JAVACLASSPATHSEP)
>


Re: finding Java on Linux

Posted by Bill Janssen <ja...@parc.com>.
Andi Vajda <va...@apache.org> wrote:

> On Wed, 14 Oct 2009, Bill Janssen wrote:
> 
> > Andi Vajda <va...@apache.org> wrote:
> >
> >> The same approach could be used for figuring out the Java stuff. Have
> >> a small class running in Java tell us.
> >
> > You would think, wouldn't you?  But then you'll often end up with gcj.
> 
> And it would tell you by looking at System.getProperties(), no ?

Sure.  But what do you do then?

> > The JDK/JRE distinction is another killer.
> 
> Indeed but then trying to compile that small class would fail telling
> us that there is no JDK.

Maybe I'm just dense, but my requirements may be more extreme than
PyLucene's.  I need "jar", "keytool" and "jarsigner", too.

Here's the fragment of UpLib's configure.in I use for Java configuation:

# it would be nice to know where JAVA_HOME is

AC_ARG_WITH(javahome, [  --with-javahome=JAVA_HOME_PATH], java_home=$with_javahome, java_home="")
if test "x$java_home" != "x"; then
  AC_MSG_CHECKING(JAVA_HOME value)
  if test -d "$java_home"; then
    JAVAHOME=$java_home
    AC_SUBST(JAVAHOME)
    AC_MSG_RESULT([$JAVAHOME])
  else
    AC_MSG_ERROR([Invalid non-directory value specified for --with-javahome])
  fi
fi
if test "x$JAVAHOME" = "x"; then
  if test "$OS_TARGET" = "Linux"; then
     AC_MSG_CHECKING(for JAVA_HOME)
     JAVAHOME=`$PYTHON unix/linux/figure-linux-java.py`
     if test "$JAVAHOME" != ""; then
        AC_MSG_RESULT($JAVAHOME)
     else
        AC_MSG_ERROR(No java installation found on this machine.)
     fi
  elif test "$OS_TARGET" = "Darwin"; then
     if test -x /usr/libexec/java_home; then
        JAVAHOME=`/usr/libexec/java_home -v 1.5`
     else
        JAVAHOME=/Library/Java/Home
     fi
  elif test "$OS_TARGET" = "win32"; then
     AC_MSG_CHECKING(for JAVA_HOME)
     JAVAHOME=`"$PYTHON" win32/find-javahome.py`
     if test "$JAVAHOME" != ""; then
        AC_MSG_RESULT($JAVAHOME)
     else
        AC_MSG_ERROR(No java installation found on this machine.)
     fi
  else
     AC_PATH_PROG(JAVAC, "javac")
     AC_PATH_PROG(JAVA, "java")
     if test "x$JAVAC" = "x" -o "x$JAVA" = "x"; then
       AC_ERROR([No value for Java home, and either "java" or "javac" can't be found on the path.])
     fi
     AC_MSG_CHECKING(for JAVA_HOME)
     result=`["$JAVAC" -classpath ./java ./java/testProperty.java; "$JAVA" -classpath ./java testProperty home.java]`
     if test -d "$result"; then
       JAVAHOME=$result
       AC_MSG_RESULT([$JAVAHOME])
     else
       AC_MSG_ERROR([Can't find JAVA_HOME; use --with-javahome=PATH to specify the path for JAVA_HOME])
     fi
  fi
fi
AC_PATH_PROG(JAVA, "java", , [ "$JAVAHOME/jre/bin" "$JAVAHOME/bin" $PATH ])
AC_PATH_PROG(JAVAC, "javac", , [ "$JAVAHOME/bin" $PATH ])
AC_PATH_PROG(JAR, "jar", , [ "$JAVAHOME/bin" $PATH ])
AC_PATH_PROG(KEYTOOL, "keytool", , [ "$JAVAHOME/jre/bin" "$JAVAHOME/bin" $PATH ])
AC_PATH_PROG(JARSIGNER, "jarsigner", , [ "$JAVAHOME/jre/bin" "$JAVAHOME/bin" $PATH ])

# what version of java?
java_version=`"$JAVA" -version 2>&1 | head -1 | sed -e 's/java version //g' -e 's/"//g'`
AC_SUBST(JAVA_MAJOR_VERSION)
AC_SUBST(JAVA_MINOR_VERSION)
AC_SUBST(JAVA_MICRO_VERSION)
AC_MSG_RESULT([looking at Java version $java_version...])
JAVA_MAJOR_VERSION=[`"$PYTHON" -c "\
import sys, re
print re.split('[\.\_]', '$java_version')[0]"`]
JAVA_MINOR_VERSION=[`"$PYTHON" -c "\
import sys, re
print re.split('[\.\_]', '$java_version')[1]"`]
JAVA_MICRO_VERSION=[`"$PYTHON" -c "\
import sys, re
print re.split('[\.\_]', '$java_version')[2]"`]
JAVA_BUILD_VERSION=[`"$PYTHON" -c "\
import sys, re
splits=re.split('[\.\_]', '$java_version')
print ((len(splits) > 3) and splits[3]) or 5"`]
AC_SUBST(JAVA_HOTSPOT_FLAGS)
JAVA_HOTSPOT_FLAGS=""
if test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -eq 6 -a $JAVA_MICRO_VERSION -eq 0 -a $JAVA_BUILD_VERSION -gt 3 -a $JAVA_BUILD_VERSION -lt 11 ; then
  JAVA_HOTSPOT_FLAGS="-Xint"
  AC_MSG_RESULT([This version of Java ($java_version) contains a Hotspot bug which causes corrupt Lucene indices.  JIT compilation will be disabled.])
fi
AC_SUBST(JAVA_COMPAT_FLAG)
AC_SUBST(JAVA_HAS_COOKIE_HANDLING)
JAVA_COMPAT_FLAG=""
JAVA_HAS_COOKIE_HANDLING=yes
if test $JAVA_MAJOR_VERSION -ge 1 -a $JAVA_MINOR_VERSION -gt 4 ; then
  if test "$need1dot4" = "yes" ; then
    JAVA_COMPAT_FLAG="-source 1.4 -target 1.4"
    JAVA_HAS_COOKIE_HANDLING=no
    AC_MSG_RESULT(Java version is $java_version; using JAVA_COMPAT_FLAG of "$JAVA_COMPAT_FLAG")
  else
    AC_MSG_RESULT(Java version is $java_version; no JAVA_COMPAT_FLAG needed)
  fi
elif test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -lt 4; then
  AC_MSG_ERROR(Java version is $java_version; we need at least 1.4.2.)
elif test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -eq 4 -a $JAVA_MICRO_VERSION -lt 2; then
  AC_MSG_ERROR(Java version is $java_version; we need at least 1.4.2.)
else
  if test $JAVA_MINOR_VERSION -lt 5; then
    JAVA_HAS_COOKIE_HANDLING=no
  fi
  AC_MSG_RESULT(Java version is $java_version; no JAVA_COMPAT_FLAG needed)
fi
if test "$JAVA_HAS_COOKIE_HANDLING" = "no"; then
  AC_MSG_RESULT([No cookie handling in Java clients; password must be passed on each call])
fi

# check for Java debug flags
AC_MSG_CHECKING(for Java debug)
AC_ARG_ENABLE(java-debug, [  --enable-java-debug], JAVADEBUGFLAGS="$enableval", JAVADEBUGFLAGS="-g")
AC_SUBST(JAVADEBUGFLAGS)
if test "$JAVADEBUGFLAGS" = "no"; then
  AC_MSG_RESULT(no)
  JAVADEBUGFLAGS=""
elif test "$JAVADEBUGFLAGS" = "yes"; then
  JAVADEBUGFLAGS="-g"
  AC_MSG_RESULT(yes:  $JAVADEBUGFLAGS)
else
  if test $JAVA_MAJOR_VERSION -eq 1 -a $JAVA_MINOR_VERSION -eq 4; then
    JAVADEBUGFLAGS="$JAVADEBUGFLAGS -deprecation"
  fi
  AC_MSG_RESULT(yes:  $JAVADEBUGFLAGS)
fi

AC_MSG_CHECKING(for Java classpath separator character)
AC_SUBST(JAVACLASSPATHSEP)
if test "$OS_TARGET" = "win32"; then
  JAVACLASSPATHSEP=";"
else
  JAVACLASSPATHSEP=":"
fi
AC_MSG_RESULT($JAVACLASSPATHSEP)

Re: finding Java on Linux

Posted by Andi Vajda <va...@apache.org>.
On Wed, 14 Oct 2009, Bill Janssen wrote:

> Andi Vajda <va...@apache.org> wrote:
>
>> The same approach could be used for figuring out the Java stuff. Have
>> a small class running in Java tell us.
>
> You would think, wouldn't you?  But then you'll often end up with gcj.

And it would tell you by looking at System.getProperties(), no ?

> The JDK/JRE distinction is another killer.

Indeed but then trying to compile that small class would fail telling us 
that there is no JDK.

Andi..