私は自分が抱えている問題についてまともな感覚を持っていると思いますが、何が起こっているのかについて誰かがもっと洞察を持っているかどうか疑問に思っていました. これは、try-to-use-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.7.0_05 ではなく Java 1.6.0_33 に切り替えると、アプリケーションがクラッシュしなくなりました
- ネイティブ コードで JAWT へのすべての参照を削除すると、アプリケーションがクラッシュしなくなりました
- すべてのビジネス ロジックを削除し、ネイティブ コードで JAWT をインスタンス化するだけで、クラッシュします。
- コード内で実際にネイティブ呼び出しを行う必要さえありません。
jawt.lib
viaにリンクされた DLL をロードするSystem.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 に切り替える)、アプリケーションは正常に実行されます。