JNI Unsatisfied Link Error

I'm receiving an Unsatisfied Link Error on a JNI method called as follows:

package myPackage;
public class Class1 {
...
   public native method1();
...
   method1();
...
}

package myPackage;
public class Class2 {
...
   static {
      System.loadLibrary("myDLL");
   }
   public native method2();
...
   method2();
...
}

Both methods are defined in myDLL.dll. The method2() call works, the error occurs when method1() is executed.

What needs to be changed/added to make this work? I figured since the library is loaded up front by the static method, the contents would be available to all classes when they are loaded therafter. Obviously, not.
softechnicsAsked:
Who is Participating?
 
aozarovConnect With a Mentor Commented:
I don't think you need to provide System.loadLibrary for every class that uses native calls.
I am using a Main class that loads the library (that main class doesn't have any native calls) which
is being used by other classes.
Are you sure Class2 static initializer is called before you call Class1#method1?
To make sure it does you can add Class2.class.getName(); [or anything else that will trigger loading class2] before you call to Class1#method
0
 
CEHJCommented:
No, you'll have to load the library in Class1 too
0
 
InteractiveMindCommented:
To extend on CEHJ's comment, I would personally create a third class, like so:

   public class LibraryLoader
   {
      static
      {
         System.loadLibrary( "myDLL" );
      }
   }

Then, just extend this class, in your other classes, like so:

package myPackage;
public class Class1 extends LibraryLoader {
...
   public native method1();
...
   method1();
...
}

package myPackage;
public class Class2 extends LibraryLoader {
...
   public native method2();
...
   method2();
...
}


Likewise, if you wanted to (it's a bit circumstantial to your situation), you could declare the method implementations in the LibraryLoader class also:

     public native method1();
     ...


Hope that helps,
Rob.
0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
aozarovCommented:
softechnics,
Did you check if "Class2 static initializer is called before you call Class1#method1"?
0
 
objectsCommented:
InteractiveMind's suggestion would already ensure that.
0
 
aozarovCommented:
I suggested/added that there is no need to call System.loadLibrary( "myDLL" ); in each java file that uses JNI.
0
 
softechnicsAuthor Commented:
I like the above suggestions, except I cannot extend the DLL Loader class since my main class already extends applet. The static{} loader cannot exist in an interface, so how do I effect multiple extends w/o using interface?
0
 
aozarovCommented:
softechnics, I don't think you need to apply the loadLibrary in each class. Do you want code to prove you that?
BTW, if you are loading native code in an Applet did you sign it?
0
 
softechnicsAuthor Commented:
aozarov,
I'm currently working on your suggestion. Our app can be run as a client app or as an applet. If an applet, I don't need the JNI function that's giving me grief. So, my JNI call is only in the main() method. However, main() is static and it appears I cannot call the JNI method from within a static context - or so the compiler tells me.

If I declare LockDisplay static, I get an UnsatisfiedLinkEerror exception at runtime.
If I call the method as ta.LockDisplay, I still get an UnsatisfiedLinkEerror exception at runtime.

My main() method looks something like this:

public class MyClass
    extends Applet
    implements ComponentListener, Runnable, WindowListener
{
...
static {
<Load DLLs here>
}
public native void LockDisplay (String className, String title);
...
    public static void main( String[] args )
    {
        /* Create an instance of the application */
        MyClass ta = new MyClass( );
...
        LockDisplay("MyClass", title);
...
    }
...
}


0
 
aozarovCommented:
>>  cannot call the JNI method from within a static context - or so the compiler tells me.
You can, if that JNI methods are defined as static.

MyClass ta = new MyClass( );
ta.LockDisplay("MyClass", title);

should work fine if you applied all the procedures correctly (rm *.class, compile, run javah -jni, implment the generated header, compile the native code and created dynamic library which
can be loaded by the static initializer of MyClass
0
 
InteractiveMindCommented:
If on the other hand, you wanted to go with my suggestion, and extend a class, then you can extend the Applet class, within the ClassLoader, like so:

   public class LibraryLoader extends Applet
   {
      static
      {
         System.loadLibrary( "myDLL" );
      }
   }

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.