Search code examples
javawindowsswte4

Accessing the current processes handles


In our RCP 4 application we have had SWT exceptions thrown caused by there being no more handles available. This could be caused by a resource leak or by other 3rd party applications running. We are unable to reproduce this in development so we would like to log any information that could possibly help us fix this in the future.

We would like to get information about the handles. E.g. Total handles and what they are used for such as images, fonts, and composites.

I've been looking this up and I'm struggling to find anything on how this can be done in Java. We could execute command line for the information but that doesn't feel like a great way of doing it.

By Handles I'm referring to GDI Handles and User Handleson Windows.

How might this be done?

Handles

plugin.xml

<plugin>
   <extension
         id="product"
         point="org.eclipse.core.runtime.products">
      <product
            application="org.eclipse.e4.ui.workbench.swt.E4Application"
            name="appid">
         <property
               name="modelResourceHandler"
               value="bundleclass://a.model.resource.handler.ModelResourceHandler">
         </property>
      </product>
   </extension>
</plugin>

Solution

  • Eclipse Sleak can monitor the allocations made by SWT - the code is here.

    However this requires the SWT Display to be created with a DeviceData object enabling tracking. The standard E4Application doesn't do this.

    So to use this you need to use your own application class extending E4Application - something like:

    import org.eclipse.e4.ui.internal.workbench.swt.E4Application;
    
    import org.eclipse.swt.graphics.DeviceData;
    import org.eclipse.swt.widgets.Display;
    
    public class MyApplication extends E4Application
    {
      /** Enable tracking */
      private static final boolean TRACKING = true;
      /** Enable debug */
      private static final boolean DEBUG = false;
    
      public MyApplication()
      {
        super();
      }
    
      @Override
      public Display getApplicationDisplay()
      {
        Display current = Display.getCurrent();
        if (current == null)
         {
           if (TRACKING || DEBUG)
            {
              DeviceData data = new DeviceData();
              data.tracking = TRACKING;
              data.debug = DEBUG;
    
              current = new Display(data);
    
              if (data.tracking)
               {
                 Sleak sleak = new Sleak();
                 sleak.open();
               }
            }
           else
            {
              current = new Display();
            }
         }
    
        return super.getApplicationDisplay();
      }
    }
    

    You will need to declare this application in the plugin.xml:

       <extension
             id="application"
             name="Application name"
             point="org.eclipse.core.runtime.applications">
          <application
                cardinality="singleton-global"
                thread="main"
                visible="true">
             <run
                   class="your.package.MyApplication">
             </run>
          </application>
       </extension>
    

    Change your product declaration in the plugin.xml to use this application instead of org.eclipse.e4.ui.workbench.swt.E4Application. So something like:

       <extension
             id="product"
             point="org.eclipse.core.runtime.products">
          <product
                name="%product.name"
                application="my.plugin.application">
    

    As a further example the following is part of a tested, working plugin.xml from one of my e4 RCPs:

    <plugin>
       <extension
             id="application"
             name="%app.name"
             point="org.eclipse.core.runtime.applications">
          <application
                cardinality="singleton-global"
                thread="main"
                visible="true">
             <run
                   class="greg.music.e4.rcp.MusicApplication">
             </run>
          </application>
       </extension>
       <extension
             id="product"
             point="org.eclipse.core.runtime.products">
          <product
                name="%product.name"
                application="greg.music.e4.rcp.application">
                ...... properties
           </product>
       </extension>
    

    This is in a plugin with id greg.music.e4.rcp. This defines an application with id greg.music.e4.rcp.application and a product with id greg.music.e4.rcp.product