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

[567 byte] By [Marton.Sigmonda] at [2007-11-27 10:56:07]
# 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

AndrewThompson64a at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

Marton.Sigmonda at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

AndrewThompson64a at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

Marton.Sigmonda at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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.

AndrewThompson64a at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

dietz333a at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

Marton.Sigmonda at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

Marton.Sigmonda at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 9

Any idea on this?

Thanks: Marton

Marton.Sigmonda at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

yomismoa at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 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

Marton.Sigmonda at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...
# 12

Hi

The BUG id 6191612. refers to same or related question

May be this helps

yomismoa at 2007-7-29 12:01:04 > top of Java-index,Desktop,Deploying...