我使用 DLL 注入和一些 jni 技巧成功地将自己的 Java 代码注入到正在运行的 Oracle Forms 应用程序中。 (Windows 7、32 位、Oracle Forms 11、JRE Java 8)
我能够遍历组件树并查询和设置一些基本 Java 对象中的值,例如来自类的对象oracle.forms.ui.VTextField
当我尝试模拟用户点击时,我陷入了困境oracle.apps.fnd.ui.Button
我尝试了两件事:
- 打电话给
simulatePush
的方法AbstractButton
class
- 打电话给
activate
的方法PushButton
class
(这两个类位于类层次结构中Button
)
结果相同:
1. 首先,它工作正常:当按钮是“搜索”按钮时,搜索完成并显示结果。
2.然后,它立即中断该应用程序,并弹出一条消息FRM-92100 Your connection to the Server was interrupted
.
从那里,应用程序被挂起。
Update:看来导致与服务器断开连接的错误是:
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(本机方法) at
sun.reflect.NativeMethodAccessorImpl.invoke(来源未知)位于
sun.reflect.DelegatingMethodAccessorImpl.invoke(来源未知)位于
java.lang.reflect.Method.invoke(来源未知)位于
CustomAWT.run(CustomAWT.java:34)位于
java.awt.event.InitationEvent.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(来源未知)
我的代码在这里:CustomAWT.run(CustomAWT.java:34)
并被称为invokeLater
。问题可能是:当调用oracle.ewt.button.PushButton.activate
方法,我不在正确的美国东部时间。
使用 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.
所以,有THREE AWT-EventQueue
线程...现在的问题是:如何查询/检索正确的线程,以及如何使Runnable
传递给invokeLater
在“好线程”中运行(我猜好的线程是最后一个(AWT-EventQueue-2
)