我想我对自己遇到的问题有一个不错的认识,但我想知道是否有人对正在发生的事情有更深入的了解。这可能与尝试使用 jawt-on-64-bit-windows-7-os 有关。
我有一个相当简单的 Java GUI 应用程序,我正在尝试将 Windows HWND 安装到它上面,这样我就可以附加一个孩子。基本上,我注意到的是,每当我在本机代码中使用 JAWT 资源时,它都会崩溃。它甚至不一定会在我的代码上崩溃,甚至不必点击 JAWT 代码。在jawt.dll/jawt.lib 中链接似乎就足够了。例如,sun.java2d.loops.DrawGlyphListLCD.DrawGlyphListLCD(Lsun/java2d/SunGraphics2D;Lsun/java2d/SurfaceData;Lsun/font/GlyphList;)V+0
当我的 Swing GUI 被渲染时,我在 Java 的 fontmanager.dll 中的类中看到了许多崩溃。完整hs_err_pid9108.log
可用:http: //pastebin.com/2QS0fDuf
一些有趣的笔记:
- 如果我将 JRE 切换到 Java 1.6.0_33 而不是 Java 1.7.0_05,则应用程序不再崩溃
- 如果我在本机代码中删除所有对 JAWT 的引用,应用程序将不再崩溃
- 如果我删除所有业务逻辑,只在本机代码中实例化 JAWT,它仍然会崩溃
- 我什至实际上不必在我的代码中进行本机调用。加载链接到
jawt.lib
via的 DLLSystem.load(...)
就足够了。我的应用程序在渲染其 GUI(使用 JRE 7)时仍会崩溃。
我已经尽可能地将代码提炼成一个仍然会失败的例子。这是Java类:
JawtTestApp.h(本机头文件)
#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(本机实现)
#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 文件)
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
}
}
请记住,编译时必须包含 JDK/include 和 JDK/include/win32,链接时必须包含 JDK/lib/jawt.lib。
我仍在进行跨平台、JDK 等的测试,但是基于这些信息,有人有什么想法吗?我缺少一个神奇的编译器标志吗?有Java补丁吗?我在这里没有想法了。
这是我的系统信息:
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
=======================================
更新
似乎这只是使用 Swing 组件的问题。如果我将上面的示例更改为使用 AWT 组件(将 JFrame 切换为 Frame),应用程序将成功运行。