I am trying to support drag and drop from a native Windows application into a Java application. My problem has been that I have no documentation, and so I have been reverse-engineering it. My first issue was that I didn’t know the name of the clipboard format. Working in the debugger, I was able to find the identifier of the custom clipboard format that the application had registered using the system call RegisterClipboardFormat(). And in sun.awt.windows.WDataTransferer, there’s a native interface to the system call GetClipboardFormatName(), by which I managed to extract the registered name. (For reference, though it doesn’t bear directly on the problem, the application is Eudora 7.1 and the name is EudoraTransferClipboardFormat.)
Now I anticipate needing to do this again, and I’d rather write a small utility now because I’m certain to forget the internal data structures of the library by the time I need it later. The problem is that the relevant clipboard format identifier is buried inside a subclass instance of SunDropTargetContextPeer as private member currentT. Navigation from the drag-and-drop event to this object likewise goes through a protected member. And the system call interface is likewise declared private. This is all visible in the debugger, but not in ordinary code.
My goal is to extract the value of currentT (since that’s what the drag and drop subsystem actually sees) and display the name of the registered clipboard formats therein. I suspect various abuses of the class loader and security system are necessary to get this working as a publishable utility written in Java.
I solved this problem by using Java reflection calls to obtain the relevant internal members. The key part of this is the function
setAccessibleon theFieldobjects. This function turns off access control on the Field object, allowing public access, albeit not through the ordinary syntax. (Note the actual function name; it’s notsubvertAccessControls.) This call succeeds in the ordinary JRE environment and probably won’t work in, say, an applet. I didn’t bother checking this because this is for a developer tool to examine a drag event for native types that won’t otherwise show up because (1) the application doesn’t know about the native type and (2) there’s no data flavor to translate the native data transfer into a Java object. Therefore, I only need it running once per application that has a drag type I’m reverse engineering; running in the ordinary JRE is all I need.Thank goodness I didn’t have to break out
java.lang.instrumentor even JVMTI. I did, however, have to abuse the security system.Tested code fragment below. The variable
long native_types[]is the output.DropTargetDragEvent dtdeis the input; it’s an argument to an event handler.