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

Posted on 2004-11-05
Last Modified: 2013-12-05
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 -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.  
Question by:whandley
    LVL 13

    Expert Comment

    it can be and must be in ur library path

    so what u have is look for and add it to library.path

    Author Comment

    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.

    LVL 13

    Expert Comment

    take a look at this neat sample

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

    export LD_LIBRARY_PATH

    and then
    java myJniProgram
    LVL 86

    Expert Comment

    What does

    ar t libintexcmoln.a

    give, out of interest?

    Author Comment

    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; has to do with analyzing financial data.    

    Author Comment

    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.    

    Accepted Solution

    PAQed with points refunded (500)

    Community Support Moderator

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How to improve team productivity

    Quip adds documents, spreadsheets, and tasklists to your Slack experience
    - Elevate ideas to Quip docs
    - Share Quip docs in Slack
    - Get notified of changes to your docs
    - Available on iOS/Android/Desktop/Web
    - Online/Offline

    Suggested Solutions

    Title # Comments Views Activity
    NTP Server in VMware 5 90
    sumHeights  challenge 17 50
    return in catch statement 1 32
    Sed question 2 25
    Attention: This article will no longer be maintained. If you have any questions, please feel free to mail me. Please see for the updated article. It is avail…
    Introduction Regular patching is part of a system administrator's tasks. However, many patches require that the system be in single-user mode before they can be installed. A cluster patch in particular can take quite a while to apply if the machine…
    Viewers will learn about arithmetic and Boolean expressions in Java and the logical operators used to create Boolean expressions. We will cover the symbols used for arithmetic expressions and define each logical operator and how to use them in Boole…
    This tutorial goes over how to archive and restore FreeBSD jails that are managed by ezjail.

    761 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    14 Experts available now in Live!

    Get 1:1 Help Now