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 |