You just got your JNI-based code to compile and link ...
but MRJ still throws an
Let's look at each of these in detail.
Exporting The Right Stuff
For MRJ to find the right functions to call in your library, they need to be exported. The linker needs to know which functions to export when it links the library. The documentation for your development system (probably either MPW or CodeWarrior) will describe in detail how to set up exports. There are basically two ways to do it:
Use a .exp file. One way to set up exports is via
a separate ".exp" file, which is a text file that contains
the names of the exported functions, one per line. If using
CodeWarrior, you add the .exp file to your project, then go
to the "PPC PEF" panel of the Project Settings dialog and
set the "Export" pop-up to "Use '.exp' File." If using MPW's
If you use a .exp file, make sure that you spell all the function names correctly (pasting them in from your source files is the best bet) and be sure to keep the file in sync when you add, remove, or rename native methods -- or if any parameters change.
Use #pragma export. The other method -- which I prefer -- is to use a C/C++ "
Another equivalent way to mark the functions for export
is to use the standard
You then need to tell the linker to export marked
functions. If using CodeWarrior, go to the "PPC PEF" panel of the Project Settings dialog and set the "Export" pop-up to "Use #pragma." If using MPW's
The advantage of using the second technique is that it always exports the correct functions, even if the set of native methods change. All you have to do is re-run java.h (or recompile your Java classes, if you're using CodeWarrior's option to emit JNI headers) and the list of exported functions will automatically be updated next time you build your native library.
The second major mistake developers make is incorrectly naming the library . The name of the library should be
exactly the same as the name you pass to
Moreover, the library name is not the same thing
as the library's filename. The filename is ignored; it's the
library name (or "fragment name") that counts. In
CodeWarrior, you set it in the "PPC PEF" project settings
panel. In MPW's
Finally, even if your library is built perfectly, it won't do much good if MRJ can't find it. The library file needs to be on the CFM search path. Basically, this means that it needs to be:
"The application", of course, can mean a JBindery-generated application, a browser like Microsoft Internet Explorer, or Apple Applet Runner. (Note that if you're running your code directly from JBindery without saving the settings as an app, then "the application" means JBindery itself).
If your native code is being used by a specific application, then the usual place to put the library is into the same folder as the app. If your native code is part of a shared Java library that's installed in the MRJClasses folder, then the native library should go into the MRJ Libraries folder (not the MRJClasses folder, for reasons described above).
Embedding the code fragment within the application itself
is tempting, especially since -- if combined with a Virtual
File System -- you can boil your whole app down to a single
file. Since the data fork is already in use by the VFS, the
best place to put the code fragment is into a resource.
You'll have to tell the linker to generate a code resource,
then copy the resource into the app and add a new entry to
If you have a pesky native library that just flat-out refuses to load even after you've used all the previous information to troubleshoot it, here's a way to debug some of the loading process. (You must have MacsBug installed to do this. Technote 1154, Debugging Java Code With MacsBug, has an introduction to MacsBug for Java developers.)
Gordon, Rob. Essential JNI. Prentice-Hall PTR, 1998. Excellent description of JNI, with lots of examples and a handy reference section at the end. Unfortunately, the platform-specific details cover only Windows and Unix, but this Technote should help you over the few trouble spots.
Apple Computer. Inside Macintosh: PowerPC System Software. Addison-Wesley, 1994. Contains a detailed description of the Code Fragment Manager (CFM) and how it loads shared libraries. (The entire book is available online in PDF form.)
Apple Computer. Building
and Managing Programs in MPW. Documents MPW tools, including
Contact ADC | ADC Site Map | ADC Advanced Search
|For information about Apple Products, please visit Apple.com.|
Contact Apple | Privacy Notice
Copyright © 2002 Apple Computer, Inc. All rights reserved.