Commit 6d7b28522c0a4e1b02152f4689e41e1314acf3db
1 parent
a78dd248
Exists in
master
and in
5 other branches
Implementando plugin e extensão java para windows
Showing
3 changed files
with
165 additions
and
6 deletions
Show diff stats
src/java/Makefile.in
| @@ -86,7 +86,7 @@ PW3270_CFLAGS ?= -I../include | @@ -86,7 +86,7 @@ PW3270_CFLAGS ?= -I../include | ||
| 86 | PLUGIN_CFLAGS=@CXXFLAGS@ -DPW3270_PLUGIN -Wno-deprecated-declarations @DLL_CFLAGS@ @JNI_CPPFLAGS@ -DJNIDIR="\"$(jnidir)\"" \ | 86 | PLUGIN_CFLAGS=@CXXFLAGS@ -DPW3270_PLUGIN -Wno-deprecated-declarations @DLL_CFLAGS@ @JNI_CPPFLAGS@ -DJNIDIR="\"$(jnidir)\"" \ |
| 87 | -DJARDIR="\"$(jvmjardir)\"" @GTK_CFLAGS@ @GTKMAC_CFLAGS@ $(PW3270_CFLAGS) | 87 | -DJARDIR="\"$(jvmjardir)\"" @GTK_CFLAGS@ @GTKMAC_CFLAGS@ $(PW3270_CFLAGS) |
| 88 | 88 | ||
| 89 | -PLUGIN_LIBS=@GTK_LIBS@ @GTKMAC_LIBS@ @JVM_LIBS@ | 89 | +PLUGIN_LIBS=@GTK_LIBS@ @GTKMAC_LIBS@ @INTL_LIBS@ @JVM_LIBS@ |
| 90 | 90 | ||
| 91 | #---[ Rules ]------------------------------------------------------------------ | 91 | #---[ Rules ]------------------------------------------------------------------ |
| 92 | 92 | ||
| @@ -190,7 +190,7 @@ $(BINRLS)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@: \ | @@ -190,7 +190,7 @@ $(BINRLS)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@: \ | ||
| 190 | 190 | ||
| 191 | @echo " LD `basename $@`" | 191 | @echo " LD `basename $@`" |
| 192 | @$(MKDIR) `dirname $@` | 192 | @$(MKDIR) `dirname $@` |
| 193 | - @$(CXX) @SYSDLL_FLAGS@ $(LDFLAGS) -Wl,-soname,`basename $@` -o $@ $^ $(CLASS_LIBS) | 193 | + @$(CXX) @SYSDLL_FLAGS@ $(LDFLAGS) -Wl,-soname,`basename $@` -o $@ $^ $(CLASS_LIBS) @INTL_LIBS@ |
| 194 | 194 | ||
| 195 | $(BINRLS)/plugins/j3270@DLLEXT@: \ | 195 | $(BINRLS)/plugins/j3270@DLLEXT@: \ |
| 196 | $(foreach SRC, $(basename $(PLUGIN_SRC)), $(OBJRLS)/j3270/$(SRC)@OBJEXT@) \ | 196 | $(foreach SRC, $(basename $(PLUGIN_SRC)), $(OBJRLS)/j3270/$(SRC)@OBJEXT@) \ |
| @@ -218,7 +218,7 @@ $(BINDBG)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@: \ | @@ -218,7 +218,7 @@ $(BINDBG)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@: \ | ||
| 218 | 218 | ||
| 219 | @echo " LD `basename $@`" | 219 | @echo " LD `basename $@`" |
| 220 | @$(MKDIR) `dirname $@` | 220 | @$(MKDIR) `dirname $@` |
| 221 | - @$(CXX) @SYSDLL_FLAGS@ $(LDFLAGS) -Wl,-soname,`basename $@` -o $@ $^ $(CLASS_LIBS) | 221 | + @$(CXX) @SYSDLL_FLAGS@ $(LDFLAGS) -Wl,-soname,`basename $@` -o $@ $^ $(CLASS_LIBS) @INTL_LIBS@ |
| 222 | 222 | ||
| 223 | $(BINDBG)/plugins/j3270@DLLEXT@: \ | 223 | $(BINDBG)/plugins/j3270@DLLEXT@: \ |
| 224 | $(BINDBG)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@ \ | 224 | $(BINDBG)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@ \ |
src/java/private.h
src/java/startstop.cc
| @@ -154,8 +154,11 @@ extern "C" { | @@ -154,8 +154,11 @@ extern "C" { | ||
| 154 | 154 | ||
| 155 | namespace PW3270_NAMESPACE { | 155 | namespace PW3270_NAMESPACE { |
| 156 | 156 | ||
| 157 | - JavaVM * java::jvm = NULL; | ||
| 158 | - JNIEnv * java::env = NULL; | 157 | + JavaVM * java::jvm = NULL; |
| 158 | + JNIEnv * java::env = NULL; | ||
| 159 | +#ifdef _WIN32 | ||
| 160 | + HMODULE java::hModule = NULL; | ||
| 161 | +#endif // _WIN32 | ||
| 159 | 162 | ||
| 160 | void java::failed(GtkWidget *widget, const char *msg, const char *format, ...) { | 163 | void java::failed(GtkWidget *widget, const char *msg, const char *format, ...) { |
| 161 | 164 | ||
| @@ -189,7 +192,159 @@ extern "C" { | @@ -189,7 +192,159 @@ extern "C" { | ||
| 189 | 192 | ||
| 190 | bool java::load_jvm(GtkWidget *widget) { | 193 | bool java::load_jvm(GtkWidget *widget) { |
| 191 | 194 | ||
| 192 | - #error Implementar | 195 | + if(jvm != NULL) { |
| 196 | + return true; | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + // Dynamically load jvm library to avoid naming and path problems. | ||
| 200 | + HMODULE kernel; | ||
| 201 | + HANDLE WINAPI (*AddDllDirectory)(PCWSTR NewDirectory); | ||
| 202 | + BOOL WINAPI (*RemoveDllDirectory)(HANDLE Cookie); | ||
| 203 | + | ||
| 204 | + struct _dlldir { | ||
| 205 | + const gchar * env; | ||
| 206 | + const gchar * path; | ||
| 207 | + HANDLE cookie; | ||
| 208 | + } dlldir[] = { | ||
| 209 | + { "JRE_HOME", "bin\\client", 0 }, | ||
| 210 | + { "JDK_HOME", "jre\\bin\\client", 0 } | ||
| 211 | + }; | ||
| 212 | + | ||
| 213 | + kernel = LoadLibrary("kernel32.dll"); | ||
| 214 | + | ||
| 215 | + AddDllDirectory = (HANDLE WINAPI (*)(PCWSTR)) GetProcAddress(kernel,"AddDllDirectory"); | ||
| 216 | + if(AddDllDirectory) { | ||
| 217 | + | ||
| 218 | + // Acrescenta mais caminhos para achar a dll | ||
| 219 | + for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { | ||
| 220 | + | ||
| 221 | + const char *env = getenv(dlldir[f].env); | ||
| 222 | + | ||
| 223 | + debug("%s=\"%s\"",dlldir[f].env,env); | ||
| 224 | + | ||
| 225 | + if(env) { | ||
| 226 | + | ||
| 227 | + gchar *p = g_build_filename(env,dlldir[f].path,NULL); | ||
| 228 | + | ||
| 229 | + debug("Adicionando diretório \"%s\"",p); | ||
| 230 | + | ||
| 231 | + wchar_t *path = (wchar_t *) malloc(4096*sizeof(wchar_t)); | ||
| 232 | + mbstowcs(path, p, 4095); | ||
| 233 | + dlldir[f].cookie = AddDllDirectory(path); | ||
| 234 | + free(path); | ||
| 235 | + | ||
| 236 | + g_free(p); | ||
| 237 | + | ||
| 238 | + } | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + } | ||
| 242 | + #ifdef DEBUG | ||
| 243 | + else { | ||
| 244 | + debug("Can't get %s: %s","AddDllDirectory",session::win32_strerror(GetLastError()).c_str()) | ||
| 245 | + } | ||
| 246 | + #endif // DEBUG | ||
| 247 | + | ||
| 248 | + hModule = LoadLibrary("jvm.dll"); | ||
| 249 | + | ||
| 250 | + if(hModule) { | ||
| 251 | + failed(widget, _( "Can't load java virtual machine" ), "%s", session::win32_strerror(GetLastError()).c_str()); | ||
| 252 | + } | ||
| 253 | + | ||
| 254 | + RemoveDllDirectory = (BOOL WINAPI (*)(HANDLE)) GetProcAddress(kernel,"RemoveDllDirectory"); | ||
| 255 | + if(RemoveDllDirectory) { | ||
| 256 | + | ||
| 257 | + for(size_t f = 0; f < G_N_ELEMENTS(dlldir); f++) { | ||
| 258 | + | ||
| 259 | + if(dlldir[f].cookie) { | ||
| 260 | + | ||
| 261 | + RemoveDllDirectory(dlldir[f].cookie); | ||
| 262 | + | ||
| 263 | + } | ||
| 264 | + } | ||
| 265 | + | ||
| 266 | + } | ||
| 267 | + | ||
| 268 | + FreeLibrary(kernel); | ||
| 269 | + | ||
| 270 | + if(!hModule) { | ||
| 271 | + return false; | ||
| 272 | + } | ||
| 273 | + | ||
| 274 | + // Consegui carregar a JVM, obtenho o método de controle | ||
| 275 | + jint JNICALL (*CreateJavaVM)(JavaVM **, void **, void *) = (jint JNICALL (*)(JavaVM **, void **, void *)) GetProcAddress(hModule,"JNI_CreateJavaVM"); | ||
| 276 | + | ||
| 277 | + if(!CreateJavaVM) { | ||
| 278 | + failed(widget, _( "Can't load java virtual machine creation method" ), "%s", session::win32_strerror(GetLastError()).c_str()); | ||
| 279 | + return false; | ||
| 280 | + } | ||
| 281 | + | ||
| 282 | + // Crio a JVM | ||
| 283 | + JavaVMInitArgs vm_args; | ||
| 284 | + JavaVMOption options[5]; | ||
| 285 | + | ||
| 286 | + jint rc = 0; | ||
| 287 | + | ||
| 288 | + memset(&vm_args,0,sizeof(vm_args)); | ||
| 289 | + memset(options,0,sizeof(options)); | ||
| 290 | + | ||
| 291 | + vm_args.version = JNI_VERSION_1_4; | ||
| 292 | + vm_args.nOptions = 0; | ||
| 293 | + vm_args.options = options; | ||
| 294 | + vm_args.ignoreUnrecognized = JNI_FALSE; | ||
| 295 | + | ||
| 296 | + options[vm_args.nOptions].optionString = g_strdup("vfprintf"); | ||
| 297 | + options[vm_args.nOptions].extraInfo = (void *) jni_vfprintf; | ||
| 298 | + vm_args.nOptions++; | ||
| 299 | + | ||
| 300 | + gchar * exports = NULL; | ||
| 301 | + char buffer[1024]; | ||
| 302 | + gchar * myDir; | ||
| 303 | + | ||
| 304 | + if(GetModuleFileName(NULL,buffer,sizeof(buffer)) < sizeof(buffer)) { | ||
| 305 | + | ||
| 306 | + gchar * ptr = strrchr(buffer,G_DIR_SEPARATOR); | ||
| 307 | + if(ptr) { | ||
| 308 | + *ptr = 0; | ||
| 309 | + myDir = g_strdup(buffer); | ||
| 310 | + } else { | ||
| 311 | + myDir = g_strdup("."); | ||
| 312 | + } | ||
| 313 | + | ||
| 314 | + | ||
| 315 | + } else { | ||
| 316 | + | ||
| 317 | + myDir = g_strdup("."); | ||
| 318 | + | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + debug("myDir=%s",myDir); | ||
| 322 | + | ||
| 323 | + exports = g_build_filename(myDir,"jvm-exports",NULL); | ||
| 324 | + g_mkdir_with_parents(exports,0777); | ||
| 325 | + | ||
| 326 | + lib3270_trace_event(v3270_get_session(widget),"java.class.path=%s",exports); | ||
| 327 | + lib3270_trace_event(v3270_get_session(widget),"java.library.path=%s",myDir); | ||
| 328 | + | ||
| 329 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.class.path=%s",exports); | ||
| 330 | + options[vm_args.nOptions++].optionString = g_strdup_printf("-Djava.library.path=%s",myDir); | ||
| 331 | + | ||
| 332 | + g_free(myDir); | ||
| 333 | + g_free(exports); | ||
| 334 | + | ||
| 335 | + rc = CreateJavaVM(&jvm,(void **)&env,&vm_args); | ||
| 336 | + if(rc < 0) { | ||
| 337 | + failed(widget, _( "Can't create java VM" ), _( "The error code was %d" ), (int) rc); | ||
| 338 | + jvm = NULL; | ||
| 339 | + } | ||
| 340 | + | ||
| 341 | + for(int f=0;f<vm_args.nOptions;f++) { | ||
| 342 | + trace("Releasing option %d: %s",f,options[f].optionString); | ||
| 343 | + g_free(options[f].optionString); | ||
| 344 | + } | ||
| 345 | + | ||
| 346 | + | ||
| 347 | + return jvm != NULL; | ||
| 193 | 348 | ||
| 194 | } | 349 | } |
| 195 | 350 |