M1 Mac运行Java GUI程序遇java.lang.NoSuchMethodError: accessibilityHitTest问题求助
问题描述
在M1芯片Mac上运行简单Java GUI程序时,触发Bad JNI lookup accessibilityHitTest错误,随后抛出Exception in thread "AppKit Thread" java.lang.NoSuchMethodError: accessibilityHitTest,点击按钮或在文本框输入都会触发该错误。
- 环境:通过Homebrew安装的OpenJDK 17.0.1,macOS 13.2 Ventura,已更新Homebrew、Java、Eclipse
- 额外现象:程序能启动,但按钮红色背景不显示,仅文本框黄色背景正常;Intel Mac上无JNI错误,但按钮背景依旧不显示;终端运行程序也出现相同问题,排除Eclipse影响
控制台错误输出
2023-02-12 07:50:17.847 java[10456:90865] Bad JNI lookup accessibilityHitTest 2023-02-12 07:50:17.849 java[10456:90865] ( 0 libawt_lwawt.dylib 0x000000010dcfc7d1 -[JavaComponentAccessibility accessibilityHitTest:withEnv:] + 153 1 libawt_lwawt.dylib 0x000000010dcad7e2 -[AWTView accessibilityHitTest:] + 179 2 AppKit 0x00007ff81322ff47 -[NSWindow(NSWindowAccessibility) accessibilityHitTest:] + 302 3 AppKit 0x00007ff812cfe5ad -[NSApplication(NSApplicationAccessibility) accessibilityHitTest:] + 285 4 AppKit 0x00007ff812cbf46b CopyElementAtPosition + 138 5 HIServices 0x00007ff8150cb505 _AXXMIGCopyElementAtPosition + 402 6 HIServices 0x00007ff8150ed194 _XCopyElementAtPosition + 355 7 HIServices 0x00007ff8150aa5a9 mshMIGPerform + 182 8 CoreFoundation 0x00007ff80f8483f8 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41 9 CoreFoundation 0x00007ff80f848337 __CFRunLoopDoSource1 + 536 10 CoreFoundation 0x00007ff80f846fb6 __CFRunLoopRun + 2749 11 CoreFoundation 0x00007ff80f845e7f CFRunLoopRunSpecific + 560 12 HIToolbox 0x00007ff8196d8766 RunCurrentEventLoopInMode + 292 13 HIToolbox 0x00007ff8196d8576 ReceiveNextEventCommon + 679 14 HIToolbox 0x00007ff8196d82b3 _BlockUntilNextEventMatchingListInModeWithFilter + 70 15 AppKit 0x00007ff8128d1293 _DPSNextEvent + 909 16 AppKit 0x00007ff8128d0114 -[NSApplication(NSEvent) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 1219 17 libosxapp.dylib 0x000000010d920653 -[NSApplicationAWT nextEventMatchingMask:untilDate:inMode:dequeue:] + 121 18 AppKit 0x00007ff8128c2757 -[NSApplication run] + 586 19 libosxapp.dylib 0x000000010d920431 +[NSApplicationAWT runAWTLoopWithApp:] + 165 20 libawt_lwawt.dylib 0x000000010dd047a1 +[AWTStarter starter:headless:] + 496 21 libosxapp.dylib 0x000000010d921f73 +[ThreadUtilities invokeBlockCopy:] + 15 22 Foundation 0x00007ff8105fd190 __NSThreadPerformPerform + 177 23 CoreFoundation 0x00007ff80f847ed1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17 24 CoreFoundation 0x00007ff80f847e80 __CFRunLoopDoSource0 + 157 25 CoreFoundation 0x00007ff80f847c4e __CFRunLoopDoSources0 + 212 26 CoreFoundation 0x00007ff80f8468a8 __CFRunLoopRun + 943 27 CoreFoundation 0x00007ff80f845e7f CFRunLoopRunSpecific + 560 28 libjli.dylib 0x000000010d3a989d CreateExecutionEnvironment + 381 29 libjli.dylib 0x000000010d3a5b45 JLI_Launch + 1253 30 java 0x0000000104dd1c15 main + 363 31 dyld 0x0000000205073310 start + 2432 ) Exception in thread "AppKit Thread" java.lang.NoSuchMethodError: accessibilityHitTest Hello from the actionPerformed() method! The button has been pressed.
运行的Java代码
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class MyFirstGUI implements ActionListener { public static void main(String[] args) { new MyFirstGUI(); // load self! } JFrame window = new JFrame("This is my first GUI program"); JButton button = new JButton("Push me!"); JTextField textField = new JTextField("Enter data here and press ENTER."); JTextArea textArea = new JTextArea("Info presented to user here."); public MyFirstGUI() // CONSTRUCTOR (called by the "new" loader) { System.out.println("Hi from MyFirstGUI constructor!"); // Build the GUI window.getContentPane().add(button, "North"); // top area window.getContentPane().add(textArea,"Center");// middle area window.getContentPane().add(textField,"South");// bottom area window.setLocation(500,0); // x,y in "pixels" y=0 is top of window window.setSize(500,500); // x,y button.setBackground(Color.red); textField.setBackground(Color.yellow); textArea.setEditable(false); // keep cursor out window.setVisible(true); // show it! window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); button.addActionListener(this); // call me when pushed! textField.addActionListener(this);// call me when ENTER key! } public void actionPerformed(ActionEvent ae) { if (ae.getSource() == button) { System.out.println("Button was pushed!"); } if (ae.getSource() == textField) { System.out.println("TextField had data entry!"); String input = textField.getText(); textField.setText(""); // clear! textArea.setText(input); } } }
解决方案
1. 解决JNI accessibility错误
该错误是M1 Mac上OpenJDK与macOS Ventura的兼容性问题,可通过添加JVM启动参数禁用辅助功能相关特性解决:
- Eclipse环境:打开运行配置,在
VM arguments中添加-Dapple.awt.accessibility.enabled=false - 终端运行:使用命令
java -Dapple.awt.accessibility.enabled=false MyFirstGUI
2. 解决按钮背景颜色不显示问题
Mac上Swing默认使用系统原生外观,会覆盖组件自定义背景色,可通过以下两种方式解决:
方式一:强制使用Swing跨平台外观
在构造函数开头添加代码:
try { UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); }
方式二:强制按钮绘制自定义背景
修改按钮设置代码:
button.setBackground(Color.red); button.setOpaque(true); button.setBorderPainted(false); // 若需要保留按钮边框,可删除此行
内容的提问来源于stack exchange,提问作者Hunter Marlette
相关产品推荐
相关产品推荐

