gpt4 book ai didi

java - 当有多个 AWT-EventQueue 线程时如何选择

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:01:39 25 4
gpt4 key购买 nike

我使用 DLL 注入(inject)和一些 jni 技巧成功地将我自己的 Java 代码注入(inject)到正在运行的 Oracle Forms 应用程序中。 (Windows 7、32 位、Oracle Forms 11、JRE Java 8)

我能够遍历组件树并在一些基本 Java 对象中查询和设置值,例如类 oracle.forms.ui.VTextField

我在尝试模拟用户点击 oracle.apps.fnd.ui.Button 时卡住了

我尝试了两件事:

  1. 调用AbstractButton类的simulatePush方法
  2. 调用PushButton类的activate方法

(这 2 个类在 Button 的类层次结构中)

结果相同: 1. 起初,它工作正常:当按钮是“搜索”按钮时,完成搜索并显示结果。 2. 然后,它会立即中断应用程序,并弹出一个提示 FRM-92100 Your connection to the Server was interrupted

从那里,应用程序被挂起。

更新:似乎导致与服务器断开连接的错误是:

java.lang.SecurityException: this KeyboardFocusManager is not installed in the current thread's context at java.awt.KeyboardFocusManager.checkCurrentKFMSecurity(Unknown Source) at java.awt.KeyboardFocusManager.getGlobalFocusOwner(Unknown Source) at java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer(Unknown Source) at sun.awt.windows.WComponentPeer.processSynchronousLightweightTransfer(Native Method) at sun.awt.windows.WComponentPeer.requestFocus(Unknown Source) at java.awt.Component.requestFocusHelper(Unknown Source) at java.awt.Component.requestFocusHelper(Unknown Source) at java.awt.Component.requestFocus(Unknown Source) at oracle.forms.handler.UICommon.updateFocus(Unknown Source) at oracle.forms.handler.UICommon.setFVP(Unknown Source) at oracle.forms.handler.UICommon.setFVP(Unknown Source) at oracle.forms.handler.UICommon.onUpdate(Unknown Source) at oracle.forms.handler.ComponentItem.onUpdate(Unknown Source) at oracle.forms.handler.JavaContainer.onUpdate(Unknown Source) at oracle.forms.handler.UICommon.onUpdate(Unknown Source) at oracle.forms.engine.Runform.onUpdateHandler(Unknown Source) at oracle.forms.engine.Runform.processMessage(Unknown Source) at oracle.forms.engine.Runform.processSet(Unknown Source) at oracle.forms.engine.Runform.onMessageReal(Unknown Source) at oracle.forms.engine.Runform.onMessage(Unknown Source) at oracle.forms.engine.Runform.processEventEnd(Unknown Source) at oracle.ewt.lwAWT.LWComponent.redispatchEvent(Unknown Source) at oracle.ewt.lwAWT.LWComponent.processEvent(Unknown Source) at oracle.ewt.button.PushButton.activate(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at CustomAWT.run(CustomAWT.java:34) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEventImpl(Unknown Source) at java.awt.EventQueue.access$400(Unknown Source) at java.awt.EventQueue$2.run(Unknown Source) at java.awt.EventQueue$2.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source)

我的代码在这里:CustomAWT.run(CustomAWT.java:34) 并使用 invokeLater 调用。问题可能是:调用 oracle.ewt.button.PushButton.activate 方法时,我不在正确的 EDT 中。

在 Java 控制台中使用“列出线程”,我得到:

Dump thread list ...
Group main,ac=30,agc=2,pri=10
main,5,alive
traceMsgQueueThread,5,alive,daemon
Timer-0,5,alive
Java Plug-In Pipe Worker Thread (Client-Side),5,alive,daemon
AWT-Shutdown,5,alive
AWT-Windows,6,alive,daemon
AWT-EventQueue-0,6,alive
SysExecutionTheadCreator,5,alive,daemon
CacheMemoryCleanUpThread,5,alive,daemon
CacheCleanUpThread,5,alive,daemon
Browser Side Object Cleanup Thread,5,alive
JVM[id=0]-Heartbeat,5,alive,daemon
Windows Tray Icon Thread,5,alive
Thread-13,5,alive
Group Plugin Thread Group,ac=3,agc=0,pri=10
AWT-EventQueue-1,6,alive
TimerQueue,5,alive,daemon
ConsoleWriterThread,6,alive,daemon
Group http://xxxx.xxxx.xxxxx.xx:8001/OA_JAVA/-threadGroup,ac=13,agc=0,pri=4
Applet 1 LiveConnect Worker Thread,4,alive
AWT-EventQueue-2,4,alive
thread applet-oracle/apps/fnd/formsClient/FormsLauncher.class-1,4,alive
Applet 2 LiveConnect Worker Thread,4,alive
thread applet-oracle.forms.engine.Main-2,4,alive
Forms-StreamMessageReader,4,alive
Forms-StreamMessageWriter,4,alive
HeartBeat,4,alive
Busy indicator,1,alive,daemon
TaskScheduler timer,4,alive
CursorIdler,4,alive
Thread-14,4,alive
Flush Queue,4,alive
Done.

所以,有三个 AWT-EventQueue 线程...现在的问题是:如何查询/检索正确的线程,以及如何生成 Runnable传递给invokeLater在“好线程”中运行(我猜好线程是最后一个(AWT-EventQueue-2)

最佳答案

经过大量实验并使用 EventQueueThreadGroup 等关键字进行谷歌搜索后,我终于找到了解决方案(在 Works For Me类别,请注意)。

我使用 sun.awt.AppContext 类。一些文档和来源 here (grepcode.com)

  1. 使用 getAppContexts 方法获取正在运行的 AppContext 的集合。
  2. 对于每个检索到的 AppContext,使用 getThreadGroup 方法获取他的 ThreadGroup
  3. 对于ThreadGroup对象,使用getName方法。
  4. 当线程组的名称以您的表单应用程序的 http: 地址开头时,检索具有键名 sun.awt.AppContext.EVENT_QUEUE_KEYObject 属性,使用 AppContextget 方法。
  5. 检索到的对象是一个EventQueue。创建一个 java.awt.event.InvocationEvent 对象,将您的 Runnable 传递给 CTOR,并使用 EventQueue< 的 postEvent 方法
  6. 您的run 方法将在正确的线程中执行。

备注:

  • 这个答案是一个特定的、对我有用的解决方案,适用于通过 Internet Explorer 链接启动并在 java.exe 进程中运行的 Oracle Forms 应用程序。在这种情况下,3 个线程组如问题所示:mainPlugin Thread Grouphttp://xxxx.xxxx.xxxxx.xx :8001/OA_JAVA/-threadGroup 你的里程可能会有所不同。
  • 如果您不使用全反射,而是导入 sun.awt.AppContext,编译器可能会以 warning: sun.awt.AppContext is Sun proprietary 的形式发出警告API,可能会在未来的版本中删除这不是很酷,但我暂时会接受。
  • run方法中,我用oracle.ewt.lwAWT.AbstractButtonsimulatePush方法测试OK。
  • 这里模拟的方法是invokeLater。对于 invokeAndWait,需要围绕 postEvent 调用编写更多代码。查看 EventQueue 类的一些来源,作为起点。

关于java - 当有多个 AWT-EventQueue 线程时如何选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34227178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com