我成功地在运行中的Oracle窗体应用程序中注入了自己的Java代码,使用了DLL注入和一些jni技巧。(Windows 7,32位,Oracle Forms 11,JRE Java 8)
我能够遍历组件树,并在一些基本的Java对象中查询和设置值,例如来自类oracle.forms.ui.VTextField的值。
当我试图模拟用户点击oracle.apps.fnd.ui.Button时,我被困住了
我试了两件事:
simulatePush类的AbstractButton方法activate类的PushButton方法(这两个类位于Button的类层次结构中)
结果是一致的: 1。首先,它工作良好:当按钮是“搜索”按钮时,搜索完成并显示结果。2.然后,它会立即中断应用程序,弹出的名称为FRM-92100 Your connection to the Server was interrupted。
从那里起,申请就挂起了。
更新:似乎导致与服务器断开连接的错误是:
java.awt.KeyboardFocusManager.checkCurrentKFMSecurity(Unknown :这个KeyboardFocusManager没有安装在当前线程的上下文中--在java.awt.KeyboardFocusManager.getGlobalFocusOwner(Unknown Source)、在java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer(Unknown Source)、在java.awt.KeyboardFocusManager.processSynchronousLightweightTransfer(Unknown Source)、在sun.awt.windows.WComponentPeer.processSynchronousLightweightTransfer(Native Source)、在sun.awt.windows.WComponentPeer.requestFocus(Unknown Source)、在java.awt.Component.requestFocusHelper(未知源)、在java.awt.Component上。(未知源)在oracle.forms.handler.UICommon.updateFocus(Unknown源的java.awt.Component.requestFocus(未知源)在oracle.forms.handler.UICommon.setFVP(未知源)在oracle.forms.handler.UICommon.setFVP(未知源)在oracle.forms.handler.ComponentItem.onUpdate(Unknown源(在oracle.forms.handler.JavaContainer.onUpdate(Unknown源)oracle.forms.handler.UICommon.onUpdate(Unknown来源)在oracle.forms.engine.Runform.onUpdateHandler(Unknown来源)在oracle.forms.engine.Runform.processMessage(Unknown来源)在oracle.forms.engine.Runform.processSet(Unknown来源)在oracle.forms.engine.Runform.onMessageReal(Unknown来源)在oracle.forms.engine.Runform.onMessage(未知来源在oracle.forms.engine.Runform.processEventEnd(Unknown来源)在甲骨文。oracle.ewt.lwAWT.LWComponent.processEvent(Unknown源(未知源)、sun.reflect.NativeMethodAccessorImpl.invoke0(Native方法(未知源)、sun.reflect.NativeMethodAccessorImpl.invoke(Unknown源( sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown源)、java.lang.reflect.Method.invoke(未知源)、CustomAWT.run(CustomAWT.java:34)(未知来源)在java.awt.EventQueue$2.运行(未知源)在java.awt.EventQueue$2.运行(未知源)在java.security.AccessController.doPrivileged(Native方法运行(未知源)在java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown来源)在java.awt.EventQueue.dispatchEvent(未知源)在java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown源)在java.awt.EventDispatchThread.pumpEventsForFilter(Unknown源)在java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown源)在java.awt.EventDispatchThread.pumpEvents(Unknown源)在java.awt.EventDispatchThread.pumpEvents(Unknown源)在java.awt.EventDispatchThread.run(未知源)
我的代码在这里:CustomAWT.run(CustomAWT.java:34),并与invokeLater一起调用。问题可能是:当调用oracle.ewt.button.PushButton.activate方法时,I不在正确的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) )。
发布于 2015-12-21 17:21:25
经过大量的实验和谷歌搜索的关键字,如EventQueue和ThreadGroup,我终于找到了一个解决方案(在为我的工作类别,请注意)。
我使用sun.awt.AppContext类。一些文档和源这里 (grepcode.com)
AppContext方法获取正在运行的getAppContexts的集合。AppContext,使用getThreadGroup方法获取他的ThreadGroup。ThreadGroup对象,使用getName方法。Object的get方法检索键名为sun.awt.AppContext.EVENT_QUEUE_KEY的AppContext属性。EventQueue。创建一个java.awt.event.InvocationEvent对象,将您的Runnable传递给CTOR,并使用EventQueue的postEvent方法。run方法将在正确的线程中执行。备注:
main、Plugin Thread Group和http://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的形式发出警告,这不是很酷,但我暂时会接受这一点。run方法中,我使用oracle.ewt.lwAWT.AbstractButton的simulatePush方法测试OK。invokeLater。对于invokeAndWait,围绕postEvent调用需要更多的代码。作为起点,请参阅EventQueue类的一些源代码。发布于 2017-10-10 10:57:46
要获得正确的EDT线程,而不管您的线程组是什么,您可以使用SunToolkit.targetToAppContext(Object target),对于参数,可以将您想要操作的AWT组件提供给它。例如来源。
然后使用EventQueue获取EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);
最后,使用可运行的InvocationEvent创建一个新的postEvent,并在EQ上调用postEvent。
发布于 2015-12-17 10:46:09
您应该能够扩展VButton类,您的类定义应该如下所示:
public class AmazingButton extends VButton implements FocusListener然后需要一个init类,如下所示:
public void init(IHandler handler)
{
m_handler = handler;
super.init(handler);
addMouseListener(new ButtonMouseAdapter());
addFocusListener(this);
} 然后,您需要实现侦听器,并在其中做一些事情:
public void focusGained(FocusEvent e)
{
if (e.getComponent() == this)
{
// put the focus on the component
e.getComponent().requestFocus();
bFocus = true ;
}
}
public void focusLost(FocusEvent e)
{
bFocus = false ;
}
/**
* Private class to handle user mouse actions
*/
class ButtonMouseAdapter extends MouseAdapter
{
/**
* User moved the mouse over the button
*/
public void mouseEntered(MouseEvent me)
{
bFocus=true ;
mouseON();
}
/**
* User moved the mouse out of the button
*/
public void mouseExited(MouseEvent me)
{
bFocus=false ;
mouseOFF();
}
/**
* User moved the mouse out of the button
*/
public void mousePressed(MouseEvent me)
{
bPressed = true ;
}
/**
* User moved the mouse out of the button
*/
public void mouseReleased(MouseEvent me)
{
bPressed = false ;
}
}我希望这个代码对你有用。
问候
https://stackoverflow.com/questions/34227178
复制相似问题