#define INCL_DOS
#define INCL_DOSMODULEMGR
#define INCL_DOSMISC
#define INCL_DOSERRORS
#include <os2.h>
#include <stdio.h>
#include <ctype.h>
#include <jni.h>
#include <stdlib.h>
#include <iostream>
#include "LoadLib.hpp"
LoadLib *javm;
ULONG rc;
JNIEnv* create_vm() {
javm = new LoadLib( "client\\jvm" );//, ".", false ); //when used with sqlite3 and cairo
if( javm->rc == NO_ERROR ) {
JavaVM* jvm;
JNIEnv* env;
JavaVMOption options[] = {
{ "-Xmx512m", NULL },
{ "-XX:+TraceClassLoading", NULL },//To see the origin of the problem class
{ "-Djava.class.path=.", NULL }, //D:\\Programs\\vxrexx\\projects\\ODBCADMN\\j4o";
{ "-Djava.library.path=.", NULL },// set native library path
{ "-Djava.compiler=NONE", NULL }, // disable JIT
{ "-verbose:gc", NULL }, // print gc messages
{ "-verbose:jni", NULL }, // print JNI-related messages
{ "-verbose:class", NULL } // print class loading messages
};
JavaVMInitArgs args;
args.version = JNI_VERSION_1_6;
args.nOptions = sizeof( options ) / sizeof( JavaVMOption );
args.options = options;
args.ignoreUnrecognized = JNI_FALSE;
InitFunc( javm->hmod, jint, JNI_CreateJavaVM, ( JavaVM **p_vm, void **p_env, void *vm_args ) );
jint jrc = JNI_CreateJavaVM( &jvm, (void**)&env, &args );
//#ifdef __WATCOMC__
if( jrc != JNI_OK )
cerr << "Problems loading JVM" << endl;
else
cout << "JVM has been loaded sucessfully" << endl;
//#endif
delete options;
return env;
}
return NULL;
}
void invoke_class( JNIEnv* env ) {
cout << "invoke class" << endl;
jclass helloWorldClass;
jmethodID mainMethod;
jobjectArray applicationArgs;
jstring applicationArg0;
cout << "FindClass HelloWorld" << endl;
helloWorldClass = env->FindClass( "HelloWorld" );
cout << "main helloWorld" << endl;
mainMethod = env->GetStaticMethodID( helloWorldClass, "main", "([Ljava/lang/String;)V" );
cout << "New Args" << endl;
applicationArgs = env->NewObjectArray( 1, env->FindClass( "java/lang/String" ), NULL );
cout << "New UTF String to test parameters" << endl;
applicationArg0 = env->NewStringUTF( "testparam" );
cout << "Args" << endl;
env->SetObjectArrayElement( applicationArgs, 0, applicationArg0 ); //KABOOM! Unless commented out. :-(
cout << "void main" << endl;
env->CallStaticVoidMethod( helloWorldClass, mainMethod, applicationArgs);
}
int main( int argc, char **argv ) {
JNIEnv* env = create_vm();
if( env )
invoke_class( env );
else
return 1;
return 0;
}
typedef struct _EXCEPTIONREGISTRATIONRECORD2
{
EXCEPTIONREGISTRATIONRECORD reg;
jmp_buf jmp;
} EXCEPTIONREGISTRATIONRECORD2, *PEXCEPTIONREGISTRATIONRECORD2;
extern ULONG APIENTRY ExceptionHandler(
PEXCEPTIONREPORTRECORD pRep,
PEXCEPTIONREGISTRATIONRECORD2 pReg,
PCONTEXTRECORD pCtx,
PVOID pDispCtx);
#define TRY(except) \
{ \
EXCEPTIONREGISTRATIONRECORD2 except={0}; \
except.reg.ExceptionHandler = (ERR)ExceptionHandler; \
DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)&except); \
if (setjmp(except.jmp) == 0) {
#define CATCH() \
} else {
#define ENDTRY(except) \
} \
DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)&except); \
}
...
ULONG APIENTRY ExceptionHandler(
PEXCEPTIONREPORTRECORD pRep,
PEXCEPTIONREGISTRATIONRECORD2 pReg,
PCONTEXTRECORD pCtx,
PVOID pDispCtx)
{
if (pRep->fHandlerFlags & (EH_EXIT_UNWIND|EH_UNWINDING|EH_NESTED_CALL))
{
return XCPT_CONTINUE_SEARCH;
}
switch (pRep->ExceptionNum)
{
case XCPT_ACCESS_VIOLATION:
case XCPT_ILLEGAL_INSTRUCTION:
case XCPT_PRIVILEGED_INSTRUCTION:
case XCPT_INVALID_LOCK_SEQUENCE:
case XCPT_INTEGER_DIVIDE_BY_ZERO:
case XCPT_INTEGER_OVERFLOW:
case XCPT_FLOAT_DIVIDE_BY_ZERO:
case XCPT_FLOAT_OVERFLOW:
case XCPT_FLOAT_UNDERFLOW:
case XCPT_FLOAT_INVALID_OPERATION:
case XCPT_FLOAT_DENORMAL_OPERAND:
case XCPT_FLOAT_INEXACT_RESULT:
case XCPT_FLOAT_STACK_CHECK:
longjmp(pReg->jmp,1);
default:
break;
}
return XCPT_CONTINUE_SEARCH;
}
/* Workaround a bug in some OS/2 PM API calls that
* modify the FPU Control Word but fail to restore it.
*/
usCW = _control87 (0, 0);
usCW = usCW | EM_INVALID | 0x80;
_control87 (usCW, MCW_EM | 0x80);
/* r = return type, f = funtion name, p = parameter(s) */
#define InitFunc( h, r, f, p ) \
r( __syscall *f)p; \
rc = DosQueryProcAddr( h, NULL, "_"#f, (PFN *) &f ); /*GCC*/\
if( rc != 0 ) \
rc = DosQueryProcAddr( h, NULL, #f, (PFN *) &f );/*OW*/
/* v = variable name */
#define InitNoFPE( v ) \
EXCEPTIONREGISTRATIONRECORD ex = { 0, }; \
LoadLib *v = new LoadLib(); \
_control87( 0, MCW_EM ); \
if( v ) { \
ex.ExceptionHandler = ( ERR )fpeHandler; \
DosSetExceptionHandler( &ex ); \
}
/* v = variable name, n = name of dll, p = path to dll */
#define NoFPE( v, n, p ) \
v->LoadLibrary( #n, #p ); \
if( v->rc == NO_ERROR ) { \
_control87( 0, MCW_EM ); \
DosSetExceptionHandler( &ex ); \
}
// this handler was excerpted from Mozilla repository
#define AddFPEHandler() \
static ULONG fpeHandler( PEXCEPTIONREPORTRECORD p1,\
PEXCEPTIONREGISTRATIONRECORD p2,\
PCONTEXTRECORD p3, \
PVOID p4 ) \
{ \
switch( p1->ExceptionNum ) \
{ \
case XCPT_FLOAT_DENORMAL_OPERAND: \
case XCPT_FLOAT_DIVIDE_BY_ZERO: \
case XCPT_FLOAT_INEXACT_RESULT: \
case XCPT_FLOAT_INVALID_OPERATION: \
case XCPT_FLOAT_OVERFLOW: \
case XCPT_FLOAT_STACK_CHECK: \
case XCPT_FLOAT_UNDERFLOW: \
{ \
unsigned cw = p3->ctx_env[0]; \
if( ( cw & MCW_EM ) != MCW_EM ) { \
/* Mask out all floating point exceptions */\
p3->ctx_env[0] |= MCW_EM; \
/* Following two lines set precision to 53 bit mantissa. See jsnum.c */\
p3->ctx_env[0] &= ~MCW_PC; \
p3->ctx_env[0] |= PC_53; \
printf("----- XCPT_CONTINUE_EXECUTION\n");\
return XCPT_CONTINUE_EXECUTION; \
} \
break; \
} \
} \
return XCPT_CONTINUE_SEARCH; \
}
Rexx interpreter: REXXSAA 4.00 3 Feb 1999
BSF4Rexx (DLL/so): 282.20090420 org/rexxla/bsf/engines/rexx
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at org.rexxla.bsf.engines.rexx.RexxAndJava.javaCallBSF(RexxAndJava.java:1306)
#define cairo_public __declspec(__cdecl)
#include <cairo\cairo.h>
#include <cairo\cairo-os2.h>
and later has, // Set FPU state which might have been changed by some Win* calls!
// (Workaround for a PM bug)
DisableFPUException();
// Initialize cairo support
cairo_os2_init();
with DisableFPUException being,/* One helper function: */
static void inline DisableFPUException()
{
unsigned short usCW;
// Some OS/2 PM API calls modify the FPU Control Word,
// but forgets to restore it.
// This can result in XCPT_FLOAT_INVALID_OPCODE exceptions,
// so to be sure, we always disable Invalid Opcode FPU exception
// before using FPU stuffs with Cairo or from this thread.
usCW = _control87(0, 0);
usCW = usCW | EM_INVALID | 0x80;
_control87(usCW, MCW_EM | 0x80);
}
With the linker fed an Imports.lnk consisting of the exports,IMPORT _cairo_os2_surface_paint_window cairo2
IMPORT _cairo_save cairo2
IMPORT _cairo_scale cairo2
IMPORT _cairo_set_source_rgb cairo2
IMPORT _cairo_rectangle cairo2
IMPORT _cairo_fill cairo2
IMPORT _cairo_translate cairo2
IMPORT _cairo_set_line_width cairo2
IMPORT _cairo_move_to cairo2
IMPORT _cairo_line_to cairo2
IMPORT _cairo_close_path cairo2
IMPORT _cairo_stroke cairo2
IMPORT _cairo_arc cairo2
IMPORT _cairo_select_font_face cairo2
IMPORT _cairo_set_font_size cairo2
IMPORT _cairo_text_extents cairo2
IMPORT _cairo_text_path cairo2
IMPORT _cairo_set_source_rgba cairo2
IMPORT _cairo_fill_preserve cairo2
IMPORT _cairo_restore cairo2
IMPORT _cairo_os2_init cairo2
IMPORT _cairo_os2_surface_create_for_window cairo2
IMPORT _cairo_os2_surface_set_hwnd cairo2
IMPORT _cairo_create cairo2
IMPORT _cairo_destroy cairo2
IMPORT _cairo_surface_destroy cairo2
IMPORT _cairo_os2_fini cairo2
LoadLib *jVM = new LoadLib( "jvm" ); //find in before/after libpath, path etc.
if( jVM->rc != NO_ERROR ) //jvm.dll not found, try subfolder "client" of above and environment variable JAVA_HOME (if set), try as is if param 2 instead contain \.
jVM->Load( "client\\jvm", "JAVA_HOME" );
/* Define each function dynamically */
int rc = NO_ERROR; //must be defined as InitFunc use rc
InitFunc( jVM->hmod, jint, JNI_GetDefaultJavaVMInitArgs, ( void *vm_args ) );
InitFunc( jVM->hmod, jint, JNI_CreateJavaVM, ( JavaVM **p_vm, JNIEnv **p_env, void *vm_args ) );
InitFunc take care of decorations "_" in front or after.resVer = JNI_GetDefaultJavaVMInitArgs(&vm_args2);
...res = JNI_CreateJavaVM( ¤tJVM, &jniEnv, &vm_args2);