Question

I'm writing some JNI code in C++ to be called from an applet on Windows XP. I've been able to successfully run the applet and have the JNI library loaded and called, even going so far as having it call functions in other DLLs. I got this working by setting up the PATH system environment variable to include the directory all of my DLLs are in.

So, the problem, is that I add another call that uses a new external DLL, and suddenly when loading the library, an UnsatisfiedLinkError is thrown. The message is: 'The specified procedure could not be found'. This doesn't seem to be a problem with a missing dependent DLL, because I can remove a dependent DLL and get a different message about dependent DLL missing. From what I've been able to find online, it appears that this message means that a native Java function implementation is missing from the DLL, but it's odd that it works fine without this extra bit of code.

Does anyone know what might be causing this? What kinds of things can give a 'The specified procedure could not be found' messages for an UnsatisifedLinkError?

Was it helpful?

Solution

I figured out the problem. This was a doozy. The message "The specified procedure could not be found" for UnsatisfiedLinkError indicates that a function in the root dll or in a dependent dll could not be found. The most likely cause of this in a JNI situation is that the native JNI function is not exported correctly. But this can apparently happen if a dependent DLL is loaded and that DLL is missing a function required by its parent.

By way of example, we have a library named input.dll. The DLL search order is to always look in the application directory first and the PATH directories last. In the past, we always ran executables from the same directory as input.dll. However, there is another input.dll in the windows system directory (which is in the middle of the DLL search order). So when running this from a java applet, if I include the code described above in the applet, which causes input.dll to be loaded, it loads the input.dll from the system directory. Because our code is expecting certain functions in input.dll which aren't there (because it's a different DLL) the load fails with an error message about missing procedures. Not because the JNI functions are exported wrong, but because the wrong dependent DLL was loaded and it didn't have the expected functions in it.

OTHER TIPS

There is a chance that the DLL was built using C++(as opposed to C). unless you took care to do an extern on the procedure,this is one possible reason.

Try exporting all the functions from the DLL. If the list includes your function, then you're good.

Usually, when linking to other libraries, you need to link to the relevant .lib file. It sounds like you aren't referencing all the lib files you need. Check what isn't linking and make sure you add it's lib to the list for the linker.

Did you create the new external DLL using the standard JNI procedure? I.e., using javah and so forth? If so, then I am not sure what is wrong.

If not, then the procedure you're trying to call hasn't been exported (as mentioned by anjanb). I am aware of two way of exporting functions: a separate export list and marking specific functions with __declspec(dllexport).

Can't access variable in C++ DLL from a C app has a little more information the topic of DLLs.

Compile your c++ code in debug mode. Then insert the DebugBreak(); statement where you would like to start debugging. Run the java code. When the DebugBreak() statement is encountered you will get a popup with a Debug button on it. Click on it. Dev Studio will open with your program in machine code. Step over with the debugger twice and you should be able to step over your source code.

If you have done all programming issue at JNI manuals and examples but still you are getting same missing procedure error, problem can be at your path variable probably. Do below steps and run again:

  1. Be sure about you set JAVA_HOME variable to your JDK folder(not JRE because JRE doesnt contain jni header) Example: At environment variable settings panel define var:JAVA_HOME val:C:\Program Files\Java\jdk1.7.0_11
  2. add %JAVA_HOME%\bin to your path variable

After doing those steps, your application can find jni procedure name and links to JNI.dll in right way. So, i hope you dont get this missing procedure error again.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top