JDK-8096775 : [WebView] implement missing functionality in PasteboardJava.cpp
  • Type: Bug
  • Component: javafx
  • Sub-Component: web
  • Affected Version: 9
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2015-03-23
  • Updated: 2015-06-12
  • Resolved: 2015-04-17
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8 JDK 9
8u60Fixed 9Fixed
Related Reports
Blocks :  
Duplicate :  
Duplicate :  
Duplicate :  
Description
The native Clipboard and Pasteboard classes were refactored in WebKit. A part of the functionality migrated from the former to the latter, in the context of a long-term task of Clipboard class removal.

Prior to the latest WebKit update there was a macros defined in WebCore/dom/Clipboard.h:

// This DOM object now works by calling through to classes in the platform layer.
// Specifically, the class currently named Pasteboard. The legacy style instead
// uses this as an abstract base class.
#define WTF_USE_LEGACY_STYLE_ABSTRACT_CLIPBOARD_CLASS (PLATFORM(IOS) || PLATFORM(QT) || PLATFORM(JAVA))

But it was removed later (http://trac.webkit.org/changeset/154230).

Currently, we have Pasteboard implemented in PasteboardJava.cpp. However, a number of methods is marked as NOT IMPLEMENTED. This leads to a crash that can be reproduced as follows:

- Open, for instance, yahoo.com in a Browser. Type any text in the search field, select it and try to drag out. A crash fill follow. Same way, try to select any text on the page and drag & drop it into the search field. Same crash.

Interestingly that the crash is not reproduced on OSX, but on Windows and Linux. A stack dump is attached.
Comments
Thanks, I did tab cleanup. webrev: http://cr.openjdk.java.net/~ant/RT-40330/webrev.1 changeset: http://hg.openjdk.java.net/openjfx/9-dev/rt/rev/072b7ddf89bf
17-04-2015

I ran a test build on OEL 6 with and without your patch. I confirmed that this bug reproduces without your patch and is fixed with your patch. +1 once you fix the formatting issues that Vadim mentioned.
15-04-2015

Hi Vadim, thanks for the review. I'll clean the code.
14-04-2015

This looks good, although I just skimmed through looking for obvious errors. I found some places where there are tabs instead of spaces, Pasteboard.h at the end, DataObjectJava.h at the end, and PasteboardJava.cpp throughout. I think it's worth to untabify them.
14-04-2015

I tested the fix against regressions comparing to the previous behaviour. Didn't find any. However, the behaviour is still imperfect. Filed new issue to track it: RT-40478.
08-04-2015

webrev: http://cr.openjdk.java.net/~ant/RT-40330/webrev.0 - ClipboardJava.* files are removed, its functionality partially migrated to PasteboardJava.cpp, partially removed as unnecessary - ClipboardUtilitiesJava.* files are renamed to PasteboardUtilitiesJava.* - WCPasteboard.initIDs() is replaced with lazy JNI methods initialization - DataObjectJava.h : refactoring only, except the new copy ctor - PasteboardJava.cpp : most of the changes are here: The new WebKit concept is that it creates a Pasteboard instance as DnD or CnP. For the first mode it uses a single instance during the whole dnd operation, so it's created with a new instance of DataObjectJava (a holder for dragged or copied data). For the second mode WebKit calls the create methods twice: on copy and on paste. For this mode a single shared DataObjectJava instance is used. The "private pasteboard" is used as temp pasteboard which is immediately copied to a base pasteboard used for an dnd/cnp op. So, for it a new DataObjectJava is created. Also, for a dnd operation, data should not be copied to the platform pasteboard. Now it's solved with the Pasteboard::m_copyPasteMode flag. When it's false, data is only exchanged with help of DataObjectJava, otherwise the platform pasteboard (WCPasteboard.java) is used as well. Some things remain unclear to me: for instance the DataObjectJava::m_fileContent field, used as an image storage. I can't see where it was read back. So, I left that logic w/o changes. Nevertheless, for an image dnd op, the image is passed to JFX in another way (I didn't have to touch that code): in DragClientJava::startDrag() with WebPage.fwkStartDrag JNI method. For a copy-n-paste op, an image is written to the platform pb with WCPasteboard.writeImage JNI method (in PasteboardJava). So, the m_fileContent field should have only be used for the HTML Clipboard API (however its implementation looks incomplete). Mostly, I looked into the GTK port (PasteboardGtk & DataObjectGtk) for a reference.
08-04-2015

The cause of the crash is simply a null ptr.
23-03-2015

In hs_err_pid13960.log (debug build) the exception is reported as EXCEPTION_CONTINUE_EXECUTION. However, with a release build, the exception is reported as EXCEPTION_ACCESS_VIOLATION and the stack looks as follows: Stack: [0x000000005a7a0000,0x000000005a8a0000], sp=0x000000005a89c980, free space=1010k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) C [jfxwebkit.dll+0x8a12eb] C [jfxwebkit.dll+0x812231] C [jfxwebkit.dll+0x815b34] C [jfxwebkit.dll+0x815c34] C [jfxwebkit.dll+0x816169] C [jfxwebkit.dll+0x81922e] C [jfxwebkit.dll+0x8addf6] C 0x0000000002975e14 Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) j com.sun.webkit.WebPage.twkProcessMouseEvent(JIIIIIIIZZZZZF)Z+0 j com.sun.webkit.WebPage.dispatchMouseEvent(Lcom/sun/webkit/event/WCMouseEvent;)Z+141 j javafx.scene.web.WebView.processMouseEvent(Ljavafx/scene/input/MouseEvent;)V+175 j javafx.scene.web.WebView.lambda$registerEventHandlers$3(Ljavafx/scene/input/MouseEvent;)V+2 j javafx.scene.web.WebView$$Lambda$83.handle(Ljavafx/event/Event;)V+8 j com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Ljavafx/event/Event;)V+5 j com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Ljavafx/event/Event;)V+28 J 3656 C1 com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Ljavafx/event/EventType;Ljavafx/event/Event;)Ljavafx/event/Event; (34 bytes) @ 0x00000000032f31ec [0x00000000032f2c80+0x56c] j com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Ljavafx/event/Event;)Ljavafx/event/Event;+8 j com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Ljavafx/event/Event;)Ljavafx/event/Event;+11 J 3750 C1 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Ljavafx/event/Event;Ljavafx/event/EventDispatchChain;)Ljavafx/event/Event; (44 bytes) @ 0x0000000003342de4 [0x0000000003342ac0+0x324] J 3640 C1 com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Ljavafx/event/Event;)Ljavafx/event/Event; (101 bytes) @ 0x000000000316852c [0x0000000003168380+0x1ac] J 3750 C1 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Ljavafx/event/Event;Ljavafx/event/EventDispatchChain;)Ljavafx/event/Event; (44 bytes) @ 0x0000000003342d04 [0x0000000003342ac0+0x244] J 3640 C1 com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Ljavafx/event/Event;)Ljavafx/event/Event; (101 bytes) @ 0x000000000316852c [0x0000000003168380+0x1ac] J 3750 C1 com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Ljavafx/event/Event;Ljavafx/event/EventDispatchChain;)Ljavafx/event/Event; (44 bytes) @ 0x0000000003342d04 [0x0000000003342ac0+0x244] J 3640 C1 com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Ljavafx/event/Event;)Ljavafx/event/Event; (101 bytes) @ 0x000000000316852c [0x0000000003168380+0x1ac] J 3858 C1 com.sun.javafx.event.EventUtil.fireEvent(Ljavafx/event/EventTarget;Ljavafx/event/Event;)Ljavafx/event/Event; (81 bytes) @ 0x000000000337cc5c [0x000000000337c540+0x71c] J 3857 C1 javafx.event.Event.fireEvent(Ljavafx/event/EventTarget;Ljavafx/event/Event;)V (35 bytes) @ 0x000000000337beec [0x000000000337be20+0xcc] j javafx.scene.Scene$MouseHandler.process(Ljavafx/scene/input/MouseEvent;Z)V+491 j javafx.scene.Scene$MouseHandler.access$1500(Ljavafx/scene/Scene$MouseHandler;Ljavafx/scene/input/MouseEvent;Z)V+3 j javafx.scene.Scene.impl_processMouseEvent(Ljavafx/scene/input/MouseEvent;)V+6 j javafx.scene.Scene$ScenePeerListener.mouseEvent(Ljavafx/event/EventType;DDDDLjavafx/scene/input/MouseButton;ZZZZZZZZZ)V+46 j com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run()Ljava/lang/Void;+438 j com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run()Ljava/lang/Object;+1 v ~StubRoutines::call_stub J 1385 java.security.AccessController.doPrivileged(Ljava/security/PrivilegedAction;Ljava/security/AccessControlContext;)Ljava/lang/Object; (0 bytes) @ 0x0000000002dfe2e6 [0x0000000002dfe280+0x66] j com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$351()Ljava/lang/Void;+11 j com.sun.javafx.tk.quantum.GlassViewEventHandler$$Lambda$216.get()Ljava/lang/Object;+4 j com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(Ljava/util/function/Supplier;)Ljava/lang/Object;+18 j com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Lcom/sun/glass/ui/View;JIIIIIIIZZ)V+103 j com.sun.glass.ui.View.handleMouseEvent(JIIIIIIIZZ)V+30 j com.sun.glass.ui.View.notifyMouse(IIIIIIIZZ)V+181 v ~StubRoutines::call_stub j com.sun.glass.ui.win.WinApplication._runLoop(Ljava/lang/Runnable;)V+0 j com.sun.glass.ui.win.WinApplication.lambda$null$146(Ljava/lang/Runnable;)V+7 j com.sun.glass.ui.win.WinApplication$$Lambda$37.run()V+8 j java.lang.Thread.run()V+11 v ~StubRoutines::call_stub
23-03-2015