dependent system libraries - LD_LIBRARY_PATH workaround
Hi,
libA.so depends onlibB.so.
TheSystem.loadLibrary("A") call fails with the following error: java.lang.UnsatisfiedLinkError:
/home/apptest/.java/deployment/cache/6.0/8/543d1248-5a10af09-n/libA.so:
libB.so: cannot open shared object file: No such file or directory
If the application is started from batch this problem can be fixed by setting the LD_LIBRARY_PATH properly.
I do not know however how to fix the issue when the application is started via JWS.
I appreciate any help.
Marton
# 1
Section 4.2 'Setting System Properties' of the
JNLP Specification states..
"The property element defines a system property that
will be available through the System.getProperty and
System.getProperties methods. Is has two required
attributes: name and value. For example:"
<property name="key1" value="value1"/>
Or in your case, something like..
<property name="LD_LIBRARY_PATH" value="/the/path"/>
I expect the application will need to have
all-permissions, to set that property.
Message was edited by:
AndrewThompson64
# 2
Your solution works only when you know "/the/path".
In this case however the path is undetermined until the JWS engine extracts the JAR that contains the libA.so and the libB.so into the cache (see the error message above).
Marton
Message was edited by:
Marton.Sigmond
# 3
> In this case however the path is undetermined until the
> JWS engine extracts the JAR that contains the libA.so
> and the libB.so ...
Finding things in the cache is a lost cause.
This application will need to use 'variant 1 of
plan a'. This basically amounts to using a JWS
intaller-desc element* that calls Java classes that
download the shared objects and cache them on
a 'known' path. e.g.
${user.home}/com/ourcompany/ourcompanyexecutables/
Then add that path to the properties. Obviously the
property declaration in the JNLP will be redundant.
* Here is an example of using an installer.
<http://www.physci.org/jws/#eis>
Message was edited by:
AndrewThompson64
# 4
> <property name="LD_LIBRARY_PATH" value="/the/path"/>
This solution does not work even when you know "/the/path" (i.e. using an installer).
The <property name="LD_LIBRARY_PATH" value="/the/path"/> expression sets the Java system property only, it does not affect the environment in which the JVM runs.
In this case however the LD_LIBRARY_PATH environment variable needs to be set.
Or finding a workaround ...
Any idea?
Thanks,
Marton
# 5
...
> In this case however the LD_LIBRARY_PATH
> environment variable needs to be set.
Yes. I got the point about it being an environment
variable. You missed part of my point. I will try to
explain better by asking.
Can you set the environment variable from Java code?
If it is possible to do that, the code can be called
from the Java code in the installer, after it
writes the libraries to the path.
> Or finding a workaround ...
Failing that (I do not have much experience trying
to manipulate env. vars. using anything but the OS'
own control panel), the only thing I can think of is
to get a plaform specific installer to do it for you.
Note that the native installer could also be
invoked from the web start installer code,
but I have no immediate suggestions on
native installers.
# 6
In this case you do not need to do anything special. That is only if circular dependencies are present.
You just need to call System.loadLibrary("libB");
before calling System.LoadLibrary("libA");
/Andy
# 7
Andy,
this is not true, see:
public class NativeDepTest
{
public static void main ( final String[] args )
{
System.loadLibrary( "vtkCommon" );
System.loadLibrary( "vtkFiltering" );
}
}
This code will fail on the second loadLibrary() call if the LD_LIBRARY_PATH is not set.
And there is no circular dependency between the two libs, see:
$ ldd ./libvtkCommon.so
linux-gate.so.1 => (0xffffe000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7d56000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7d52000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0xb7c97000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7c70000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7c64000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7b23000)
/lib/ld-linux.so.2 (0x80000000)
$ ldd ./libvtkFiltering.so
linux-gate.so.1 => (0xffffe000)
libvtkCommon.so => ./libvtkCommon.so (0xb7d69000)
libpthread.so.0 => /lib/tls/i686/cmov/libpthread.so.0 (0xb7d45000)
libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7d40000)
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0xb7c86000)
libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7c5f000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7c53000)
libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7b12000)
/lib/ld-linux.so.2 (0x80000000)
(VTK is free, if you want to try it yourself.)
Marton
Message was edited by:
Marton.Sigmond
# 8
I do not think there is a way how an environment variable can be set from Java code.
I am looking for a solution that affects the Java application shell only, and keeps the user work environment intact. I do not think this is possible with a native installer.
I hoped that there is a solution in JNLP that is similar to the ant's java task:
<env key="LD_LIBRARY_PATH" path="/the/path" />
Marton
# 9
Any idea on this?
Thanks: Marton
# 10
Hi
May be you can solve this issue by porviding these native lib via jnlp file, for example :
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0"
codebase="......"
href="......">
<information>
<title>....</title>
</information>
<resources>
<j2se version="1.5+" initial-heap-size="64M" max-heap-size="196M"/>
<jar href="Cartografia.jar"/>
<jar href="postgresql-8.0.309.jdbc3.jar"/>
<jar href="poi-2.0-pre2-20030711.jar"/>
<jar href="weka.jar"/>
<jar href="bfopdf.jar"/>
<jar href="Jama-1.0.1.jar"/>
<jar href="jdom.jar"/>
<jar href="xerces_2_3_0.jar"/>
<jar href="vecmath.jar"/>
<jar href="j3daudio.jar"/>
<jar href="j3dcore.jar"/>
<jar href="j3dutils.jar"/>
</resources>
<resources os="Windows">
<nativelib href="j3DWinOpenGL.jar"/>
</resources>
<security>
<all-permissions/>
</security>
<application-desc main-class="......."/>
</jnlp>
Here i send one java 3D native lib, some .dll, after jaring and singning
Hope this helps
# 11
This was the first thing I tried ... without success.
The problem is that the JWS engine extracts both the libA.so and the libB.so into the cache, and adds the cache directory to the java.library.path property, but not to the LD_LIBRARY_PATH environment variable.
SInce the operating system searches libraries in paths specified by the LD_LIBRARY_PATH, opening the libA.so will fail due to the missing dependent library: libB.so.
Marton
# 12
Hi
The BUG id 6191612. refers to same or related question
May be this helps