Commit 6d7b28522c0a4e1b02152f4689e41e1314acf3db

Authored by perry.werneck@gmail.com
1 parent a78dd248

Implementando plugin e extensão java para windows

src/java/Makefile.in
... ... @@ -86,7 +86,7 @@ PW3270_CFLAGS ?= -I../include
86 86 PLUGIN_CFLAGS=@CXXFLAGS@ -DPW3270_PLUGIN -Wno-deprecated-declarations @DLL_CFLAGS@ @JNI_CPPFLAGS@ -DJNIDIR="\"$(jnidir)\"" \
87 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 91 #---[ Rules ]------------------------------------------------------------------
92 92  
... ... @@ -190,7 +190,7 @@ $(BINRLS)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@: \
190 190  
191 191 @echo " LD `basename $@`"
192 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 195 $(BINRLS)/plugins/j3270@DLLEXT@: \
196 196 $(foreach SRC, $(basename $(PLUGIN_SRC)), $(OBJRLS)/j3270/$(SRC)@OBJEXT@) \
... ... @@ -218,7 +218,7 @@ $(BINDBG)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@: \
218 218  
219 219 @echo " LD `basename $@`"
220 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 223 $(BINDBG)/plugins/j3270@DLLEXT@: \
224 224 $(BINDBG)@DLLDIR@/@DLLPREFIX@jni3270@DLLEXT@ \
... ...
src/java/private.h
... ... @@ -49,6 +49,10 @@
49 49  
50 50 namespace java {
51 51  
  52 +#ifdef _WIN32
  53 + extern HMODULE hModule;
  54 +#endif // WIN32
  55 +
52 56 extern JavaVM * jvm;
53 57 extern JNIEnv * env;
54 58  
... ...
src/java/startstop.cc
... ... @@ -154,8 +154,11 @@ extern "C" {
154 154  
155 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 163 void java::failed(GtkWidget *widget, const char *msg, const char *format, ...) {
161 164  
... ... @@ -189,7 +192,159 @@ extern "C" {
189 192  
190 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  
... ...