Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

JNI Programming

18 views
Skip to first unread message

Bala

unread,
Nov 6, 2007, 12:29:56 PM11/6/07
to
Hello,

I am programming using JNI to call a method from a c static library.
I created the shared library for this purpose and the necessary
compilations.

Now, when i try to run my application Main.java, it gives me the
following runtime error

Exception in thread "main" java.lang.UnsatisfiedLinkError: /home1/
users/biyer/Bala/OAPI/src/libOpenApiImp.so:
Can't load Sparc 32-bit .so on a Sparc 32-bit platform
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1751)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1676)
at java.lang.Runtime.loadLibrary0(Runtime.java:822)
at java.lang.System.loadLibrary(System.java:993)
at OpenApi.<clinit>(OpenApi.java:7)
at Main.main(Main.java:5)

I am using the following version of JAVA on Solaris 10 Sparc

java version "1.5.0_12"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_12-b04)
Java HotSpot(TM) Server VM (build 1.5.0_12-b04, mixed mode)

Please let me know whats going wrong?

Gordon Beaton

unread,
Nov 6, 2007, 12:33:30 PM11/6/07
to
On Tue, 06 Nov 2007 09:29:56 -0800, Bala wrote:
> Exception in thread "main" java.lang.UnsatisfiedLinkError: /home1/
> users/biyer/Bala/OAPI/src/libOpenApiImp.so:
> Can't load Sparc 32-bit .so on a Sparc 32-bit platform

Well that is an odd message...

What commands did you use to build the .so file?

What do "file libOpenApiImp.so" and "ldd libOpenApiImp.so" say?

/gordon

--

Bala

unread,
Nov 6, 2007, 1:20:32 PM11/6/07
to

Hello,

I built the .so using the following command
g++ -Wno-deprecated -G -I/usr/java/include -I/usr/java/include/solaris
-I/home1/users/biyer/Bala/OAPI/include JavaC.C -o libOpenApiImp.so

This is what ldd says
ldd libOpenApiImp.so
libstdc++.so.6 => /usr/sfw/lib/libstdc++.so.6
libm.so.2 => /lib/libm.so.2
libgcc_s.so.1 => /usr/sfw/lib/libgcc_s.so.1
libc.so.1 => /lib/libc.so.1
/platform/SUNW,Sun-Fire-480R/lib/libc_psr.so.1

Lothar Kimmeringer

unread,
Nov 6, 2007, 1:24:17 PM11/6/07
to
Bala wrote:

> Can't load Sparc 32-bit .so on a Sparc 32-bit platform

Google[0] points to
http://forum.java.sun.com/thread.jspa?threadID=792436&messageID=9469362
Seems to be a cryptic message that has been introduced with
a specific version of Java 1.5

You can go back to an older version to get meaningful
messages or simply check the library for dependencies
with other shared libraries that are not solved on
that particular system.


Regards, Lothar

[0] http://www.google.de/search?hl=de&q=Can%27t+load+Sparc+32-bit+.so+on+a+Sparc+32-bit+platform&btnG=Google-Suche&meta=
--
Lothar Kimmeringer E-Mail: spam...@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!

Bala

unread,
Nov 6, 2007, 1:38:07 PM11/6/07
to
On Nov 6, 1:24 pm, Lothar Kimmeringer <news200...@kimmeringer.de>
wrote:

> Bala wrote:
> > Can't load Sparc 32-bit .so on a Sparc 32-bit platform
>
> Google[0] points tohttp://forum.java.sun.com/thread.jspa?threadID=792436&messageID=9469362

> Seems to be a cryptic message that has been introduced with
> a specific version of Java 1.5
>
> You can go back to an older version to get meaningful
> messages or simply check the library for dependencies
> with other shared libraries that are not solved on
> that particular system.
>
> Regards, Lothar
>
> [0]http://www.google.de/search?hl=de&q=Can%27t+load+Sparc+32-bit+.so+on+...
> --
> Lothar Kimmeringer E-Mail: spamf...@kimmeringer.de

> PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)
>
> Always remember: The answer is forty-two, there can only be wrong
> questions!

Hello,

I shifted to an older version and it says that there are symbols
referred by my native function that are not found. My native method
first initializes another dynamic library using the dlopen call and
then calls a method of that dynamic library. This dynamic library in
turn refers to a couple of static libraries as well.

Exception in thread "main" java.lang.UnsatisfiedLinkError: /home1/

users/biyer/Bala/OAPI/src/libOpenApiImp.so: ld.so.1: java: fatal:
relocation error: file /home1/users/biyer/Bala/OAPI/src/
libOpenApiImp.so: symbol _Z9OAPI_mainv: referenced symbol not found
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1586)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1511)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)


at OpenApi.<clinit>(OpenApi.java:7)
at Main.main(Main.java:5)

Do i need to link the static libraries as well with my Java
Application? If yes, how do i do it?

Thanx for the earlier help, it gave me an idea what was going wrong
atleast

Lothar Kimmeringer

unread,
Nov 6, 2007, 1:50:36 PM11/6/07
to
Bala wrote:

> Do i need to link the static libraries as well with my Java
> Application? If yes, how do i do it?

From your other answer:

| I built the .so using the following command
| g++ -Wno-deprecated -G -I/usr/java/include -I/usr/java/include/solaris
| -I/home1/users/biyer/Bala/OAPI/include JavaC.C -o libOpenApiImp.so

I don't know Solaris very much but when I compile under Linux
it's necessary to compile it with -fPIC (and I always compile
with -Wall, but that should be only a question of style here ;-)


Regards, Lothar


--
Lothar Kimmeringer E-Mail: spam...@kimmeringer.de

Gordon Beaton

unread,
Nov 6, 2007, 1:52:15 PM11/6/07
to
On Tue, 06 Nov 2007 18:20:32 -0000, Bala wrote:
> I built the .so using the following command
> g++ -Wno-deprecated -G -I/usr/java/include
> -I/usr/java/include/solaris -I/home1/users/biyer/Bala/OAPI/include
> JavaC.C -o libOpenApiImp.so

If you'd run "file libOpenApiImp.so" I think it would tell you you've
created a regular executable file, not a shared object. Note that -G
is an option for Sun's own compiler, not g++. It doesn't do what you
expect here.

To do this with gcc (or g++) you need to do something like this:

compile only:
g++ -fpic -D_REENTRANT
-I /usr/java/include
-I /usr/java/include/solaris
-I /home1/users/biyer/Bala/OAPI/include
-c JavaC.C

link:
g++ -shared JavaC.o -o libOpenApiImp.so

or compile and link in one step:
g++ -fpic -shared -D_REENTRANT
-I /usr/java/include
-I /usr/java/include/solaris
-I /home1/users/biyer/Bala/OAPI/include
JavaC.C -o libOpenApiImp.so

/gordon

--

Bala

unread,
Nov 6, 2007, 1:54:49 PM11/6/07
to
On Nov 6, 1:50 pm, Lothar Kimmeringer <news200...@kimmeringer.de>
wrote:

> Bala wrote:
> > Do i need to link the static libraries as well with my Java
> > Application? If yes, how do i do it?
>
> From your other answer:
>
> | I built the .so using the following command
> | g++ -Wno-deprecated -G -I/usr/java/include -I/usr/java/include/solaris
> | -I/home1/users/biyer/Bala/OAPI/include JavaC.C -o libOpenApiImp.so
>
> I don't know Solaris very much but when I compile under Linux
> it's necessary to compile it with -fPIC (and I always compile
> with -Wall, but that should be only a question of style here ;-)
>
> Regards, Lothar
> --
> Lothar Kimmeringer E-Mail: spamf...@kimmeringer.de

> PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)
>
> Always remember: The answer is forty-two, there can only be wrong
> questions!

But my issue is that libOpenApiImp.so calls functions from 3 more
static libraries, liba.a, libb.a and libc.a. Do these libraries need
to be linked to Java application, because the only executing program
here is the JAVA application. The error says that OAPI_Main refers to
undefined symbols, which means its not able to find the methods that
are in the static libraries..

Any comments on this?

Gordon Beaton

unread,
Nov 6, 2007, 1:58:03 PM11/6/07
to
On Tue, 06 Nov 2007 18:54:49 -0000, Bala wrote:
> But my issue is that libOpenApiImp.so calls functions from 3 more
> static libraries, liba.a, libb.a and libc.a. Do these libraries need
> to be linked to Java application, because the only executing program
> here is the JAVA application.

When you link your shared object (see my other reply), you need to
mention each of the dependent libraries with link options like this:

-L /path/to/your/libs -la -lb -lc

/gordon

--

Bala

unread,
Nov 6, 2007, 3:28:31 PM11/6/07
to

Hi Gordon,

I used the command that you had pasted. The dynamic libraries got
created but this time, even with an older version, i am getting just
this message.
Sorry to bother you much, but im just 2 months old in JAVA, so not
sure which way to look at.. I have loads of other doubts and queries
with respect to JNI. Once this issue gets solved, im gonna bang some
more :)

Exception in thread "main" java.lang.UnsatisfiedLinkError: OAPIInit
at OpenApi.OAPIInit(Native Method)
at Main.main(Main.java:6)

java version "1.4.2_13"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_13-b06)
Java HotSpot(TM) Client VM (build 1.4.2_13-b06, mixed mode)

Bala

unread,
Nov 6, 2007, 3:33:39 PM11/6/07
to


Sorry, this problem seems to be solved. I had the wrong name mangling
conversion in the JavaC.C file, which was causing the problem. Now my
code executes, but dlopen failed due to some reason, will check that.
The other dynamic library libSubscribe.so could not be loaded when i
used dlopen to call it.

Gordon Beaton

unread,
Nov 6, 2007, 3:32:28 PM11/6/07
to
On Tue, 06 Nov 2007 20:28:31 -0000, Bala wrote:
> Exception in thread "main" java.lang.UnsatisfiedLinkError: OAPIInit
> at OpenApi.OAPIInit(Native Method)
> at Main.main(Main.java:6)

You are making some progress; Unlike the previous errors, this one
doesn't occur at System.loadLibrary(), it occurs when you try to
invoke a native method.

This error says that the native method OAPIInit() doesn't exist in the
library. You might disagree with that, but the JVM has a very specific
idea of what the method needs to be called in order to find it.

javah should have produced a header file with the correct declaration.
You should have included that header file in your source code, and
used exactly those method declarations. Perhaps it's time for you to
post your code.

/gordon

--

Roedy Green

unread,
Nov 6, 2007, 4:06:48 PM11/6/07
to
On Tue, 06 Nov 2007 09:29:56 -0800, Bala <R.Bala...@gmail.com>
wrote, quoted or indirectly quoted someone who said :

>UnsatisfiedLinkError

see
http://mindprod.com/jgloss/runerrormessages.html#UNSATISFIEDLINKERROR
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Gordon Beaton

unread,
Nov 7, 2007, 5:14:14 AM11/7/07
to
On Tue, 06 Nov 2007 20:33:39 -0000, Bala wrote:
> Sorry, this problem seems to be solved. I had the wrong name
> mangling conversion in the JavaC.C file, which was causing the
> problem.

This often indicates that you didn't exactly obey the method
signatures generated by javah, since javah already declares the
generated methods 'extern "C"' in the header file. For example if you
changed any of the argument datatypes the declaration no longer has
any effect.

> Now my code executes, but dlopen failed due to some reason, will
> check that. The other dynamic library libSubscribe.so could not be
> loaded when i used dlopen to call it.

If libSubscribe.so has further dependencies (check with ldd) then the
dynamic linker needs to be able to find them at runtime or
libSubscribe.so itself will fail to load. Note that this depends on
the flags you pass to dlopen(), in particular RTLD_LAZY or RTLD_NOW.

The dependent libraries, unlike libSubscribe.so, must either be in
default locations (typically /lib and /usr/lib) or in one of the paths
mentioned in LD_LIBRARY_PATH.

/gordon

--

Bala

unread,
Nov 8, 2007, 5:31:45 PM11/8/07
to


All the dependent libraries that libSubscribe.so is statically linked
and are all static c libraries.

Loading of libSubscribe.so is successful now, but after that the
Java's Main application tries to call the required native function, i
am getting an error which i have pasted below the source code.

This is how my source code looks like
Main.java - Executing Program
------------------------------
class Main {
public static void main (String Args[]) {
OpenApi openApi = new OpenApi();
openApi.OAPIInit ();
}
}

OpenApi.java - Used to generate OpenApi.h using javah
-----------------------------------------------------
class OpenApi {
public native void OAPIInit ();

static {
System.loadLibrary ("OpenApiImp");
}
}

JavaC.C - Used to create libOpenApiImp.so
------------------------------------------
#include "OpenApi.h"
#include "jni.h"
#include <Common.h>
#include <dlfcn.h>
#include <link.h>

JNIEXPORT void JNICALL Java_OpenApi_OAPIInit(JNIEnv *env, jobject obj)
{
if (!dlopen ("//home1//users//biyer//Bala//OAPI//src//
libSubscribe.so", RTLD_GLOBAL))
{
printf ("\n Library Loaded Successfully\n");
OAPI_main();
printf ("\n OAPI_Main Called\n");
}
else
printf ("\nError Loading the Dynamic Library\n");
}

Common.C - Used to generate libSubscribe.so
-------------------------------------------
void OAPI_main()
{
printf ("\nIn OAPI Main\n");
OAPI_Init();
strcpy (FirmName, "BRAS");
OAPI_PASSPORT *Passport = GetAPassport (FirmName);
OAPI_Logon (Passport);
OAPI_start();
SpecialRequest();
My_mainloop();
}

All the functions called by OPAI_main are functions inside the static
libraries which are linked to libSubscribe.so.

When i run Main.java, i get the error as i stated

java Main

Library Loaded Successfully
ld.so.1: java: fatal: relocation error: file /home1/users/biyer/Bala/


OAPI/src/libOpenApiImp.so: symbol _Z9OAPI_mainv: referenced symbol not
found

Killed


Any thoughts why this could be happening? Does this mean that the
static libraries havent got linked properly?

This is the command that i use to build both the shared libraries.
libOpenApiImp.so
----------------
g++ -fpic -Wl,-G -Wl,-dy -Wno-deprecated -D_REENTRANT -DSOLARIS -DSUN4
-DSUN -DSVR4 -D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/
java/include/solaris
-I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/
src JavaC.C /home1/users/biyer/Bala/OAPI/lib/libAdpt.a /home1/users/
biyer/Bala/OAPI/lib/libDef.a
/home1/users/biyer/Bala/OAPI/lib/libxAdpt.a -o libOpenApiImp.so

libSubscribe.so
---------------
g++ -fpic -Wl,-G -Wl,-dy -Wno-deprecated -D_REENTRANT -DSOLARIS -DSUN4
-DSUN -DSVR4
-D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/java/include/
solaris
-I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/
src Common.C /home1/users/biyer/Bala/OAPI/lib/libAdpt.a /home1/users/
biyer/Bala/OAPI/lib/libDef.a
/home1/users/biyer/Bala/OAPI/lib/libxAdpt.a -o libSubscribe.so

Joshua Cranmer

unread,
Nov 8, 2007, 7:19:50 PM11/8/07
to
Bala wrote:
> ld.so.1: java: fatal: relocation error: file /home1/users/biyer/Bala/
> OAPI/src/libOpenApiImp.so: symbol _Z9OAPI_mainv: referenced symbol not
> found
> Killed
>
>
> Any thoughts why this could be happening? Does this mean that the
> static libraries havent got linked properly?
>
> libOpenApiImp.so
> ----------------
> g++ -fpic -Wl,-G -Wl,-dy -Wno-deprecated -D_REENTRANT -DSOLARIS -DSUN4
> [snip]

And there's your problem: you're using a C++ compiler to generate C
code. Either use gcc or declare your methods to be C-based (extern "C").

The long of it:
Inside the linked native libraries, there can only be one function by
any given name. This is why C does not permit multiple functions of the
same name. When C++ introduced this feature, the function names had to
be modified by use of a specific mangling technique. So your "OAPI_main"
become "_Z9OAPI_mainv" instead of "_OAPI_main"; the extra characters are
a nice way of encoding its name to avoid conflicts.

By declaring functions to be C (or similar) via the `extern "C"'
keywords, the compiler is instructed to not mangle these names as they
produce the code.

P.S. Sorry to anybody if my oversimplified explanation of mangled names
became too inaccurate.

--
Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Gordon Beaton

unread,
Nov 9, 2007, 2:18:09 AM11/9/07
to
On Thu, 08 Nov 2007 14:31:45 -0800, Bala wrote:
> This is the command that i use to build both the shared libraries.
> libOpenApiImp.so
> ----------------
> g++ -fpic -Wl,-G -Wl,-dy -Wno-deprecated -D_REENTRANT -DSOLARIS -DSUN4
> -DSUN -DSVR4 -D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/
> java/include/solaris
> -I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/
> src JavaC.C /home1/users/biyer/Bala/OAPI/lib/libAdpt.a /home1/users/
> biyer/Bala/OAPI/lib/libDef.a
> /home1/users/biyer/Bala/OAPI/lib/libxAdpt.a -o libOpenApiImp.so
>
> libSubscribe.so
> ---------------
> g++ -fpic -Wl,-G -Wl,-dy -Wno-deprecated -D_REENTRANT -DSOLARIS -DSUN4
> -DSUN -DSVR4
> -D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/java/include/
> solaris
> -I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/
> src Common.C /home1/users/biyer/Bala/OAPI/lib/libAdpt.a /home1/users/
> biyer/Bala/OAPI/lib/libDef.a
> /home1/users/biyer/Bala/OAPI/lib/libxAdpt.a -o libSubscribe.so

Joshua has already explained about the name mangling.

I just thought I'd mention that it's rather unconventional to specify
static libraries as though they were unadorned object files, even
though it might work for you. The "normal" way is to specify one or
more library paths with -L, the each library with -l, like this:

-L /home1/users/biyer/Bala/OAPI/lib -lAdpt -lDef -lxAdpt

IMO this is both clearer and easier to maintain (lookup "DRY" on
wikipedia). There may also be subtle differences in the way the linker
treats the files as well, but that's just speculation.

/gordon

--

Bala

unread,
Nov 12, 2007, 6:07:56 PM11/12/07
to
> --- Hide quoted text -
>
> - Show quoted text -

Hello,

Thanx Joshua,
I was able to run the application when i put OAPI_main in extern "C".
Was a silly mistake. But the static libraries that i am using are
compiled with CC 5.8. So g++ compiled code doesnt work for specific
functions when it tries to call them. Hence i migrated my source
compilation to CC, the same code just that i used CC instead of g++ to
create the shared libraries.
I am facing a different issue here.

Java program loads the first libOpenApiImp.so file properly, but this
in turn fails to load libSubscribe.so. This works perfect with g++
compiled versions.

I created a shared library using CC with the following command

CC -G -D_REENTRANT -DSOLARIS -DSUN4 -DSUN -DSVR4 -


D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/java/include/
solaris -I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/

Bala/OAPI/src Common.cpp liba.a libb.b -o libSubscribe.so

Then i compiled my source as
CC -DSOLARIS -DSUN4 -DSUN -DSVR4 -D_POSIX_PTHREAD_SEMANTICS -I/home1/
users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/src
Main.cpp -o Main.o

Now when i run Main.o it says its not able to open the shared
library. It prints an error message which is part of my code. "Error
Loading the Dynamic Library"

I am also attaching the sample code in here.. The path of the library
that i have mentioned is correct since the same code works fine with g+
+ created shared library.

Please let me know if i need to do something differently if i am using
CC.

Main.cpp
--------
#include <iostream>


#include <Common.h>
#include <dlfcn.h>
#include <link.h>

#include <stdio.h>

using namespace std;

int main ()
{
void *handle;
void (*fptr)();
handle = dlopen ("./libSubscribe.so", RTLD_GLOBAL | RTLD_LAZY);
if (handle == NULL)


printf ("\nError Loading the Dynamic Library\n");

else


{
printf ("\n Library Loaded Successfully\n");

fptr = (void (*) ()) dlsym (handle, "OAPI_main");
if (fptr)
{
(*fptr)();


printf ("\n OAPI_Main Called\n");
}
else
{

printf ("\nCould not find method\n");
}
}
return (0);
}

Gordon Beaton

unread,
Nov 13, 2007, 2:00:29 AM11/13/07
to
On Mon, 12 Nov 2007 15:07:56 -0800, Bala wrote:
> I was able to run the application when i put OAPI_main in extern
> "C". Was a silly mistake. But the static libraries that i am using
> are compiled with CC 5.8. So g++ compiled code doesnt work for
> specific functions when it tries to call them.

That seems to indicate that the static functions should have been
declared extern "C".

Have you thought of using gcc (not g++), since your code really isn't
c++ anyway... it could save you a lot of grief.

> Hence i migrated my source compilation to CC, the same code just
> that i used CC instead of g++ to create the shared libraries. I am
> facing a different issue here.
>
> Java program loads the first libOpenApiImp.so file properly, but this
> in turn fails to load libSubscribe.so. This works perfect with g++
> compiled versions.

Are you saying that dlopen() fails, or dlsym()? Have you checked errno
or called dlerror() so see why, instead of simply printing your own
message indicating failure?

If dlopen() is failing, check (with "ldd") that libSubscribe.so has no
further runtime dependencies, and (with "file") that it is a correctly
built shared object. If there are additional runtime dependencies,
they must be findable through LD_LIBRARY_PATH or in a standard place
like /lib or /usr/lib.

If dlsym() is failing, make sure (with "nm" or "objdump") that the
shared library contains the correct unmangled symbols you think it
does.

You might consult the Solaris Linker and Libraries Guide, online at
docs.sun.com.

BTW this is no longer a Java or JNI issue, consider taking it to a
Solaris newsgroup.

/gordon


--

Bala

unread,
Nov 13, 2007, 9:16:24 AM11/13/07
to
> BTW this is no longer a Java orJNIissue, consider taking it to a
> Solaris newsgroup.
>
> /gordon
>
> --

Yeah sure. I will check it out on the solaris group, since it seems
to be an issue with the way CC and g++ works. Thanx for all the help
in this regard. Will get back once this issue is solved to discuss
more about JNI stuff.

Thanks again for the timely help.
Bala

0 new messages