1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
|
JVM startup debugging
=====================
So the JVM won't start under JPype. It works fine for everyone else, but just
not you. Now what? The following instructions are for Linux, but apply to
most unix like systems with minor modifications.
JAVA_HOME
---------
First make sure your JAVA_HOME is set correctly. It should point to a
directory containing the JRE or JDK. It should look something like...::
bin conf COPYRIGHT include jmods legal lib release
For Unix we expect to find ``$JAVA_HOME\lib\server\libjvm.so`` or
``$JAVA_HOME\lib\client\libjvm.dll``. We will assume it is server for this
document.
Architecture
------------
To check the type of a file, use the ``file`` command.
First lets check the architecture of the ``libjvm.so`` file::
$ file $JAVA_HOME/lib/server/libjvm.so
/usr/lib/jvm/java-11-openjdk-amd64/lib/server/libjvm.so: ELF 64-bit LSB shared object, x86-64,
version 1 (GNU/Linux), dynamically linked, BuildID[sha1]=1313ccf3deaef446a6c2fec9561f2232e4202bc8, stripped
We can also check the architecture of python or the test file::
$ file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=24c58f45e6aa4a41c0d69a74063243b692d51e0d, not stripped
$ file /usr/bin/python3.8
/usr/bin/python3.8: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, for GNU/Linux 3.2.0, BuildID[sha1]=f9e05e26d8232239158889727d8056c122a9e958, stripped
The import thing is that each must have the samme architecture. In this case, 64-bit LSB x86-64.
If one or more libraries or binaries has a mismatch then it likely won't work with that JVM.
Dependencies
------------
The JVM has many dependencies. If any of them are missing, or
not in a search path, or they are the wrong architecture then
it will fail to load. To get a list of dependencies use::
ldd -v "$JAVA_HOME/lib/server/libjvm.so"
It should produce an output similar to::
linux-vdso.so.1 (0x00007ffff3591000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fd55b5b0000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fd55b390000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fd55b000000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fd55ac60000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fd55a860000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd55cc00000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fd55a640000)
If any of these libraries are missing or the wrong architecture it will cause issues.
Testing the JVM
---------------
Assuming that you have the JAVA_HOME set, the architectures are correct, and
all of the dependencies are in place it should load. But lets run a test.
Compile using the System C++ compiler.
Use::
g++ testJVM.cpp -ldl
Run it with::
a.out "$JAVA_HOME\lib\server\libjvm.so"
It should produce and output like::
$ ./a.out $JAVA_HOME/lib/server/libjvm.so
Load library
Load entry points
Entry point found 0x7fad8e08f670
Pack JVM arguments
Num options: 0
Create JVM
Create Java resources
Destroy JVM
Unload library
Success
Testing static load
-------------------
Dlopen provides very little diagnostic information. So you may want to try a static JVM load.
To build a static JVM test use::
g++ staticJVM.cpp -ljvm -L $JAVA_HOME/lib/server/
The launch it with::
LD_LIBRARY_PATH=$JAVA_HOME/lib/server a.out
This should produce the output::
Pack JVM arguments
Num options: 0
Create JVM
Create Java resources
Destroy JVM
Success
If the library does not match it should produce something like::
./a.out: error while loading shared libraries: libjvm.so: cannot open shared object file: No such file or directory
Two different libstdc++ versions
--------------------------------
If you are compiling the source on a test environment and pushing the compiled Jpype source to a different environment (Unix/Linux) you might see a situation where running::
ldd libstdc++.so.6
links to a different version of your production environment.
You can rememdy this by copying the so file to your production system and creating a soft link to the file with::
ln -s libstdc++.so.6.0.29 libstdc++.so.6
Then override the system's (in the example below, Oracle/Solaris) 64bit dynamic linker path with::
export LD_LIBRARY_PATH_64=/path/to/linked/file/above
NOTE: You will want to include the path to any other .so files you will be needing.
|