有多个线程时如何选择AWT-EventQueue线程 [英] How to choose an AWT-EventQueue thread, when there are several of them

查看:87
本文介绍了有多个线程时如何选择AWT-EventQueue线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I successfully injected my own Java code in a running Oracle Forms application, using DLL Injection and some jni trickery. (Windows 7, 32 bits, Oracle Forms 11, JRE Java 8)

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

I am able to traverse the tree of Components and to query and set values in some basic Java objects, such as those from class oracle.forms.ui.VTextField

当尝试模拟用户点击oracle.apps.fnd.ui.Button

我尝试了两件事:

  1. 调用AbstractButton类的simulatePush方法
  2. 调用PushButton类的activate方法
  1. call the simulatePush method of the AbstractButton class
  2. call the activate method of the PushButton class

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

(the 2 classes are in the class hierarchy for Button)

结果相同: 1.首先,它工作正常:当按钮是搜索"按钮时,将完成搜索并显示结果. 2.然后,它立即中断应用程序,并显示一个弹出窗口FRM-92100 Your connection to the Server was interrupted.

Results were identical: 1. At first, it works fine: when the button is a "Search" button, the search is done and the results are displayed. 2. Then, it immediately breaks the application, with a pop-up saying FRM-92100 Your connection to the Server was interrupted.

从那里挂起应用程序.

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

Update: It seems that the error which cause a disconnection from the Server is:

java.lang.SecurityException:此KeyboardFocusManager不是 安装在当前线程的上下文中 java.awt.KeyboardFocusManager.checkCurrentKFMSecurity(未知源) 在java.awt.KeyboardFocusManager.getGlobalFocusOwner(未知来源) 在 java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer(未知 来源) sun.awt.windows.WComponentPeer.processSynchronousLightweightTransfer(本机 方法)位于sun.awt.windows.WComponentPeer.requestFocus(未知 源)位于java.awt.Component.requestFocusHelper(未知源)位于 java.awt.Component.requestFocusHelper(未知源),网址为 java.awt.Component.requestFocus(未知源),网址为 oracle.forms.handler.UICommon.updateFocus(未知源)位于 oracle.forms.handler.UICommon.setFVP(未知源)位于 oracle.forms.handler.UICommon.setFVP(未知源)位于 oracle.forms.handler.UICommon.onUpdate(未知源),位于 oracle.forms.handler.ComponentItem.onUpdate(未知源)位于 oracle.forms.handler.JavaContainer.onUpdate(未知源) oracle.forms.handler.UICommon.onUpdate(未知源),位于 oracle.forms.engine.Runform.onUpdateHandler(未知源)位于 oracle.forms.engine.Runform.processMessage(未知源)位于 oracle.forms.engine.Runform.processSet(未知源)位于 oracle.forms.engine.Runform.onMessageReal(未知源)位于 oracle.forms.engine.Runform.onMessage(未知源)位于 oracle.forms.engine.Runform.processEventEnd(未知源)位于 oracle.ewt.lwAWT.LWComponent.redispatchEvent(未知源)位于 oracle.ewt.lwAWT.LWComponent.processEvent(未知源)位于 oracle.ewt.button.PushButton.activate(来源未知) sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)位于 sun.reflect.NativeMethodAccessorImpl.invoke(未知来源)位于 sun.reflect.DelegatingMethodAccessorImpl.invoke(来源未知) java.lang.reflect.Method.invoke(来源未知) CustomAWT.run(CustomAWT.java:34)位于 java.awt.event.InvocationEvent.dispatch(未知源)位于 java.awt.EventQueue.dispatchEventImpl(未知源)在 java.awt.EventQueue.access $ 400(未知源) java.awt.EventQueue $ 2.run(未知源) java.awt.EventQueue $ 2.run(未知源) java.security.AccessController.doPrivileged(本机方法),位于 java.security.AccessControlContext $ 1.doIntersectionPrivilege(未知 源)位于java.awt.EventQueue.dispatchEvent(未知源)位于 java.awt.EventDispatchThread.pumpOneEventForFilters(未知来源) 在java.awt.EventDispatchThread.pumpEventsForFilter(未知来源) 在java.awt.EventDispatchThread.pumpEventsForHierarchy(未知 源)位于java.awt.EventDispatchThread.pumpEvents(未知源) 在java.awt.EventDispatchThread.pumpEvents(未知来源)处 java.awt.EventDispatchThread.run(未知来源)

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中.

My code is here: CustomAWT.run(CustomAWT.java:34) and is called with invokeLater. Problem is probably: when calling the oracle.ewt.button.PushButton.activate method, I am NOT in the right EDT.

在Java控制台中使用列表线程",我得到了:

Using "List Threads" in the Java Console, I got:

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)

So, there is THREE AWT-EventQueue threads... Question is now: How to query/retrieve the right one, and how to make the Runnable passed to invokeLater to run in the "Good Thread" (I guess that the good one is the last one (AWT-EventQueue-2)

推荐答案

经过大量的实验和Google搜索,例如EventQueueThreadGroup之类的关键字,我终于找到了解决方案(在 Works for Me中类别,请注意).

After a lot of experimentation and google searches with keywords like EventQueue and ThreadGroup I have finally found a solution (in the Works For Me category, mind you).

我使用sun.awt.AppContext类.一些文档和资源这里(grepcode.com)

I use the sun.awt.AppContext class. Some documentation and sources here (grepcode.com)

  1. 使用getAppContexts方法获取正在运行的AppContext的集合.
  2. 对于每个检索到的AppContext,请使用getThreadGroup方法获取其ThreadGroup.
  3. 对于ThreadGroup对象,请使用getName方法.
  4. 当线程组的名称以Forms Application的http:地址开头时,请使用AppContextget方法检索键名称为sun.awt.AppContext.EVENT_QUEUE_KEYObject属性.
  5. 检索到的对象是EventQueue.创建一个java.awt.event.InvocationEvent对象,将您的Runnable传递给CTOR,并使用EventQueuepostEvent方法.
  6. 您的run方法将在正确的线程中执行.
  1. Get a Collection of the running AppContext's using the getAppContexts method.
  2. For each retrieved AppContext, get his ThreadGroup using the getThreadGroup method.
  3. With the ThreadGroup object, Use the getName method.
  4. When the name of the Thread Group starts with the http: address of your Forms Application, retrieve the Object property with key name sun.awt.AppContext.EVENT_QUEUE_KEY, using the get method of AppContext.
  5. The retrieved object is an EventQueue. Create an java.awt.event.InvocationEvent object, passing your Runnable to the CTOR, and use the postEvent method of EventQueue.
  6. Your run method will be executed in the right thread.

备注:

  • 此答案是特定的,对我有用的,通过Internet Explorer链接启动并在java.exe进程中运行的Oracle Forms Application解决方案.在这种情况下,三个线程组将显示为问题:mainPlugin Thread Grouphttp://xxxx.xxxx.xxxxx.xx:8001/OA_JAVA/-threadGroup.您的里程可能会有所不同.
  • 如果您不使用全反射,而是导入sun.awt.AppContext,则编译器可能会以warning: sun.awt.AppContext is Sun proprietary API and may be removed in a future release的形式发出警告,这不是很酷,但是我暂时会接受.
  • li>
  • run方法中,我使用oracle.ewt.lwAWT.AbstractButtonsimulatePush方法测试了OK.
  • 此处模拟的方法是invokeLater.对于invokeAndWait,在postEvent调用周围需要更多代码.作为起点,请参见EventQueue类的一些资料.
  • This answer is a specific, works for me, solution for an Oracle Forms Application launched via an Internet Explorer link, and running in a java.exe process. In that situation, the 3 Thread Groups are as shown in the question: main, Plugin Thread Group, and http://xxxx.xxxx.xxxxx.xx:8001/OA_JAVA/-threadGroup Your mileage may vary.
  • If you don't use full reflection, but instead do import sun.awt.AppContext, the compiler may emit warnings in the form warning: sun.awt.AppContext is Sun proprietary API and may be removed in a future release That's not very cool, but I will live with that, for the time being.
  • In the run method, I tested OK with the simulatePush method of oracle.ewt.lwAWT.AbstractButton.
  • The method emulated here is invokeLater. For invokeAndWait, more code is needed around the postEvent call. See some sources for the EventQueue class, as a starting point.

这篇关于有多个线程时如何选择AWT-EventQueue线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆