java – 如何选择一个AWT-EventQueue线程,当有几个

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

我可以遍历组件树,并查询和设置一些基本Java对象中的值,例如来自class oracle.forms.ui.VTextField的值

当我试图模拟用户点击oracle.apps.fnd.ui.Button时,我被卡住了

我试过2件事情:

>调用AbstractButton类的simulatePush方法
>调用PushButton类的activate方法

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

结果相同:
首先,它工作正常:当按钮是“搜索”按钮时,搜索完成并显示结果.
然后,它立即中断应用程序,弹出一声说FRM-92100您与服务器的连接中断.

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

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

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

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

解决方法

经过大量的实验和谷歌搜索与关键字,如EventQueue和ThreadGroup我终于找到一个解决方案(在我的工作类别,介意你).

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

>使用getAppContexts方法获取正在运行的AppContext的集合.
>对于每个检索的AppContext,使用getThreadGroup方法获取他的ThreadGroup.
>使用ThreadGroup对象,使用getName方法.
>当Thread组的名称以您的Forms Application的http:地址开头时,使用AppContext的get方法检索带有名称sun.awt.AppContext.EVENT_QUEUE_KEY的Object属性.
>检索到的对象是一个EventQueue.创建一个java.awt.event.InvocationEvent对象,将您的Runnable传递给CTOR,并使用EventQueue的postEvent方法.
>你的run方法将在正确的线程中执行.

备注:

>这个答案是一个具体的,适用于我,通过Internet Explorer链接启动的Oracle Forms应用程序的解决方案,并在java.exe进程中运行.在这种情况下,3个线程组如问题所示:main,Plugin Thread Group和http://xxxx.xxxx.xxxxx.xx:8001 / OA_JAVA / -threadGroup您的里程可能会有所不同.>如果不使用完全反射,而是导入sun.awt.AppContext,编译器可能会以警告形式发出警告:sun.awt.AppContext是Sun专有API,可能会在将来的版本中删除这不是很很酷,但我会和那个一起生活的,暂时的.>在run方法中,我使用oracle.ewt.lwAWT.AbstractButton的simulatePush方法测试了OK.>这里仿真的方法invokelater.对于invokeAndWait,postEvent调用需要更多的代码.查看EventQueue类的一些来源,作为起点.

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...