[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 363
  • Last Modified:

JNI Problem: Works under Windows, fails under Unix (Solaris 8)

I have a C++ program that functions as a wrapper around an existing C library of functions and implements the native method I call from the Java client. This works perfectly under Windows (compiled with Visual C++), but when I moved everything to the Unix platform (Solaris 8) along with the Unix version of the C library of functions, it fails as follows:

I get no errors from the compiler/linker, but when I run, I get one of two results:
--- If I explicitly reference the C library during the compile (with the -l flag), I can not load my own shared object in the Java client. I get "UnsatisfiedLinkError, no cmosubjni in java.library.path."
---If I do _not_ reference the C library during the build, my shared object loads just fine in the Java client, but the first call to a subroutine in the C library results in "relocation error, symbol not found ..."  I can, however, call standard C++ subroutines in the standard libraries, because I've inserted printf statements to see what's going on.

This is (from my makefile) the compile statement with the C library explicitly named:

CC -G -I. -I/fmac/dev/res/rmc/c09591/pmt/src/cdu_trustee/build/inc -I/java/include
 -I/java/include/solaris CMOSubJNI.cpp -o libcmosubjni.so -L/fmac/dev/res/rmc/
c09591/pmt/src/cdu_trustee/build/lib/ -lintexcmoln

CMOSubJNI is my wrapper class; the C library is named ilbintexcmoln.a  I have both an .so file and an .a file version of the C library; I believe these correspond to the .dll and .lib files under Windows, respectively, so I used the .a file under Unix as I used the .lib file under Windows. Just for the heck of it, I also tried the .so file, with the same results.

Again, this works under Windows, therefore the problem must lie with some switch or other that I am not using or using incorrectly during the compile/link.

Any help would be appreciated.  
1 Solution
it can be cmosubjni.so and must be in ur library path

so what u have is look for cmosubjni.so and add it to library.path
whandleyAuthor Commented:
Afraid not. Remember, if I remove the explicit reference to the C library during the compile/link (-lintexcmoln), loadLibrary does not fail. I don't change anything else, and loadLibrary works just fine. Therefore, there's nothing wrong with the library.path.

take a look at this neat sample


to run ur program u will do from ur shell command:

LD_LIBRARY_PATH =%LD_LIBRARY_PATH%:/pathToUrSoLibrary/cmosubjni.so

and then
java myJniProgram
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

What does

ar t libintexcmoln.a

give, out of interest?
whandleyAuthor Commented:
Thanks for the tips all, I've tried them all to no avail. Again, I don't think the problem is with LD_LIBRARY_PATH since it is able to find and load my shared object if I don't use the -lintexcmoln flag in the compile/link step. This leads me to believe there is something about this C library itself that is causing the problem. Somehow including that flag causes the linker to set some kind of reference to that object, and once it is set, loadLibrary then says it can't find _my_ object (in which the native methods are defined), when in fact the problem is that it can't find some object referenced by the library. Does that make sense?  
Anyone know of a way to debug this?  I've tried ldd -r "name", but that simply lists every C++ function I call as undefined, when in fact I can do a printf without a problem.

Re the question about the library itself, it is a set of routines provided by www.intex.com; has to do with analyzing financial data.    
whandleyAuthor Commented:
I solved this myself, thought the solution might be helpful to others.
It was correct to explicitly reference the library during the compile (with the -l flag); you have to do that to link the calls to the other library module. The root of the problem was that there was one unresolved symbol in the native method implementation I was trying to load.  Java unfortunately does not tell you this, it misleadingly and incorrectly tells you it can not _find_ the shared library you are trying to load.

Why did this happen on Unix but not on Windows? In the header file which I had to include in my native implmentation in order to reference the other shared library, there was a conditional inclusion of a reference to an obsolete method that users of that library formerly had to code in their module, because earlier editions of the library module did a callback to this method. The definition has to be there for backward compatibility. The Windows VCC+ compiler handled this conditional reference correctly and eliminated it, so there was no problem when I ran my code. But the Solaris C++ compiler could not handle the conditional nature of the defition, and went ahead and included that reference, resulting in an unresolved symbol when I compiled on Solaris.  The solution was to create an empty, dummy implementation of this obsolete method in my native implementation.    
PAQed with points refunded (500)

Community Support Moderator

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

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.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now