I’ve worked with lots of embedding APIs for C in my life (Perl/XS, PHP, PostgreSQL/libpg, etc) and I really enjoyed one aspect of the Java JNI: the Sun guys made the wise decision of putting everything into just the jni.h header file and not even providing a corresponding libjni.a. All JNI API functions are part of a large environment data structure (as function pointers) passed to all Java native functions.
I don’t know whether it was intentional or just by accident. But this is an ultra portable way for loading extensions as Dynamic Shared Objects (DSO) as there are no symbols of the application the Unix Run-Time Link-Editor (RTLD) has to resolve for the loaded DSO. This is usually a portability issue when dealing with DSOs, although I guess mostly all Unix programmers never recognize. Nice done, Sun! I would like to see more DSO based embedding APIs which use this approach.