【发布时间】:2015-12-11 15:38:05
【问题描述】:
我使用 DLL 注入和一些 jni 技巧成功地将自己的 Java 代码注入到正在运行的 Oracle Forms 应用程序中。 (Windows 7、32 位、Oracle Forms 11、JRE Java 8)
我能够遍历组件树并在一些基本 Java 对象中查询和设置值,例如来自类 oracle.forms.ui.VTextField 的对象
我在尝试模拟用户点击 oracle.apps.fnd.ui.Button 时卡住了
我尝试了两件事:
- 调用
AbstractButton类的simulatePush方法 - 调用
PushButton类的activate方法
(这 2 个类在 Button 的类层次结构中)
结果相同:
1.起初,它工作正常:当按钮是“搜索”按钮时,搜索完成并显示结果。
2. 然后,它立即中断应用程序,并弹出一个说FRM-92100 Your connection to the Server was interrupted。
从那里,应用程序被挂起。
更新: 似乎导致与服务器断开连接的错误是:
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(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at 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(Unknown Source) at java.awt.EventQueue$2.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) 在 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(Unknown Source) 在 java.awt.EventDispatchThread.run(未知来源)
我的代码在这里: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)
【问题讨论】:
-
你试过
separateFrame="True"小程序参数吗? -
@dan 我无法更改服务器上的任何内容。不确定我是否理解您的建议。 Oracle Forms 应用程序(Oracle Application eBusiness Center)已经作为主窗口运行,是 Window Desktop 的子窗口。
标签: java java-native-interface event-dispatch-thread oracleforms