問題はnative側のオブジェクトへの参照をいかにJava側へ渡すかである.類似の議論は, JavaHouse, JavaWorldなどで行われている.Java側で JMOSSite.AccessDrawer()が JMOSDrawer(CMOSSite) を呼ぶようにしたところ,CMOSSite->AccessDrawer()までは動作(この時点でMAPPERのSYSTEM を見るとCabinetTOCとなっている)するようになったが,getHashCode()でエラーとなりRegistryへの登録ができない.getHashCode()に渡そうとしているポインタがJMOSDrawerではなくCMOSDrawerだからでは?
Registryに登録されるのは,つまりJava側のオブジェクト(jobject)とnative側のオブジェクトのマッピングである.必ずしもJava側とnative側のコンストラクタが同期する必要はない.そこで以下のようにすることで,JMOSSite.AccessDrawer()の件をついに解決.

public class JMOSSite {
public JMOSDrawer AccessDrawer(String drawerName) {
JMOSDrawer jd = new JMOSDrawer();
jd = AccessDrawer(jd, drawerName);
return(jd);
};
private native JMOSDrawer AccessDrawer(JMOSDrawer jd, String
drawerName);
}
JNIEXPORT jobject JNICALL Java_JMOSSite_AccessDrawer
(JNIEnv *env, jobject jmosSite, jobject jmosDrawer, jstring drw)
{
CMOSSite *c;
CMOSDrawer *d;
jboolean isCopy1;
char *drawerName;
jint hashCode = getHashCode(env, jmosSite);
Registry::lookup((void*)hashCode, (void*&) c);
drawerName = (char *) env->GetStringUTFChars(drw, &isCopy1);
d = c->AccessDrawer((const char *)drawerName);
hashCode = getHashCode(env, jmosDrawer);
Registry::add((void*) hashCode, (void*&) d);
if (isCopy1 == JNI_TRUE)
env->ReleaseStringUTFChars(drw,drawerName);
return(jmosDrawer);
}
JNIEXPORT void JNICALL Java_JMOSDrawer__1jni_1initialize
(JNIEnv *env, jobject jmosDrawer)
{
jint hashCode = getHashCode(env, jmosDrawer);
//      CMOSDrawer *cmosDrawer = new CMOSDrawer((const char
*)DrawerName, (CMO
SSession *)jmosSession);
//      Registry::add((void*) hashCode, (void*&) cmosDrawer);
}

つまりJMOSSiteには,

public JMOSDrawer AccessDrawer(String drawerName)
private native JMOSDrawer AccessDrawer(JMOSDrawer jd, String  drawerName)

2種類のAccessDrawer()メソッドを用意.AccessDrawer(String)はJMOSDrawerを初期化し,その参照をAccessDrawer(JMOSDrawer,String)に渡す.JMOSDrawerのコンスラクタは何もしない(インスタンスを初期化するだけ).AccessDrawer(JMOSDrawer,String)はnative側のAccessDrawerを呼び出し,この中でRegistryへの登録を行う.