- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
UnsatisfiedLinkError in console, not command line
Tue, 2009-03-03, 05:54
I'm fighting an UnsatisfiedLinkError trying to use some SWIG generated
java bindings, and I'm seeing something very puzzling. I'm hoping
someone here may recognize this problem.
Given a SWIG generated library Foo and a static function bar that
returns (int)1, I see these two behaviors:
# works with -e
> scala -cp Foo.jar -e 'System.loadLibrary("JFoo"); println(Foo.bar)'
1
>
# fails when typed interactively
> scala -cp Foo.jar
Welcome to Scala version 2.7.3.final (Java HotSpot(TM) 64-Bit Server
VM, Java 1.6.0_07).
Type in expressions to have them evaluated.
Type :help for more information.
scala> System.loadLibrary("JFoo"); println(Foo.bar)
java.lang.UnsatisfiedLinkError: Foo.JFooJNI.bar()I
at Foo.JFooJNI.bar(Native Method)
at Foo.JFoo.bar(JFoo.java:13)
at .(:5)
at .()
Just to be clear, it gets past the System.loadLibrary call. I can use
`pmap` and verify that the shared library is loaded afterwards. It
fails on the call to Foo.bar().
I don't understand why it works the first way and not the second way.
Wed, 2009-03-04, 00:17
#2
Re: Re: UnsatisfiedLinkError in console, not command line
Where do you put and declare to the jvm the location of the native library ?
try to call the interpreter with -Djava.library.path=Foo.so (or Foo.dll)
/davidB
On Tue, Mar 3, 2009 at 19:02, J Robert Ray <jrobertray@gmail.com> wrote:
try to call the interpreter with -Djava.library.path=Foo.so (or Foo.dll)
/davidB
On Tue, Mar 3, 2009 at 19:02, J Robert Ray <jrobertray@gmail.com> wrote:
I did some more digging and found the interpreter makes it own classloader.
http://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/compiler/scala/tools/nsc/InterpreterLoop.scala?rev=9925
I believe in the interactive session, the SWIG generated jar has been
loaded by the parent classloader, and my System.loadLibrary call in
the interpreter runs in a child classloader. Therefore the two don't
see each other.
I was able to make my jar work by adding a static {
System.loadLibrary(); } block to the SWIG-generated class(es). With
this in place I saw a "already loaded in another classloader" message
if I attempted to System.loadLibrary again in the console.
On Mon, Mar 2, 2009 at 8:53 PM, J Robert Ray <jrobertray@gmail.com> wrote:
> I'm fighting an UnsatisfiedLinkError trying to use some SWIG generated
> java bindings, and I'm seeing something very puzzling. I'm hoping
> someone here may recognize this problem.
>
> Given a SWIG generated library Foo and a static function bar that
> returns (int)1, I see these two behaviors:
> # works with -e
>> scala -cp Foo.jar -e 'System.loadLibrary("JFoo"); println(Foo.bar)'
> 1
>>
> # fails when typed interactively
>> scala -cp Foo.jar
> Welcome to Scala version 2.7.3.final (Java HotSpot(TM) 64-Bit Server
> VM, Java 1.6.0_07).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> System.loadLibrary("JFoo"); println(Foo.bar)
> java.lang.UnsatisfiedLinkError: Foo.JFooJNI.bar()I
> at Foo.JFooJNI.bar(Native Method)
> at Foo.JFoo.bar(JFoo.java:13)
> at .<init>(<console>:5)
> at .<clinit>(<console>)
>
> Just to be clear, it gets past the System.loadLibrary call. I can use
> `pmap` and verify that the shared library is loaded afterwards. It
> fails on the call to Foo.bar().
>
> I don't understand why it works the first way and not the second way.
>
Wed, 2009-03-04, 04:47
#3
Re: Re: UnsatisfiedLinkError in console, not command line
pmap is a tool which, given a pid, will print a list of all the shared
libraries linked into a process. I was able to use this to see my
library get loaded after loadLibrary().
I did try both java.library.path and LD_LIBRARY_PATH variations. These
both behaved the same way.
My problem is solved now with a static block in the JNI class. I found
a section in the SWIG docs that shows how to add custom code to the
JNI class it generates. IMO, they should've shown that in their
tutorial rather than suggest to loadLibrary() manually.
I was getting the same UnsatisfiedLinkError in a deployed tomcat app
when the .jar lived in tomcat's lib dir but the loadLibrary() happened
in my app. I had the same problem of the JNI class and the loadLibrary
happening in two different classloaders.
On Tue, Mar 3, 2009 at 3:09 PM, David Bernard
wrote:
> Where do you put and declare to the jvm the location of the native library ?
> try to call the interpreter with -Djava.library.path=Foo.so (or Foo.dll)
>
> /davidB
>
> On Tue, Mar 3, 2009 at 19:02, J Robert Ray wrote:
>>
>> I did some more digging and found the interpreter makes it own
>> classloader.
>>
>> http://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/compiler/scala...
>>
>> I believe in the interactive session, the SWIG generated jar has been
>> loaded by the parent classloader, and my System.loadLibrary call in
>> the interpreter runs in a child classloader. Therefore the two don't
>> see each other.
>>
>> I was able to make my jar work by adding a static {
>> System.loadLibrary(); } block to the SWIG-generated class(es). With
>> this in place I saw a "already loaded in another classloader" message
>> if I attempted to System.loadLibrary again in the console.
>>
>> On Mon, Mar 2, 2009 at 8:53 PM, J Robert Ray wrote:
>> > I'm fighting an UnsatisfiedLinkError trying to use some SWIG generated
>> > java bindings, and I'm seeing something very puzzling. I'm hoping
>> > someone here may recognize this problem.
>> >
>> > Given a SWIG generated library Foo and a static function bar that
>> > returns (int)1, I see these two behaviors:
>> > # works with -e
>> >> scala -cp Foo.jar -e 'System.loadLibrary("JFoo"); println(Foo.bar)'
>> > 1
>> >>
>> > # fails when typed interactively
>> >> scala -cp Foo.jar
>> > Welcome to Scala version 2.7.3.final (Java HotSpot(TM) 64-Bit Server
>> > VM, Java 1.6.0_07).
>> > Type in expressions to have them evaluated.
>> > Type :help for more information.
>> >
>> > scala> System.loadLibrary("JFoo"); println(Foo.bar)
>> > java.lang.UnsatisfiedLinkError: Foo.JFooJNI.bar()I
>> > at Foo.JFooJNI.bar(Native Method)
>> > at Foo.JFoo.bar(JFoo.java:13)
>> > at .(:5)
>> > at .()
>> >
>> > Just to be clear, it gets past the System.loadLibrary call. I can use
>> > `pmap` and verify that the shared library is loaded afterwards. It
>> > fails on the call to Foo.bar().
>> >
>> > I don't understand why it works the first way and not the second way.
>> >
>
>
I did some more digging and found the interpreter makes it own classloader.
http://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/compiler/scala...
I believe in the interactive session, the SWIG generated jar has been
loaded by the parent classloader, and my System.loadLibrary call in
the interpreter runs in a child classloader. Therefore the two don't
see each other.
I was able to make my jar work by adding a static {
System.loadLibrary(); } block to the SWIG-generated class(es). With
this in place I saw a "already loaded in another classloader" message
if I attempted to System.loadLibrary again in the console.
On Mon, Mar 2, 2009 at 8:53 PM, J Robert Ray wrote:
> I'm fighting an UnsatisfiedLinkError trying to use some SWIG generated
> java bindings, and I'm seeing something very puzzling. I'm hoping
> someone here may recognize this problem.
>
> Given a SWIG generated library Foo and a static function bar that
> returns (int)1, I see these two behaviors:
> # works with -e
>> scala -cp Foo.jar -e 'System.loadLibrary("JFoo"); println(Foo.bar)'
> 1
>>
> # fails when typed interactively
>> scala -cp Foo.jar
> Welcome to Scala version 2.7.3.final (Java HotSpot(TM) 64-Bit Server
> VM, Java 1.6.0_07).
> Type in expressions to have them evaluated.
> Type :help for more information.
>
> scala> System.loadLibrary("JFoo"); println(Foo.bar)
> java.lang.UnsatisfiedLinkError: Foo.JFooJNI.bar()I
> at Foo.JFooJNI.bar(Native Method)
> at Foo.JFoo.bar(JFoo.java:13)
> at .(:5)
> at .()
>
> Just to be clear, it gets past the System.loadLibrary call. I can use
> `pmap` and verify that the shared library is loaded afterwards. It
> fails on the call to Foo.bar().
>
> I don't understand why it works the first way and not the second way.
>