Re: Handling native libs within a Virtual Machine
Juergen Kreileder wrote:
> Tom Marble wrote:
>> Current Debian Java Policy [1] in section "Chapter 2.1: Virtual Machines"
>> stipulates "If a virtual machine supports native code, it must include
>> the
>> directory /usr/lib/jni in its search path for these dynamic libraries."
>
> JVMs should not put their native libraries into /usr/lib/jni, they
> should just add '/usr/lib/jni' to the search path for
> System.loadLibrary().
>
> This allows the installation of JNI libraries for use with all
> installed JVMs. Of course this only works if the JVMs also find the
> corresponding Java libraries.
>
> For Blackdown, we add '/usr/lib/jni' to the search path for
> System.loadLibrary() and '/usr/share/java' to java.ext.dirs when the
> VM was installed from a .deb. (Implemented in HotSpot's os_linux.cpp.)
It may be easiest to demonstrate an alternative with an example.
Allow me to use the JOGL project [1] to demonstrate the point.
If I follow the instructions for "Local installation" [2] which keeping
Debian Policy [3] in mind I then can do the following (to simulate
what a debianized jogl-demos package might do... note only the code
elements of the packaging are represented here):
1. simulate what libjogl-jni would do
A. Download jogl-natives-linux-i586.jar, and unpack it
mkdir -p /tmp/libjogl
cd /tmp/libjogl
jar xvf jogl-natives-linux-i586.jar
mv libjogl.so libjogl_awt.so libjogl_cg.so libjogl_drihack.so /usr/lib/jni/
rm -r /tmp/libjogl
2. simulate what libjogl-java would do
A. Control would depend on libjogl-jni
B. Download and install jogl.jar in /usr/share/java/
3. simulate what jogl-demos would do
A. Control would depend on libjogl-java
B. Download jogl-demos-data.jar jogl-demos.jar jogl-demos-util.jar
and place them in /usr/share/jogl-demos
C. Place the launcher jogl-demos in /usr/bin
(see attachment)
So if we assume that there is at least one Java runtime installed and
it has been selected with update-java-alternatives (UJA) then the jogl-demos
launcher can be used to launch each of the demos (demos docs here [4]):
tmarble@techno 10% jogl-demos -v 7
running JOGL demo 7 = demos.vertexProgRefract.VertexProgRefract
java version "1.5.0_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_06-b05)
Java HotSpot(TM) Client VM (build 1.5.0_06-b05, mixed mode, sharing)
LD_LIBRARY_PATH=/usr/lib/jni:/usr/local/lib:/usr/X11R6/lib
java -client -Djava.ext.dirs=/usr/share/java:/usr/share/jogl-demos demos.vertexProgRefract.VertexProgRefract
tmarble@techno 11%
So note with this example that we didn't need to /usr/lib/jni to the search
path for System.loadLibrary() nor add /usr/share/java to the default java.ext.dirs
in the JVM. Note also, from the JOGL documentation, "Dropping the JOGL jar and
native library into the extension directory of the JRE is strongly discouraged.
Doing so can cause conflicts with third-party applications launched via
Java Web Start, and causes confusion later when upgrading the distribution."
And, we know already from Debian Java Policy and existing Java applications
in Debian that a launcher script will be required in /usr/bin *anyway*
so adding LD_LIBRARY_PATH and -Djava.ext.dirs (or to -cp) seems like an
easy and a JVM neutral approach while preserving the consistency of
Java libraries in /usr/share/java and JNI in /usr/lib/jni. In fact
one could even imagine a genericized java application launcher that,
optionally, uses a specific settings a separate file
(e.g. /etc/default/jogl-demos and /usr/bin/jogl-demos -> javalauncher ).
What does everyone think of this alternative?
Regards,
--Tom
[1] https://jogl.dev.java.net/
[2] https://jogl.dev.java.net/nonav/source/browse/*checkout*/jogl/doc/userguide/index.html?rev=HEAD&content-type=text/html
[3] http://wiki.debian.org/Java/Draft
[4] https://jogl-demos.dev.java.net/nonav/source/browse/*checkout*/jogl-demos/doc/readme.html
_____________________________________________________________________________
Tom.Marble@sun.com
Senior Java Performance Engineer Sun Microsystems, Inc.
http://blogs.sun.com/tmarble What do you want from Java Libre?
#!/bin/sh
# launcher for jogl-demos
program=$(basename $0)
demos="demos.gears.Gears \
demos.hwShadowmapsSimple.HWShadowmapsSimple \
demos.infiniteShadowVolumes.InfiniteShadowVolumes \
demos.proceduralTexturePhysics.ProceduralTexturePhysics \
demos.vertexArrayRange.VertexArrayRange \
demos.vertexBufferObject.VertexBufferObject \
demos.vertexProgRefract.VertexProgRefract \
demos.vertexProgWarp.VertexProgWarp"
usage()
{
rv=$1
cat >&2 <<-EOF
usage: $program [-v|--verbose] [-h|-?|--help] [N]
where N is demo # N
without N, the list of demos is provided
EOF
list_demos
exit $rv
}
vecho()
{
[ -z "$verbose" ] || echo >&2 "$@"
}
list_demos()
{
echo " "
echo "JOGL demos available"
echo "--------------------"
i=1
for d in $demos; do
printf "%2d: %s\n" $i $d
(( i++ ))
done
}
get_demo()
{
j=$1
if [ $j -lt 1 ]; then
usage 1
fi
i=1
main=""
for d in $demos; do
if [ $i -eq $j ]; then
main=$d
break
fi
(( i++ ))
done
[ -n "$main" ] || usage 1
}
demo=
verbose=
while [ "$#" -gt 0 ]; do
case "$1" in
-v|--verbose)
verbose=yes
;;
-h|-?|--help)
usage 0
;;
-*)
usage 1
;;
*)
[ -z "$demo" ] || usage 1
demo=$1
;;
esac
shift
done
[ "$#" -eq 0 ] || usage 1
[ -n "$demo" ] || usage 0
get_demo $demo
vecho "running JOGL demo $demo = $main"
# native java libraries
if [ "X$LD_LIBRARY_PATH" = "X" ]; then
LD_LIBRARY_PATH=/usr/lib/jni
else
LD_LIBRARY_PATH=/usr/lib/jni:$LD_LIBRARY_PATH
fi
export LD_LIBRARY_PATH
# java library classes
cdir=/usr/share/java
clib=$cdir/jogl.jar
# application classes
adir=/usr/share/jogl-demos
alib=$adir/jogl-demos.jar:$adir/jogl-demos-util.jar:$adir/jogl-demos-data.jar
# application classpath
# main class set above
# main=demos.gears.Gears
# classic approach
# classpath="-cp $clib:$alib $main"
# java.ext.dirs approach
classpath="-Djava.ext.dirs=$cdir:$adir $main"
# NOTE: for other apps that have the main class in the jar manifest
# per http://java.sun.com/docs/books/tutorial/deployment/jar/appman.html
# classpath="-jar Java2Demo.jar"
# Java tunables
compiler="-client"
heap=""
gc=""
misc=""
jvmargs="$compiler $heap $gc $misc $classpath"
# application arguments
appargs=""
args="$jvmargs $appargs"
# assume /usr/bin/java has been set by update-java-alternatives
if [ -n "$verbose" ]; then
java -version
fi
vecho "LD_LIBRARY_PATH=$LD_LIBRARY_PATH"
vecho "java $args"
vecho " "
exec java $args
Reply to: