I think I have a decent sense of the problem I'm having, but I was wondering if anyone had any more insight into what's going on. This may be related to trying-to-use-jawt-on-64-bit-windows-7-os.
I have a fairly simple Java GUI application and I'm trying to be able to get the Windows HWND to it so I can attach a child. Basically, what I notice is that any time I use JAWT resources in my native code, it crashes. It doesn't even necessarily crash on my code and it doesn't even have to hit the JAWT code. Linking in the jawt.dll/jawt.lib seems to be enough. For example, I've seen numerous crashes in the class sun.java2d.loops.DrawGlyphListLCD.DrawGlyphListLCD(Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Lsun/font/GlyphList;)V+0
in Java's fontmanager.dll when my Swing GUI is being rendered. Full hs_err_pid9108.log
available here: http://pastebin.com/2QS0fDuf
Some interesting notes:
- If I switch my JRE to Java 1.6.0_33 instead of Java 1.7.0_05, the application no longer crashes
- If I remove all references to JAWT in my native code, the application no longer crashes
- If I remove all my business logic and do nothing but instantiate JAWT in my native code, it still crashes
- I don't even actually have to make a native call in my code. Loading the DLL linked to
jawt.lib
viaSystem.load(...)
is enough. My application will still crash while rendering its GUI (with JRE 7).
I've distilled the code down as much as I can to an example that will still fail. Here's the Java class:
JawtTestApp.h (Native Header)
#include <jni.h>
#ifndef _Included_com_stackoverflow_JawtTestApp
#define _Included_com_stackoverflow_JawtTestApp
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT void JNICALL Java_com_stackoverflow_JawtTestApp_testJawt(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
JawtTestApp.cpp (Native Implementation)
#include <jawt_md.h>
#include <assert.h>
JNIEXPORT void JNICALL Java_com_stackoverflow_JawtTestApp_testJawt(JNIEnv *env, jobject jawtTestApp, jobject component)
{
JAWT awt;
awt.version = JAWT_VERSION_1_4;
assert(JAWT_GetAWT(env,&awt) != JNI_FALSE);
}
JawtTestApp.h (Java File)
package com.stackoverflow;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class JawtTestApp
{
private final JFrame frame;
/*
//AWT ONLY (this works)
private final Frame frame;
public JawtTestApp()
{
frame = new Frame();
frame.add(new Label("Please stop crashing!"));
frame.pack();
frame.setVisible(true);
}
*/
//SWING ONLY (this crashes)
private final JFrame frame;
public JawtTestApp()
{
frame = new JFrame();
frame.add(new JLabel("Please stop crashing!"));
frame.pack();
frame.setVisible(true);
}
public native void testJawt(Object o);
public static void main(final String args[])
{
System.load("C:\\Users\\username\\Documents\\Visual Studio 2005\\Projects\\JawtTestApp\\debug\\JawtTestApp.dll");
JawtTestApp app = new JawtTestApp();
app.testJawt(app.frame);
//NOTE: I don't actually even have to call the native method! System.load is enough
}
}
Keep in mind you'll have to include JDK/include and JDK/include/win32 when you compile and JDK/lib/jawt.lib when you link.
I'm still working on testing across platforms, JDKs, etc., but based on this information, does anyone have any ideas? Is there a magical compiler flag I'm missing? Is there a Java patch? I'm running out of ideas here.
Here's my system info:
OS: Windows 7 , 64 bit Build 7601 Service Pack 1
CPU:total 4 (2 cores per cpu, 2 threads per core) family 6 model 37 stepping 2, cmov, cx8, fxsr, mmx, sse, sse2, sse3, ssse3, sse4.1, sse4.2, popcnt, ht, tsc, tscinvbit
Memory: 4k page, physical 3985080k(1468212k free), swap 7968308k(4277740k free)
vm_info: Java HotSpot(TM) Client VM (23.1-b03) for windows-x86 JRE (1.7.0_05-b06), built on Jun 27 2012 00:51:27 by "java_re" with unknown MS VC++:1600
======================================
UPDATE
It seems like this is only a problem using Swing components. If I change the above example to use AWT components (switch JFrame to Frame), the application runs successfully.