Я успешно ввел свой собственный Java-код в запущенное приложение Oracle Forms, используя DLL Injection и некоторые jni-обманки. (Windows 7, 32 бита, Oracle Forms 11, JRE Java 8)
Я могу пересекать дерево Компонентов и запрашивать и устанавливать значения в некоторых базовых объектах Java, например, из класса oracle.forms.ui.VTextField
Я застреваю при попытке имитировать пользователя, нажмите oracle.apps.fnd.ui.Button
Я пробовал 2 вещи:
- вызывать метод
simulatePush
классаAbstractButton
- вызов метода
activate
классаPushButton
(2 класса находятся в иерархии классов для 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(Native Метод) на 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(Неизвестный источник)
Мой код здесь: 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.
Итак, есть потоки THREE AWT-EventQueue
... Вопрос теперь: как выполнить запрос/получить правильный и как сделать Runnable
пройденный invokeLater
для запуска в "Хорошей теме" (я думаю, что хороший является последним (AWT-EventQueue-2
)