Skip to main content

[JNI] Unsatisfied Link Error

1 reply [Last post]
talwyn
Offline
Joined: 2005-08-19

Hello everybody,

I'm trying to wrap a native C library in Java so I can use the methods exposed by the dll files from my programs. The following class contains my native methods:

<br />
package com.byteholder.camlib.canon.eos;</p>
<p>public class JEOS {</p>
<p>   public static native int EdsInitializeSDK();</p>
<p>   public static native int EdsTerminateSDK();</p>
<p>   // ...</p>
<p>}

The generated by javah contains the following code:

/* DO NOT EDIT THIS FILE - it is machine generated */<br />
#include<br />
/* Header for class com_byteholder_camlib_canon_eos_JEOS */</p>
<p>#ifndef _Included_com_byteholder_camlib_canon_eos_JEOS<br />
#define _Included_com_byteholder_camlib_canon_eos_JEOS<br />
#ifdef __cplusplus<br />
extern "C" {<br />
#endif<br />
/*<br />
 * Class:     com_byteholder_camlib_canon_eos_JEOS<br />
 * Method:    EdsInizializeSDK<br />
 * Signature: ()I<br />
 */<br />
JNIEXPORT jint JNICALL Java_com_byteholder_camlib_canon_eos_JEOS_EdsInizializeSDK<br />
  (JNIEnv *, jclass);</p>
<p>/*<br />
 * Class:     com_byteholder_camlib_canon_eos_JEOS<br />
 * Method:    EdsTerminateSDK<br />
 * Signature: ()I<br />
 */<br />
JNIEXPORT jint JNICALL Java_com_byteholder_camlib_canon_eos_JEOS_EdsTerminateSDK<br />
  (JNIEnv *, jclass);</p>
<p>#ifdef __cplusplus<br />
}<br />
#endif<br />
#endif

I've then written a C-File that implements those methods:

#include "EDSDK.h"<br />
#include "jeos.h"</p>
<p>#ifdef __cplusplus<br />
extern "C" {<br />
#endif</p>
<p>JNIEXPORT jint JNICALLJava_com_byteholder_camlib_canon_eos_JEOS_EdsInizializeSDK<br />
(JNIEnv *env, class cl) {<br />
	// EdsError err = EDS_ERR_OK;<br />
	// err = EdsInitializeSDK();<br />
	return (jint) 0;<br />
}</p>
<p>JNIEXPORT jint JNICALLJava_com_byteholder_camlib_canon_eos_JEOS_EdsTerminateSDK<br />
(JNIEnv *env, jclass cl) {<br />
	// EdsError err = EDS_ERR_OK;<br />
	// err = EdsTerminateSDK();<br />
	return (jint) 0;<br />
}</p>
<p>#ifdef __cplusplus<br />
}<br />
#endif

I then compile the C-File using MinGW's gcc port and get a dll file that looks fine when inspected in dependency walker.

Then, I have a JUnit test case that loads my dll as well as those provided by the native library in question using System.load("");

When I run that test case, I get an UnsatisfiedLinkError in the line where I try to invoke the first native method:

java.lang.UnsatisfiedLinkError: com.byteholder.camlib.canon.eos.JEOS.EdsInizializeSDK()I<br />
	at com.byteholder.camlib.canon.eos.JEOS.EdsInizializeSDK(Native Method)<br />
	at com.byteholder.camlib.canon.eos.test.JEOSTest.testJEOS(JEOSTest.java:32)<br />
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)<br />
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)<br />
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)<br />
	at java.lang.reflect.Method.invoke(Method.java:597)<br />
	at junit.framework.TestCase.runTest(TestCase.java:164)<br />
	at junit.framework.TestCase.runBare(TestCase.java:130)<br />
	at junit.framework.TestResult$1.protect(TestResult.java:106)<br />
	at junit.framework.TestResult.runProtected(TestResult.java:124)<br />
	at junit.framework.TestResult.run(TestResult.java:109)<br />
	at junit.framework.TestCase.run(TestCase.java:120)<br />
	at junit.framework.TestSuite.runTest(TestSuite.java:230)<br />
	at junit.framework.TestSuite.run(TestSuite.java:225)<br />
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)<br />
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)<br />
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)[Dynamic-linking native method java.net.PlainSocketImpl.socketClose0 ... JNI]</p>
<p>	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)<br />
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)<br />
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

Passing -verbose:jni produces the following output:

[Dynamic-linking native method java.lang.Object.registerNatives ... JNI]<br />
[Registering JNI native method java.lang.Object.hashCode]<br />
[Registering JNI native method java.lang.Object.wait]<br />
[Registering JNI native method java.lang.Object.notify]<br />
[Registering JNI native method java.lang.Object.notifyAll]<br />
[Registering JNI native method java.lang.Object.clone]<br />
[Dynamic-linking native method java.lang.System.registerNatives ... JNI]<br />
[Registering JNI native method java.lang.System.currentTimeMillis]<br />
[Registering JNI native method java.lang.System.nanoTime]<br />
[Registering JNI native method java.lang.System.arraycopy]<br />
[Dynamic-linking native method java.lang.Thread.registerNatives ... JNI]<br />
[Registering JNI native method java.lang.Thread.start0]<br />
[Registering JNI native method java.lang.Thread.stop0]<br />
[Registering JNI native method java.lang.Thread.isAlive]<br />
[Registering JNI native method java.lang.Thread.suspend0]<br />
[Registering JNI native method java.lang.Thread.resume0]<br />
[Registering JNI native method java.lang.Thread.setPriority0]<br />
[Registering JNI native method java.lang.Thread.yield]<br />
[Registering JNI native method java.lang.Thread.sleep]<br />
[Registering JNI native method java.lang.Thread.currentThread]<br />
[Registering JNI native method java.lang.Thread.countStackFrames]<br />
[Registering JNI native method java.lang.Thread.interrupt0]<br />
[Registering JNI native method java.lang.Thread.isInterrupted]<br />
[Registering JNI native method java.lang.Thread.holdsLock]<br />
[Registering JNI native method java.lang.Thread.getThreads]<br />
[Registering JNI native method java.lang.Thread.dumpThreads]<br />
[Dynamic-linking native method java.lang.Class.registerNatives ... JNI]<br />
[Registering JNI native method java.lang.Class.getName0]<br />
[Registering JNI native method java.lang.Class.getSuperclass]<br />
[Registering JNI native method java.lang.Class.getInterfaces]<br />
[Registering JNI native method java.lang.Class.getClassLoader0]<br />
[Registering JNI native method java.lang.Class.isInterface]<br />
[Registering JNI native method java.lang.Class.getSigners]<br />
[Registering JNI native method java.lang.Class.setSigners]<br />
[Registering JNI native method java.lang.Class.isArray]<br />
[Registering JNI native method java.lang.Class.isPrimitive]<br />
[Registering JNI native method java.lang.Class.getComponentType]<br />
[Registering JNI native method java.lang.Class.getModifiers]<br />
[Registering JNI native method java.lang.Class.getDeclaredFields0]<br />
[Registering JNI native method java.lang.Class.getDeclaredMethods0]<br />
[Registering JNI native method java.lang.Class.getDeclaredConstructors0]<br />
[Registering JNI native method java.lang.Class.getProtectionDomain0]<br />
[Registering JNI native method java.lang.Class.setProtectionDomain0]<br />
[Registering JNI native method java.lang.Class.getDeclaredClasses0]<br />
[Registering JNI native method java.lang.Class.getDeclaringClass]<br />
[Registering JNI native method java.lang.Class.getGenericSignature]<br />
[Registering JNI native method java.lang.Class.getRawAnnotations]<br />
[Registering JNI native method java.lang.Class.getConstantPool]<br />
[Registering JNI native method java.lang.Class.desiredAssertionStatus0]<br />
[Registering JNI native method java.lang.Class.getEnclosingMethod0]<br />
[Dynamic-linking native method java.lang.Class.getPrimitiveClass ... JNI]<br />
[Dynamic-linking native method java.security.AccessController.getStackAccessControlContext ... JNI]<br />
[Dynamic-linking native method java.security.AccessController.getInheritedAccessControlContext ... JNI]<br />
[Dynamic-linking native method java.lang.ClassLoader.registerNatives ... JNI]<br />
[Registering JNI native method java.lang.ClassLoader.retrieveDirectives]<br />
[Dynamic-linking native method java.security.AccessController.doPrivileged ... JNI]<br />
[Dynamic-linking native method java.lang.System.initProperties ... JNI]<br />
[Dynamic-linking native method java.io.FileInputStream.initIDs ... JNI]<br />
[Dynamic-linking native method java.io.FileDescriptor.initIDs ... JNI]<br />
[Dynamic-linking native method java.io.FileDescriptor.set ... JNI]<br />
[Dynamic-linking native method java.io.FileOutputStream.initIDs ... JNI]<br />
[Dynamic-linking native method sun.misc.Unsafe.registerNatives ... JNI]<br />
[Registering JNI native method sun.misc.Unsafe.getLoadAverage]<br />
[Dynamic-linking native method java.lang.Throwable.fillInStackTrace ... JNI]<br />
[Registering JNI native method sun.misc.Unsafe.setMemory]<br />
[Registering JNI native method sun.misc.Unsafe.copyMemory]<br />
[Registering JNI native method sun.misc.Unsafe.getObject]<br />
[Registering JNI native method sun.misc.Unsafe.putObject]<br />
[Registering JNI native method sun.misc.Unsafe.getObjectVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putObjectVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getBoolean]<br />
[Registering JNI native method sun.misc.Unsafe.putBoolean]<br />
[Registering JNI native method sun.misc.Unsafe.getBooleanVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putBooleanVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getByte]<br />
[Registering JNI native method sun.misc.Unsafe.putByte]<br />
[Registering JNI native method sun.misc.Unsafe.getByteVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putByteVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getShort]<br />
[Registering JNI native method sun.misc.Unsafe.putShort]<br />
[Registering JNI native method sun.misc.Unsafe.getShortVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putShortVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getChar]<br />
[Registering JNI native method sun.misc.Unsafe.putChar]<br />
[Registering JNI native method sun.misc.Unsafe.getCharVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putCharVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getInt]<br />
[Registering JNI native method sun.misc.Unsafe.putInt]<br />
[Registering JNI native method sun.misc.Unsafe.getIntVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putIntVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getLong]<br />
[Registering JNI native method sun.misc.Unsafe.putLong]<br />
[Registering JNI native method sun.misc.Unsafe.getLongVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putLongVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getFloat]<br />
[Registering JNI native method sun.misc.Unsafe.putFloat]<br />
[Registering JNI native method sun.misc.Unsafe.getFloatVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putFloatVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getDouble]<br />
[Registering JNI native method sun.misc.Unsafe.putDouble]<br />
[Registering JNI native method sun.misc.Unsafe.getDoubleVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.putDoubleVolatile]<br />
[Registering JNI native method sun.misc.Unsafe.getByte]<br />
[Registering JNI native method sun.misc.Unsafe.putByte]<br />
[Registering JNI native method sun.misc.Unsafe.getShort]<br />
[Registering JNI native method sun.misc.Unsafe.putShort]<br />
[Registering JNI native method sun.misc.Unsafe.getChar]<br />
[Registering JNI native method sun.misc.Unsafe.putChar]<br />
[Registering JNI native method sun.misc.Unsafe.getInt]<br />
[Registering JNI native method sun.misc.Unsafe.putInt]<br />
[Registering JNI native method sun.misc.Unsafe.getLong]<br />
[Registering JNI native method sun.misc.Unsafe.putLong]<br />
[Registering JNI native method sun.misc.Unsafe.getFloat]<br />
[Registering JNI native method sun.misc.Unsafe.putFloat]<br />
[Registering JNI native method sun.misc.Unsafe.getDouble]<br />
[Registering JNI native method sun.misc.Unsafe.putDouble]<br />
[Registering JNI native method sun.misc.Unsafe.getAddress]<br />
[Registering JNI native method sun.misc.Unsafe.putAddress]<br />
[Registering JNI native method sun.misc.Unsafe.allocateMemory]<br />
[Registering JNI native method sun.misc.Unsafe.reallocateMemory]<br />
[Registering JNI native method sun.misc.Unsafe.freeMemory]<br />
[Registering JNI native method sun.misc.Unsafe.objectFieldOffset]<br />
[Registering JNI native method sun.misc.Unsafe.staticFieldOffset]<br />
[Registering JNI native method sun.misc.Unsafe.staticFieldBase]<br />
[Registering JNI native method sun.misc.Unsafe.ensureClassInitialized]<br />
[Registering JNI native method sun.misc.Unsafe.arrayBaseOffset]<br />
[Registering JNI native method sun.misc.Unsafe.arrayIndexScale]<br />
[Registering JNI native method sun.misc.Unsafe.addressSize]<br />
[Registering JNI native method sun.misc.Unsafe.pageSize]<br />
[Registering JNI native method sun.misc.Unsafe.defineClass]<br />
[Registering JNI native method sun.misc.Unsafe.defineClass]<br />
[Registering JNI native method sun.misc.Unsafe.allocateInstance]<br />
[Registering JNI native method sun.misc.Unsafe.monitorEnter]<br />
[Registering JNI native method sun.misc.Unsafe.monitorExit]<br />
[Registering JNI native method sun.misc.Unsafe.tryMonitorEnter]<br />
[Registering JNI native method sun.misc.Unsafe.throwException]<br />
[Registering JNI native method sun.misc.Unsafe.compareAndSwapObject]<br />
[Registering JNI native method sun.misc.Unsafe.compareAndSwapInt]<br />
[Registering JNI native method sun.misc.Unsafe.compareAndSwapLong]<br />
[Registering JNI native method sun.misc.Unsafe.putOrderedObject]<br />
[Registering JNI native method sun.misc.Unsafe.putOrderedInt]<br />
[Registering JNI native method sun.misc.Unsafe.putOrderedLong]<br />
[Registering JNI native method sun.misc.Unsafe.park]<br />
[Registering JNI native method sun.misc.Unsafe.unpark]<br />
[Dynamic-linking native method sun.reflect.Reflection.getCallerClass ... JNI]<br />
[Dynamic-linking native method java.lang.String.intern ... JNI]<br />
[Dynamic-linking native method java.lang.System.setIn0 ... JNI]<br />
[Dynamic-linking native method java.lang.Float.floatToRawIntBits ... JNI]<br />
[Dynamic-linking native method java.lang.Double.doubleToRawLongBits ... JNI]<br />
[Dynamic-linking native method java.lang.Object.getClass ... JNI]<br />
[Dynamic-linking native method java.lang.Class.forName0 ... JNI]<br />
[Dynamic-linking native method sun.reflect.Reflection.getClassAccessFlags ... JNI]<br />
[Dynamic-linking native method sun.reflect.NativeConstructorAccessorImpl.newInstance0 ... JNI]<br />
[Dynamic-linking native method sun.misc.VM.initialize ... JNI]<br />
[Dynamic-linking native method java.lang.Runtime.maxMemory ... JNI]<br />
[Dynamic-linking native method java.lang.System.setOut0 ... JNI]<br />
[Dynamic-linking native method java.lang.System.setErr0 ... JNI]<br />
[Dynamic-linking native method java.io.FileSystem.getFileSystem ... JNI]<br />
[Dynamic-linking native method java.io.Win32FileSystem.initIDs ... JNI]<br />
[Dynamic-linking native method java.io.WinNTFileSystem.initIDs ... JNI]<br />
[Dynamic-linking native method java.lang.System.mapLibraryName ... JNI]<br />
[Dynamic-linking native method java.io.WinNTFileSystem.getBooleanAttributes ... JNI]<br />
[Dynamic-linking native method java.io.WinNTFileSystem.canonicalize0 ... JNI]<br />
[Dynamic-linking native method java.lang.ClassLoader$NativeLibrary.load ... JNI]<br />
[Dynamic-linking native method sun.misc.Signal.findSignal ... JNI]<br />
[Dynamic-linking native method sun.misc.Signal.handle0 ... JNI]<br />
[Dynamic-linking native method sun.io.Win32ErrorMode.setErrorMode ... JNI]<br />
[Dynamic-linking native method java.lang.Compiler.registerNatives ... JNI]<br />
[Registering JNI native method java.lang.Compiler.compileClass]<br />
[Registering JNI native method java.lang.Compiler.compileClasses]<br />
[Registering JNI native method java.lang.Compiler.command]<br />
[Registering JNI native method java.lang.Compiler.enable]<br />
[Registering JNI native method java.lang.Compiler.disable]<br />
[Dynamic-linking native method java.lang.ClassLoader$NativeLibrary.find ... JNI]<br />
[Dynamic-linking native method java.security.AccessController.doPrivileged ... JNI]<br />
[Dynamic-linking native method java.io.FileInputStream.open ... JNI]<br />
[Dynamic-linking native method java.io.FileInputStream.readBytes ... JNI]<br />
[Dynamic-linking native method java.io.FileInputStream.available ... JNI]<br />
[Dynamic-linking native method java.lang.reflect.Array.newArray ... JNI]<br />
[Dynamic-linking native method java.io.ObjectStreamClass.initNative ... JNI]<br />
[Dynamic-linking native method java.io.FileInputStream.close0 ... JNI]<br />
[Dynamic-linking native method java.io.WinNTFileSystem.list ... JNI]<br />
[Dynamic-linking native method java.io.WinNTFileSystem.canonicalizeWithPrefix0 ... JNI]<br />
[Dynamic-linking native method java.lang.ClassLoader.findLoadedClass0 ... JNI]<br />
[Dynamic-linking native method java.lang.ClassLoader.findBootstrapClass ... JNI]<br />
[Dynamic-linking native method java.security.AccessController.doPrivileged ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.initIDs ... JNI]<br />
[Dynamic-linking native method java.io.WinNTFileSystem.getLastModifiedTime ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.open ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.getTotal ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.getEntry ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipEntry.initIDs ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipEntry.initFields ... JNI]</p>
<p>[Dynamic-linking native method java.util.zip.ZipFile.freeEntry ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.getCSize ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.getSize ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.getMethod ... JNI]<br />
[Dynamic-linking native method java.util.zip.Inflater.initIDs ... JNI]<br />
[Dynamic-linking native method java.util.zip.Inflater.init ... JNI]<br />
[Dynamic-linking native method java.util.zip.Inflater.inflateBytes ... JNI]<br />
[Dynamic-linking native method java.util.zip.ZipFile.read ... JNI]<br />
[Dynamic-linking native method java.lang.Package.getSystemPackage0 ... JNI]<br />
[Dynamic-linking native method java.io.WinNTFileSystem.getLength ... JNI]<br />
[Dynamic-linking native method java.lang.ClassLoader.defineClass1 ... JNI]<br />
[Dynamic-linking native method java.util.zip.Inflater.reset ... JNI]<br />
[Dynamic-linking native method java.util.jar.JarFile.getMetaInfEntryNames ... JNI]<br />
[Dynamic-linking native method java.lang.Double.longBitsToDouble ... JNI]<br />
[Dynamic-linking native method java.lang.StrictMath.floor ... JNI]<br />
[Dynamic-linking native method java.lang.Class.isAssignableFrom ... JNI]<br />
[Dynamic-linking native method java.lang.ref.Finalizer.invokeFinalizeMethod ... JNI]<br />
[Dynamic-linking native method java.net.InetAddress.init ... JNI]<br />
[Dynamic-linking native method java.net.InetAddressImplFactory.isIPv6Supported ... JNI]<br />
[Dynamic-linking native method java.net.Inet4Address.init ... JNI]<br />
[Dynamic-linking native method java.net.PlainSocketImpl.initProto ... JNI]<br />
[Dynamic-linking native method java.net.PlainSocketImpl.socketCreate ... JNI]<br />
[Dynamic-linking native method java.net.PlainSocketImpl.socketConnect ... JNI]<br />
[Dynamic-linking native method java.net.SocketOutputStream.init ... JNI]<br />
[Dynamic-linking native method java.net.SocketInputStream.init ... JNI]<br />
[Dynamic-linking native method java.net.SocketInputStream.socketRead0 ... JNI]<br />
[Dynamic-linking native method java.net.SocketOutputStream.socketWrite0 ... JNI]<br />
[Dynamic-linking native method sun.reflect.NativeMethodAccessorImpl.invoke0 ... JNI]<br />
[Dynamic-linking native method java.io.FileOutputStream.writeBytes ... JNI]<br />
[Dynamic-linking native method java.lang.Throwable.getStackTraceDepth ... JNI]<br />
[Dynamic-linking native method java.lang.Throwable.getStackTraceElement ... JNI]<br />
[Dynamic-linking native method java.lang.Shutdown.halt0 ... JNI]

I'm rather confused because the JNI verbose output contains no hints that my library or the wrapped library are loaded, although I do use correct absolute paths.

Any help in this would be greatly appreciated.

Thanks in advance,
Stephan

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
gluk
Offline
Joined: 2009-04-20

Your error might have already a solution at this site: http://iderror.com/category/errors/java/