当有多个AWT-EventQueue线程时,如何选择一个线程?

 2023-01-19    404  

问题描述

我使用DLL注入和一些JNI Trickery成功地将自己的Java代码注入了运行的Oracle表单应用程序中. (Windows 7,32位,Oracle表格11,JRE Java 8)

我能够穿越组件树,并在某些基本的Java对象中查询和设置值,例如类oracle.forms.ui.VTextField

当有多个AWT-EventQueue线程时,如何选择一个线程?

中的对象

尝试模拟用户时,我被卡住了.单击oracle.apps.fnd.ui.Button

我尝试了2件事:

  1. 调用simulatePush类的方法AbstractButton class
  2. 调用activate PushButton类的方法

(这两个类位于Button的类层次结构中)

结果是相同的:
1.首先,它可以正常工作:当按钮是”搜索”按钮时,进行搜索并显示结果.
2.然后,它立即打破了应用程序,并用弹出式弹出式FRM-92100 Your connection to the Server was interrupted.

.

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

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

java.lang.securityexception:此键盘focusmanager不是
安装在当前线程的上下文中
java.awt.keyboardfocusmanager.checkcurrentkfmsecurity(未知来源)
在java.aw.aw.keyboardfocusmanager.getglobalfocusowner(未知来源)

java.awt.keyboardfocusmanager.processsynchronouslightweighttransfer(未知
来源)
sun.awt.windows.wcomponentpeer.processsynchronouslightweighttransfer(本机
方法)在sun.aw.windows.wcomponentpeer.requestfocus(未知)
来源)at Java.awt.component.requestfocushelper(未知来源)
java.awt.component.requestfocushelper(未知来源)
java.awt.component.requestfocus(未知来源)
oracle.forms.handler.uicommon.updatefocus(未知来源)
oracle.forms.handler.uicommon.setfvp(未知来源)at
oracle.forms.handler.uicommon.setfvp(未知来源)at
oracle.forms.handler.uicommon.onupdate(未知来源)
oracle.forms.handler.componentItem.onupdate(未知来源)at
oracle.forms.handler.javacontainer.onupdate(未知来源)
oracle.forms.handler.uicommon.onupdate(未知来源)
oracle.forms.engine.runform.onupdatehandler(未知来源)
oracle.forms.engine.runform.Runform.ProcessMessage(未知来源)
oracle.forms.engine.runform.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)at
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(未知
来源)at Java.aw.awt.eventqueue.dispatchevent(未知来源)
java.awt.eventdispatchthread.pumponeeventforfilters(未知来源)
在java.aw.awt.eventdispatchthread.pumpeventsforfilter(未知来源)
在java.aw.awt.eventdispatchthread.pumpeventsforhierarchy(未知
源)at Java.awt.eventdispatchthread.pumpevents(未知来源)
在java.aw.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.

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

推荐答案

经过大量实验和Google搜索使用EventQueue和ThreadGroup之类的关键字搜索,我终于找到了一个解决方案(在中为我工作类别,请注意您)./p>

我使用sun.awt.AppContext类.某些文档和来源在这里(grepcode.com)

  1. 使用getAppContexts方法获取运行AppContext的集合.
  2. 对于每个检索的AppContext,使用getThreadGroup方法获取他的ThreadGroup
  3. 使用ThreadGroup对象,使用getName方法.
  4. 当线程组的名称以http:表单应用程序的地址开头时,使用Object sun.awt.AppContext.EVENT_QUEUE_KEY检索Object属性,使用get get AppContext的方法.
  5. .

  6. 检索的对象是EventQueue.创建一个java.awt.event.InvocationEvent对象,将您的Runnable传递到CTOR,然后使用postEvent EventQueue的方法.
  7. 您的run方法将在正确的线程中执行.

备注:

  • 这个答案是一个特定的,对我有用,是通过Internet Explorer链接启动的Oracle表单应用程序的解决方案,并在Java.exe过程中运行.在这种情况下,这三个线程组如问题所示: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方法进行了测试.
  • 此处模拟的方法是invokeLater.对于invokeAndWait,postEvent呼叫需要更多代码.请参阅一些EventQueue类的来源,作为起点.

其他推荐答案

要获得正确的EDT线程,无论您的线程组如何,您都可以使用SunToolkit.targetToAppContext(Object target),并且对于参数,您可以将其馈送给您打算采取的awt组件.示例 source .

然后使用EventQueue eq = SunToolkit.getSystemEventQueueImplPP(appContext);

获取事件.

最后,使用可运行的可运行创建一个新的InvocationEvent,并在等式上调用后事件.

其他推荐答案

您应该能够扩展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 ;
    }

  }

我希望此代码对您有用.

问候

以上所述是小编给大家介绍的当有多个AWT-EventQueue线程时,如何选择一个线程?,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25834.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。