UnsatisfiedLinkError and how to use the .nar files

383 views
Skip to first unread message

geoffh...@gmail.com

unread,
Feb 25, 2014, 5:44:30 AM2/25/14
to mave...@googlegroups.com
I'm trying to use the nar-maven-plugin
I can create a .nar file, but run into the UnsatisfiedLinkError when executing
NarSystem.loadLibrary();
The error is
no native-general.1.0.0 in java.library.path

To try and identify what was happening, I imported the Maven project into Eclipse and ran the unit test that depends on the native code in the .nar file
If I load the .nar file directly with
System.load(<abs path to .nar file>);
in place of
NarSystem.loadLibrary();
then I get the error:
native-general.1.0.0: Invalid ELF header

Looking at one of the other posts, there is a comment
> The .nar files buy you mainly the ability to store the files in Maven
> repositories. However, as they contain native libraries, they usually
> cannot be used as-are, but have to be unpacked.

So my questions are:
1) how do I unpack the .nar file such that
System.load(<abs path to unpacked .nar file>);
will not give an error

2) How do I then get
NarSystem.loadLibrary();
to not result in an ULE

I've looked at various examples and used them as the basis for my build:
http://blog.bigpixel.ro/2012/07/building-cc-applications-with-maven/
https://resources.riskfocusinc.com/portal/display/PUBLIC/Maven+NAR+Plugin+Tutorial
but whatever I do, I can't get past the ULE

Thanks for reading and any help

Geoff Hartnell

unread,
Feb 27, 2014, 9:44:05 AM2/27/14
to mave...@googlegroups.com
I've made a bit of progress with the ULE / unpack problem in that a .so file is generated that contains the JNI referenced call
After a Maven build I have the following .so file
native/general/target/nar/general-1.0.0-amd64-Linux-gcc-jni/lib/amd64-Linux-gcc/jni/lib-general-1.0.0.so

In Eclipse, I can load this directly with
System.load("native/general/target/nar/general-1.0.0-amd64-Linux-gcc-jni/lib/amd64-Linux-gcc/jni/lib-general-1.0.0.so");
and no ULE or any other exception occurs

However if in Eclipse I try
NarSystem.loadLibrary() in place of the System.load call
and step into the NarSystem class, it calls
System.loadLibrary("general-1.0.0.so");

That call then fails with
no general-1.0.0 in java.library.path
and the java.library.path is
native/general/target/nar/nar-generated

So it looks like
1) the library name is somehow prefixed with 'lib-'
2) the location of the .so file does not correspond to the java.library.path

Can anyone shed any light on what I need to do to resolve the above two items so that NarSystem.loadLibrary() completes without a ULE

I stress that I am only doing this in Eclipse to debug what is happening
 - I actually want to run the maven build
 
Thanks for reading and any help


Geoff Hartnell

unread,
Feb 28, 2014, 7:08:02 AM2/28/14
to mave...@googlegroups.com
I'm trying to configure the nar-maven-plugin according to:
http://maven-nar.github.io/configuration.html

I've tried using the linker configuration options to specify the name of the output library
However, whatever I do, the output filename always has the 'lib' prefix
In the linker config I have
<linker>
  <clearDefaultOptions/>
  <options>
    <option>-o general-1.0.0.so</option>
  </options>
</linker>

However, the debug shows
[INFO] Starting link {4.6 -o general-1.0.0.so -shared -L/opt/coretech/lib -Bdynamic -lscl41 -L/opt/coretech/lib -Bdynamic -lregexp41}
[DEBUG] gcc "-o general-1.0.0.so" -shared -o lib-general-1.0.0.so /src/common/src/native/general/target/nar/obj/amd64-Linux-gcc/CommonUtils.o -L/opt/coretech/lib -Bdynamic -lscl41 -L/opt/coretech/lib -Bdynamic -lregexp41
[DEBUG] Execute:Java13CommandLauncher: Executing 'gcc' with arguments:
'-o general-1.0.0.so'
'-shared'
'-o'
'lib-general-1.0.0.so'
'/src/common/src/native/general/target/nar/obj/amd64-Linux-gcc/CommonUtils.o'
'-L/opt/coretech/lib'
'-Bdynamic'
'-lscl41'
'-L/opt/coretech/lib'
'-Bdynamic'
'-lregexp41'

Similarly in the cpp options I have
<cpp>
<clearDefaultOptions>true</clearDefaultOptions>
  <options>
    <option>-Dnullptr=0</option>
    <option>-fPIC</option>
    <option>-Wall</option>
  </options>
</cpp>

But the debug output appears to adding -c and -fPIC by default
[DEBUG] Execute:Java13CommandLauncher: Executing 'gcc' with arguments:
'-Dnullptr=0'
'-fPIC'
'-Wall'
'-c'
'-fPIC'

Any suggestions how to suppress the default options for linker and compiler
Is there something obvious that I'm missing

Thanks for reading and any help

On Tuesday, 25 February 2014 10:44:30 UTC, Geoff Hartnell wrote:

Greg Domjan

unread,
Feb 28, 2014, 7:29:46 AM2/28/14
to mave...@googlegroups.com
Hi Geoff,

The maven configuration has identified <output> as a specific tag rather than leaving it to using <options>  as this is needed in the case of dependencies making references automatically.

try
<configuration>
  <output>general-${project.version}<output>


Curious, why not use standard form prefixing with lib.

Greg

Geoff Hartnell

unread,
Feb 28, 2014, 8:35:25 AM2/28/14
to mave...@googlegroups.com
Greg,

Thanks for your reply and I'll try that shortly

The reason that I'm trying to get rid of the 'lib' prefix is because when I debug into NarSystem.loadLibary(), the generated code calls:

System.loadLibrary("general-1.0.0");

 - and that fails with a ULE and the message:
no general-1.0.0 in java.library.path

Hence I'm thinking, I need to get rid of the 'lib' prefix

However, if the System.loadLibrary call silently adds the 'lib' prefix, then perhaps the real ULE message is
no libgeneral-1.0.0 in java.library.path

 - and I just have to work out how to set the java.library.path

Would that be correct ?

Thanks
Geoff





On Tuesday, 25 February 2014 10:44:30 UTC, Geoff Hartnell wrote:

Johannes Schindelin

unread,
Mar 3, 2014, 11:07:08 AM3/3/14
to Geoff Hartnell, mave...@googlegroups.com
Hi Geoff,

On Fri, 28 Feb 2014, Geoff Hartnell wrote:

> The reason that I'm trying to get rid of the 'lib' prefix is because when I
> debug into NarSystem.loadLibary(), the generated code calls:
>
> System.loadLibrary("general-1.0.0");
>
> - and that fails with a ULE and the message:
> no general-1.0.0 in java.library.path

The problem appears to me that the system property java.library.path
(which needs to be set *before* the JVM is spun up, setting it afterwards
is too late) does not point to the directory containing
libgeneral-1.0.0.so.

The same exception would be thrown if a *dependency* of
libgeneral-1.0.0.so (use "ldd libgeneral-1.0.0.so" to find out against
what libraries it links) is not found in the java.library.path nor the
system library paths.

System.loadLibrary() will automatically prefix the name with a "lib"
(except on Windows) and add the appropriate file extension.

Ciao,
Johannes
Reply all
Reply to author
Forward
0 new messages