Thursday, April 23, 2015

mksock command

I was disappointed to discover Mac OS X 10.9.5 lacks an mksock command, in order to create a Unix domain socket. Now, usually applications will create these as needed, yet sometimes it is useful to create one manually (such as for testing purposes.) So I wrote my own mksock command, code is below:

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

int main(int argc, char **argv) {
        if (argc < 2) {
                fprintf(stderr, "usage: mksock PATH...\n");
                return 1;
        }
        struct sockaddr_un addr;
        int rc = 0;
        for (int i = 1; i < argc; i++) {
                memset(&addr, 0, sizeof(addr));
                addr.sun_family = AF_UNIX;
                strncpy(addr.sun_path, argv[i], sizeof(addr.sun_path));
                addr.sun_path[sizeof(addr.sun_path)-1] = 0;
                const int fd = socket(PF_UNIX, SOCK_STREAM, 0);
                if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) { 
                        fprintf(stderr, "mksock: %s: %s\n", addr.sun_path, strerror(errno));
                        rc = 1;
                }
                close(fd);
        }
 return rc;
}

Saturday, June 8, 2013

SvgClean.js

If I edit an SVG file in InkScape and then save it, InkScape pollutes the SVG with all manner of InkScape specific attributes and elements. It also needlessly adds RDF and CreativeCommons and Dublin Core metadata, even when there is no real metadata to export. If I use "Plain SVG" instead of "Inkscape SVG" as the save file type, it excludes the sodipodi and inkscape namespace attributes, but it still adds the needless metadata. So this is a script which removes:
  • All comments, processing instructions, etc.
  • All attributes and elements from non-SVG namespaces.
  • Metadata and defs elements if they have no content after the above.
  • Pretty-printing of resultant XML
nsXMLNS = "http://www.w3.org/2000/xmlns/";
nsSVG = "http://www.w3.org/2000/svg";

// Converts XML document to string
xmlToString = function(doc) {
   var domreg = org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance();
   var ls = domreg.getDOMImplementation("LS");
   var w = ls.createLSSerializer();
   w.getDomConfig().setParameter("format-pretty-print", true);
   var lsout = ls.createLSOutput();
   var out = new java.io.StringWriter();
   lsout.setCharacterStream(out);
   w.write(doc, lsout);
   out.close();
   return "" + out.toString();
};

// Instantiate document builder
getDocBuilder = function() {
   var dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
   dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
   dbf.setNamespaceAware(true);
   return dbf.newDocumentBuilder();
};

// Load XML file from disk into memory
loadXMLFile = function(file) {
   var inp = new java.io.File(file);
   return getDocBuilder().parse(inp);
};

// Retrieve child nodes of given node. Non-live.
getKids = function(node) {
   var kids = [];
   for (var i = 0; i < node.childNodes.length; i++)
      kids.push(node.childNodes.item(i));
   return kids;
};

// Remove all comments, processing instructions, document types
cleanDocument1 = function(node) {
   var toRemove = [];
   var Node = org.w3c.dom.Node;
   for (var i = 0; i < node.childNodes.length; i++) {
      var k = node.childNodes.item(i);
      if (k.nodeType === Node.COMMENT_NODE ||
              k.nodeType === Node.DOCUMENT_TYPE_NODE ||
              k.nodeType === Node.PROCESSING_INSTRUCTION_NODE)
         toRemove.push(k);
   }
   for (var i in toRemove)
      toRemove[i].parentNode.removeChild(toRemove[i]);
   var kids = getKids(node);
   for (var i in kids)
      cleanDocument1(kids[i]);
};

// Removes all elements and attributes in non-SVG namespace
cleanDocument2 = function(node) {
   var Node = org.w3c.dom.Node;
   if (node.nodeType === Node.ELEMENT_NODE) {
      if (!nsSVG.equals(node.namespaceURI)) {
         node.parentNode.removeChild(node);
         return;
      }
      var attrs = node.attributes;
      var toRemove = [];
      for (var i = 0; i < attrs.length; i++) {
         var attr = attrs.item(i);
         if (attr.namespaceURI !== null &&
                 !nsXMLNS.equals(attr.namespaceURI) &&
                 !nsSVG.equals(attr.namespaceURI))
            toRemove.push(attr);
      }
      for (var i in toRemove)
         node.removeAttributeNode(toRemove[i]);
   }
   var kids = getKids(node);
   for (var i in kids)
      cleanDocument2(kids[i]);
};

// Remove empty metadata and defs attributes
cleanDocument3 = function(node) {
   var Node = org.w3c.dom.Node;
   if (node.nodeType === Node.ELEMENT_NODE) {
      if ("metadata".equals(node.localName) ||
              "defs".equals(node.localName)) {
         var k = 0;
         for (var i = 0; i < node.childNodes.length; i++)
            if (node.childNodes.item(i).nodeType === Node.ELEMENT_NODE)
               k++;
         if (k === 0) {
            node.parentNode.removeChild(node);
            return;
         }
      }
   }
   var kids = getKids(node);
   for (var i in kids)
      cleanDocument3(kids[i]);
};

// Remove non-SVG XMLNS declarations
cleanDocument4 = function(node) {
   var Node = org.w3c.dom.Node;
   if (node.nodeType === Node.ELEMENT_NODE) {
      var attrs = node.attributes;
      var toRemove = [];
      for (var i = 0; i < attrs.length; i++) {
         var attr = attrs.item(i);
         if (attr.namespaceURI !== null &&
                 nsXMLNS.equals(attr.namespaceURI) &&
                 !nsSVG.equals(attr.value))
            toRemove.push(attr);
      }
      for (var i in toRemove)
         node.removeAttributeNode(toRemove[i]);
   }
   var kids = getKids(node);
   for (var i in kids)
      cleanDocument4(kids[i]);
};

try {
   var doc = loadXMLFile(arguments[0]);
   if (!nsSVG.equals(doc.documentElement.namespaceURI) ||
           !"svg".equals(doc.documentElement.localName))
      throw "Not an SVG document";
   cleanDocument1(doc);
   cleanDocument2(doc);
   cleanDocument3(doc);
   cleanDocument4(doc);
   println(xmlToString(doc));
} catch (e) {
   if (e.rhinoException)
      e.rhinoException.printStackTrace();
   else if (e.javaException)
      e.javaException.printStackTrace();
   else
      println(e);
}

XML pretty-printing and XSLT processing in Rhino JavaScript

One of my favourite utilities on Linux is xmllint, in particular xmllint --format. Ugly, unreadable XML in, nice and pretty XML out. Unfortunately, xmllint is not usually installed on Windows. Oh, I could just download the Windows executable. Or, I could write my own little XML pretty printer in JavaScript (Mozilla Rhino bundled with the JDK). Well, the advantage of this approach, is that it can be used on any platform where the JDK is installed, even when you are not allowed to compile or install other software.
xmlToString = function(doc) {
   var domreg = org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance();
   var ls = domreg.getDOMImplementation("LS");
   var w = ls.createLSSerializer();
   w.getDomConfig().setParameter("format-pretty-print", true);
   var lsout = ls.createLSOutput();
   var out = new java.io.StringWriter();
   lsout.setCharacterStream(out);
   w.write(doc, lsout);
   out.close();
   return "" + out.toString();
};

try {
   var inp = new java.io.File(arguments[0]);
   var dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
   dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
   dbf.setNamespaceAware(true);
   var db = dbf.newDocumentBuilder();
   var doc = db.parse(inp);
   println(xmlToString(doc));
} catch (e) {
  if (e.javaException)
    e.javaException.printStackTrace();
  throw e;
}
Another tool I often use is xsltproc, for applying XSLT stylesheets. Here is a JavaScript equivalent for that:
xmlToString = function(doc) {
   var domreg = org.w3c.dom.bootstrap.DOMImplementationRegistry.newInstance();
   var ls = domreg.getDOMImplementation("LS");
   var w = ls.createLSSerializer();
   w.getDomConfig().setParameter("format-pretty-print", true);
   var lsout = ls.createLSOutput();
   var out = new java.io.StringWriter();
   lsout.setCharacterStream(out);
   w.write(doc, lsout);
   out.close();
   return "" + out.toString();
};

getDocBuilder = function() {
   var dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
   dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
   dbf.setNamespaceAware(true);
   return dbf.newDocumentBuilder();
};

loadXMLFile = function(file) {
   var inp = new java.io.File(file);
   return getDocBuilder().parse(inp);
};

applyXSLT = function(doc, xslt) {
   var dsDoc = new javax.xml.transform.dom.DOMSource(doc);
   var dsXSLT = new javax.xml.transform.dom  .DOMSource(xslt);
   var tf = javax.xml.transform.TransformerFactory.newInstance();
   var xf = tf.newTransformer(dsXSLT);
   var out = getDocBuilder().newDocument();
   var drOut = new javax.xml.transform.dom.DOMResult(out);
   xf.transform(dsDoc, drOut);
   return out;
};

try {
   var doc = loadXMLFile(arguments[0]);
   var xslt = loadXMLFile(arguments[1]);
   var out = applyXSLT(doc, xslt);
   println(xmlToString(out));
} catch (e) {
   if (e.javaException)
      e.javaException.printStackTrace();
   throw e;
}

Tuesday, April 23, 2013

Merging JaCoCo coverage reports across several modules in a Maven multi-module project.



I tried to follow the instructions in this article: http://java.dzone.com/articles/jacoco-maven-multi-module. However, what I don’t like, is your “coverage” module has to hardcode references to all the modules in your multi-module project. That means, that when you need to add a new module, you must now update two places – both the parent pom.xml, and the coverage pom.xml. People are likely to forget to do the later, especially if a new developer is working on your project.

My solution is here. Basically, rather than hard-coding references to the  other modules, we load the parent pom.xml and extract the list from the <modules> tag. Two provisos: (1) this will not work for multi-level multi-module projects; (2) this assumes you stick to Maven standard directory structures. With some code changes, you could overcome those provisos.

Yet another ANTDOC tool



I wanted a tool to generating documentation from ANT projects. I had a look at AntDoc (http://antdoc.free.fr) and was not entirely happy with it, so I decided to write my own. It is far simpler, but it does exactly what I want. See attached antdoc.zip.

Mystery: Why does java.lang.Class.forName(“java.security.AccessController”) return null in jrunscript?



Solution: Mozilla Rhino supports a concept called “class shutters” which enable you to block scripts from accessing any class. The JS implementation that comes with the JDK installs one called com.sun.script.javascript.RhinoClassShutter, which blocks access to java.security.AccessController. If you need to call it from JavaScript, you will need to write a class in Java to call it on your behalf. Be aware, that this is done for security reasons, so you need to ensure you understand the security implications before you do so.

Friday, March 8, 2013

Why does Netbeans beep? Debugging with a custom AWT Toolkit



I use Javascript to remote control Netbeans using a modified version of JRUNSCRIPTIN (http://kenai.com/projects/jrunscriptin). Most of the time my code works, but sometimes I was not getting the results I expected. When this happened, Netbeans would beep at me while performing certain editor actions. I was wondering if the beeping was related to why my code didn’t work? I was pretty sure the beeping was from java.awt.Toolkit.getDefaultToolkit().beep(). So I thought, let’s attach a debugger, see who is calling that. Well, it was a bit tricky to get Netbeans to debug itself. Possibly, I could have started two instances of Netbeans and used one to debug another – Netbeans won’t do this by default, but there is a way (http://wiki.netbeans.org/FaqAlternateUserdir). However, my code which remote controls Netbeans would get confused if more than one Netbeans was running, so I decided to look for another debugger.

I could have tried Eclipse, I could have tried JDeveloper. I’ve got both on my system, but possibly not the latest versions, so I might have had to muck around to get them to work with JDK7. Then I thought – there is a debugger that comes with the JDK – jdb. Let me try that. First I start Netbeans with debug on:

C:\Program Files\NetBeans 7.3 Beta 2\bin>netbeans64 -J-Xdebug -J-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1044

Use “jps –v” to find out pid of netbeans. In another window, attach to it with JDB:

jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=1044

Now, using Windows, I know the beep() method is actually sun.awt.windows.WToolkit.beep(). You can find out the toolkit class your platform uses with “System.println(Toolkit.getDefaultToolkit().getClass().getName())”. The platform default is overridden by “-Dawt.toolkit=com.example.MyAWTToolkit”. So I try to set a breakpoint with jdb on “sun.awt.windows.WToolkit.beep”:

> stop in sun.awt.windows.WToolkit.beep
Internal exception:
com.sun.jdi.NativeMethodException: Cannot set breakpoints on native methods
        at com.sun.tools.jdi.EventRequestManagerImpl.createBreakpointRequest(EventRequestManagerImpl.java:814)

This seems to be some JDB limitation – Netbeans debugger can put a breakpoint on a native method, jdb can't. Hmm, what should I do.

So I decided upon the following somewhat unorthodox approach – I wrote my own AWT toolkit. My custom AWT Toolkit actually delegates everything to the platform one, except the beep() method also does “new Throwable().printStackTrace()”. It solved my problem. My toolkit isn’t perfect – I didn’t bother to delegate every method, it probably still has some StackOverflowError bugs (any method in java.awt.Toolkit which tests if the current Toolkit is the default one will tend to cause this) – but it seems to be enough for Netbeans to run – the fonts look ugly, but when it beeps, it tells me why!

Code is attached. Run it like so:

netbeans64 -J-Dawt.toolkit= awtbug.AWTBugToolkit -J-Xbootclasspath/a:
awtbug.jar -J-Dawtbug.realToolkit=sun.awt.windows.WToolkit

Here is a sample of the output:

java.lang.Throwable: AWTBugToolkit.beep()
at awtbug.AWTBugToolkit.beep(AWTBugToolkit.java:393)
at org.netbeans.modules.java.editor.imports.JavaFixAllImports.performFixImports(JavaFixAllImports.java:260)
at org.netbeans.modules.java.editor.imports.JavaFixAllImports.access$200(JavaFixAllImports.java:104)
at org.netbeans.modules.java.editor.imports.JavaFixAllImports$1.run(JavaFixAllImports.java:148)
at org.netbeans.modules.java.editor.imports.JavaFixAllImports$1.run(JavaFixAllImports.java:125)
at org.netbeans.api.java.source.JavaSource$1.run(JavaSource.java:644)
at org.netbeans.api.java.source.JavaSource$1.run(JavaSource.java:634)
at org.netbeans.api.java.source.JavaSource$MultiTask.run(JavaSource.java:488)
at org.netbeans.modules.parsing.impl.TaskProcessor.callUserTask(TaskProcessor.java:584)
at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:153)
at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:137)
at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:201)
at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:198)
at org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager.priorityIO(FileChangedManager.java:176)
at org.netbeans.modules.masterfs.providers.ProvidedExtensions.priorityIO(ProvidedExtensions.java:360)
at org.netbeans.modules.parsing.impl.Utilities.runPriorityIO(Utilities.java:74)
at org.netbeans.modules.parsing.impl.TaskProcessor.runUserTask(TaskProcessor.java:198)
at org.netbeans.modules.parsing.api.ParserManager.parse(ParserManager.java:104)
at org.netbeans.api.java.source.JavaSource.runUserActionTaskImpl(JavaSource.java:438)
at org.netbeans.api.java.source.JavaSource.runUserActionTask(JavaSource.java:409)
at org.netbeans.api.java.source.JavaSource.runModificationTask(JavaSource.java:655)
at org.netbeans.modules.java.editor.imports.JavaFixAllImports$2.run(JavaFixAllImports.java:164)
at org.netbeans.modules.progress.ui.RunOffEDTImpl$1.run(RunOffEDTImpl.java:150)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1454)
at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2036)

Now off to read the Netbeans source code, to find out why. (Having done so, I’m ironically left with the conclusion, that I don’t think the beeps have anything to do with why my script doesn’t work.)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The code:

package awtbug;

import java.awt.AWTError;
import java.awt.Button;
import java.awt.Canvas;
import java.awt.Checkbox;
import java.awt.CheckboxMenuItem;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Desktop;
import java.awt.Dialog;
import java.awt.Dialog.ModalExclusionType;
import java.awt.Dialog.ModalityType;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Insets;
import java.awt.JobAttributes;
import java.awt.KeyboardFocusManager;
import java.awt.Label;
import java.awt.List;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.PageAttributes;
import java.awt.Panel;
import java.awt.Point;
import java.awt.PopupMenu;
import java.awt.PrintJob;
import java.awt.ScrollPane;
import java.awt.Scrollbar;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.datatransfer.Clipboard;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.InvalidDnDOperationException;
import java.awt.dnd.peer.DragSourceContextPeer;
import java.awt.event.AWTEventListener;
import java.awt.font.TextAttribute;
import java.awt.im.InputMethodHighlight;
import java.awt.image.ColorModel;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.awt.peer.ButtonPeer;
import java.awt.peer.CanvasPeer;
import java.awt.peer.CheckboxMenuItemPeer;
import java.awt.peer.CheckboxPeer;
import java.awt.peer.ChoicePeer;
import java.awt.peer.DesktopPeer;
import java.awt.peer.DialogPeer;
import java.awt.peer.FileDialogPeer;
import java.awt.peer.FontPeer;
import java.awt.peer.FramePeer;
import java.awt.peer.KeyboardFocusManagerPeer;
import java.awt.peer.LabelPeer;
import java.awt.peer.LightweightPeer;
import java.awt.peer.ListPeer;
import java.awt.peer.MenuBarPeer;
import java.awt.peer.MenuItemPeer;
import java.awt.peer.MenuPeer;
import java.awt.peer.MouseInfoPeer;
import java.awt.peer.PanelPeer;
import java.awt.peer.PopupMenuPeer;
import java.awt.peer.ScrollPanePeer;
import java.awt.peer.ScrollbarPeer;
import java.awt.peer.TextAreaPeer;
import java.awt.peer.TextFieldPeer;
import java.awt.peer.WindowPeer;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Map;
import java.util.Properties;
import sun.awt.HeadlessToolkit;
import sun.awt.KeyboardFocusManagerPeerProvider;

/**
 * AWTBUG is a dummy AWT toolkit implementation used for debugging. It delegates
 * all calls to the standard AWT toolkit, but it intercepts beep() and prints
 * the stack trace.
 *
 * @author Simon Kissane
 */
public final class AWTBugToolkit extends Toolkit implements
        KeyboardFocusManagerPeerProvider {

   private Toolkit toolkit = getNamedToolkit();

   private static synchronized Toolkit getNamedToolkit() {
      final String nm = System.getProperty("awtbug.realToolkit");
      return (Toolkit) java.security.AccessController.doPrivileged(
              new java.security.PrivilegedAction() {
         @Override
         public Object run() {
            Toolkit toolkit = null;
            Class cls = null;
            try {
               try {
                  cls = Class.forName(nm);
               } catch (ClassNotFoundException e) {
                  ClassLoader cl = ClassLoader.getSystemClassLoader();
                  if (cl != null)
                     try {
                        cls = cl.loadClass(nm);
                     } catch (ClassNotFoundException ee) {
                        throw new AWTError("Toolkit not found: " + nm);
                     }
               }
               if (cls != null) {
                  toolkit = (Toolkit) cls.newInstance();
                  if (GraphicsEnvironment.isHeadless())
                     toolkit = new HeadlessToolkit(toolkit);
               }
            } catch (InstantiationException e) {
               throw new AWTError("Could not instantiate Toolkit: " + nm);
            } catch (IllegalAccessException e) {
               throw new AWTError("Could not access Toolkit: " + nm);
            }
            return toolkit;
         }
      });
   }

   @Override
   public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(
           KeyboardFocusManager kfm) {
      return ((KeyboardFocusManagerPeerProvider) toolkit).
              createKeyboardFocusManagerPeer(kfm);
   }

   private Object call(String method) {
      return call(method, new Class[0], new Object[0]);
   }

   private Object call(final String method,
           final Class[] types, final Object[] args) {
      return AccessController.doPrivileged(new PrivilegedAction() {
         @Override
         public Object run() {
            try {
               Class c = Toolkit.class;
               Method m = c.getDeclaredMethod(method, types);
               m.setAccessible(true);
               return m.invoke(toolkit, args);
            } catch (NoSuchMethodException | SecurityException |
                    IllegalAccessException | IllegalArgumentException |
                    InvocationTargetException ex) {
               throw new RuntimeException(ex);
            }
         }
      });
   }

   @Override
   public DesktopPeer createDesktopPeer(Desktop target) throws HeadlessException {
      return (DesktopPeer) call("createDesktopPeer",
              new Class[]{Desktop.class}, new Object[]{target});
   }

   @Override
   public void setDynamicLayout(boolean dynamic) throws HeadlessException {
      toolkit.setDynamicLayout(dynamic);
   }

   @Override
   public boolean isDynamicLayoutActive() throws HeadlessException {
      return toolkit.isDynamicLayoutActive();
   }

   @Override
   public Insets getScreenInsets(GraphicsConfiguration gc) throws
           HeadlessException {
      return toolkit.getScreenInsets(gc);
   }

   @Override
   public Image createImage(byte[] imagedata) {
      return toolkit.createImage(imagedata);
   }

   @Override
   public PrintJob getPrintJob(Frame frame, String jobtitle,
           JobAttributes jobAttributes, PageAttributes pageAttributes) {
      return toolkit.getPrintJob(frame, jobtitle, jobAttributes, pageAttributes);
   }

   @Override
   public int getMenuShortcutKeyMask() throws HeadlessException {
      return toolkit.getMenuShortcutKeyMask();
   }

   @Override
   public boolean getLockingKeyState(int keyCode) throws
           UnsupportedOperationException {
      return toolkit.getLockingKeyState(keyCode);
   }

   @Override
   public void setLockingKeyState(int keyCode, boolean on) throws
           UnsupportedOperationException {
      toolkit.setLockingKeyState(keyCode, on);
   }

   @Override
   public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
           throws IndexOutOfBoundsException, HeadlessException {
      return toolkit.createCustomCursor(cursor, hotSpot, name);
   }

   @Override
   public Dimension getBestCursorSize(int preferredWidth, int preferredHeight)
           throws HeadlessException {
      return toolkit.getBestCursorSize(preferredWidth, preferredHeight);
   }

   @Override
   public int getMaximumCursorColors() throws HeadlessException {
      return toolkit.getMaximumCursorColors();
   }

   @Override
   public boolean isFrameStateSupported(int state) throws HeadlessException {
      return toolkit.isFrameStateSupported(state);
   }

   @Override
   public <T extends DragGestureRecognizer> T createDragGestureRecognizer(
           Class<T> abstractRecognizerClass,
           DragSource ds, Component c, int srcActions, DragGestureListener dgl) {
      return toolkit.createDragGestureRecognizer(abstractRecognizerClass, ds, c,
              srcActions, dgl);
   }

   @Override
   public void addPropertyChangeListener(String name, PropertyChangeListener pcl) {
      toolkit.addPropertyChangeListener(name, pcl);
   }

   @Override
   public void removePropertyChangeListener(String name,
           PropertyChangeListener pcl) {
      toolkit.removePropertyChangeListener(name, pcl);
   }

   @Override
   public PropertyChangeListener[] getPropertyChangeListeners() {
      return toolkit.getPropertyChangeListeners();
   }

   @Override
   public PropertyChangeListener[] getPropertyChangeListeners(
           String propertyName) {
      return toolkit.getPropertyChangeListeners(propertyName);
   }

   @Override
   public boolean isAlwaysOnTopSupported() {
      return toolkit.isAlwaysOnTopSupported();
   }

   @Override
   public void addAWTEventListener(AWTEventListener listener, long eventMask) {
      toolkit.addAWTEventListener(listener, eventMask);
   }

   @Override
   public void removeAWTEventListener(AWTEventListener listener) {
      toolkit.removeAWTEventListener(listener);
   }

   @Override
   public AWTEventListener[] getAWTEventListeners() {
      return toolkit.getAWTEventListeners();
   }

   @Override
   public AWTEventListener[] getAWTEventListeners(long eventMask) {
      return toolkit.getAWTEventListeners(eventMask);
   }

   @Override
   public boolean areExtraMouseButtonsEnabled() throws HeadlessException {
      return toolkit.areExtraMouseButtonsEnabled();
   }

   @Override
   public Dimension getScreenSize() throws HeadlessException {
      return toolkit.getScreenSize();
   }

   @Override
   public int getScreenResolution() throws HeadlessException {
      return toolkit.getScreenResolution();
   }

   @Override
   public ColorModel getColorModel() throws HeadlessException {
      return toolkit.getColorModel();
   }

   @Override
   public String[] getFontList() {
      return toolkit.getFontList();
   }

   @Override
   public FontMetrics getFontMetrics(Font font) {
      return toolkit.getFontMetrics(font);
   }

   @Override
   public void sync() {
      toolkit.sync();
   }

   @Override
   public Image getImage(String filename) {
      return toolkit.getImage(filename);
   }

   @Override
   public Image getImage(URL url) {
      return toolkit.getImage(url);
   }

   @Override
   public Image createImage(String filename) {
      return toolkit.createImage(filename);
   }

   @Override
   public Image createImage(URL url) {
      return toolkit.createImage(url);
   }

   @Override
   public boolean prepareImage(Image image, int width, int height,
           ImageObserver observer) {
      return toolkit.prepareImage(image, width, height, observer);
   }

   @Override
   public int checkImage(Image image, int width, int height,
           ImageObserver observer) {
      return toolkit.checkImage(image, width, height, observer);
   }

   @Override
   public Image createImage(ImageProducer producer) {
      return toolkit.createImage(producer);
   }

   @Override
   public Image createImage(byte[] imagedata, int imageoffset, int imagelength) {
      return toolkit.createImage(imagedata, imageoffset, imagelength);
   }

   @Override
   public PrintJob getPrintJob(Frame frame, String jobtitle, Properties props) {
      return toolkit.getPrintJob(frame, jobtitle, props);
   }

   @Override
   public void beep() {
      new Throwable("AWTBugToolkit.beep()").printStackTrace();
      toolkit.beep();
   }

   @Override
   public Clipboard getSystemClipboard() throws HeadlessException {
      return toolkit.getSystemClipboard();
   }

   @Override
   public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent dge)
           throws InvalidDnDOperationException {
      return toolkit.createDragSourceContextPeer(dge);
   }

   @Override
   public boolean isModalityTypeSupported(ModalityType modalityType) {
      return toolkit.isModalityTypeSupported(modalityType);
   }

   @Override
   public boolean isModalExclusionTypeSupported(
           ModalExclusionType modalExclusionType) {
      return toolkit.isModalExclusionTypeSupported(modalExclusionType);
   }

   @Override
   public Map<TextAttribute, ?> mapInputMethodHighlight(
           InputMethodHighlight highlight)
           throws HeadlessException {
      return toolkit.mapInputMethodHighlight(highlight);
   }

   @Override
   protected MouseInfoPeer getMouseInfoPeer() {
      return (MouseInfoPeer) call("getMouseInfoPeer",
              new Class[0], new Object[0]);
   }

   @Override
   protected LightweightPeer createComponent(Component target) {
      return (LightweightPeer) call("createComponent", new Class[]{
                 Component.class}, new Object[]{target});
   }

   @Override
   protected void loadSystemColors(int[] systemColors) throws HeadlessException {
      call("loadSystemColors", new Class[]{new int[0].getClass()},
              new Object[]{systemColors});
   }

   @Override
   protected boolean isDynamicLayoutSet() throws HeadlessException {
      return (Boolean) call("isDynamicLayoutSet", new Class[0], new Object[0]);
   }

   @Override
   protected Object lazilyLoadDesktopProperty(String name) {
      return call("lazilyLoadDesktopProperty", new Class[]{String.class},
              new Object[]{name});
   }

   @Override
   protected void initializeDesktopProperties() {
      call("initializeDesktopProperties");
   }

   @Override
   protected ButtonPeer createButton(Button target) throws HeadlessException {
      return (ButtonPeer) call("createButton",
              new Class[]{Button.class}, new Object[]{target});
   }

   @Override
   protected TextFieldPeer createTextField(TextField target) throws
           HeadlessException {
      return (TextFieldPeer) call("createTextField",
              new Class[]{TextField.class},
              new Object[]{target});
   }

   @Override
   protected LabelPeer createLabel(Label target) throws HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected ListPeer createList(List target) throws HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected CheckboxPeer createCheckbox(Checkbox target) throws
           HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected ScrollbarPeer createScrollbar(Scrollbar target) throws
           HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected ScrollPanePeer createScrollPane(ScrollPane target) throws
           HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected TextAreaPeer createTextArea(TextArea target) throws
           HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected ChoicePeer createChoice(Choice target) throws HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected FramePeer createFrame(Frame target) throws HeadlessException {
      return (FramePeer) call("createFrame",
              new Class[]{Frame.class},
              new Object[]{target});
   }

   @Override
   protected CanvasPeer createCanvas(Canvas target) {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected PanelPeer createPanel(Panel target) {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected WindowPeer createWindow(Window target) throws HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected DialogPeer createDialog(Dialog target) throws HeadlessException {
      return (DialogPeer) call("createDialog",
              new Class[]{Dialog.class},
              new Object[]{target});
   }

   @Override
   protected MenuBarPeer createMenuBar(MenuBar target) throws HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected MenuPeer createMenu(Menu target) throws HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   protected PopupMenuPeer createPopupMenu(PopupMenu target) throws
           HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   public MenuItemPeer createMenuItem(MenuItem target) throws
           HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   public FileDialogPeer createFileDialog(FileDialog target) throws
           HeadlessException {
      throw new UnsupportedOperationException("Not supported yet.");
   }

   @Override
   public CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target)
           throws HeadlessException {
      return (CheckboxMenuItemPeer) call("createCheckboxMenuItem",
              new Class[]{CheckboxMenuItem.class},
              new Object[]{target});
   }

   @Override
   public FontPeer getFontPeer(String name, int style) {
      return (FontPeer) call("getFontPeer",
              new Class[]{String.class, Integer.TYPE},
              new Object[]{name, style});
   }

   @Override
   public EventQueue getSystemEventQueueImpl() {
      return (EventQueue) call("getSystemEventQueueImpl");
   }
}