Sometimes, the X clipboard is in some state that causes pastes to fail
with the following, or similar, stack traces:
java.lang.NullPointerException: Failed to retrieve atom name.
at java.desktop/sun.awt.X11.XlibWrapper.XGetAtomName(Native Method)
at java.desktop/sun.awt.X11.XAtom.getName(XAtom.java:189)
at
java.desktop/sun.awt.X11.XDataTransferer.getTargetNameForAtom(XDataTransferer.java:172)
at
java.desktop/sun.awt.X11.XDataTransferer.getNativeForFormat(XDataTransferer.java:161)
at
java.desktop/sun.awt.datatransfer.DataTransferer.getFlavorsForFormatsAsSet(DataTransferer.java:487)
at
java.desktop/sun.awt.datatransfer.SunClipboard.formatArrayAsDataFlavorSet(SunClipboard.java:342)
at
java.desktop/sun.awt.datatransfer.SunClipboard.isDataFlavorAvailable(SunClipboard.java:185)
This is a widespread issue and very frustrating issue, see:
-
https://youtrack.jetbrains.com/issue/JBR-438/Clipboard-operations-arent-working-in-certain-state-of-Xorg-selection-buffers
-
https://www.google.com/search?q="Failed+to+retrieve+atom+name"+"DataTransferer"
Frankly, I don't understand how X works at all, or how this issue
arises. However, this same workaround was applied to Mozilla in 2010:
https://hg.mozilla.org/releases/mozilla-1.9.1/rev/62f3d28797e2, and I
don't see any reasonable behavior that having this workaround in place
would break. The workaround works by simply skipping native formats
that don't have a name.
Verified to work by running IntelliJ Clion under the modified VM and
verifying that paste from my terminal, which previously did not work,
now works. I'm not familiar with OpenJDK unit testing conventions, but
I believe this change falls under the "highly platform-dependent"
exception.
From 321770ecbdce86aafb9f9c45db0bdcda678c643a Mon Sep 17 00:00:00 2001
From: Flaviu Tamas <[email protected]>
Date: Tue, 18 Oct 2022 23:54:34 -0400
Subject: [PATCH] Fixes failed paste when X clipboard is in a certain state
This is a widespread issue, see:
- https://youtrack.jetbrains.com/issue/JBR-438/Clipboard-operations-arent-working-in-certain-state-of-Xorg-selection-buffers
- https://www.google.com/search?q="Failed+to+retrieve+atom+name"+"DataTransferer"
Verified to work by running IntelliJ Clion under the modified VM and
verifying that paste from my terminal, which previously did not work,
now works.
---
.../sun/awt/datatransfer/DataTransferer.java | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java
index 8ca34787e19..dc40b3d336d 100644
--- a/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java
+++ b/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java
@@ -421,7 +421,13 @@ public abstract class DataTransferer {
// flavorMap - after this step, this map maps each of the DataFlavors
// from flavorSet to any of the specified formats.
for (long format : formats) {
- String nat = getNativeForFormat(format);
+ String nat;
+ try {
+ nat = getNativeForFormat(format);
+ } catch (NullPointerException e) {
+ // protect against bogus atoms, see https://hg.mozilla.org/releases/mozilla-1.9.1/rev/62f3d28797e2
+ continue;
+ }
List<DataFlavor> flavors = map.getFlavorsForNative(nat);
for (DataFlavor flavor : flavors) {
// Don't explicitly test for String, since it is just a special
@@ -485,7 +491,14 @@ public abstract class DataTransferer {
Set<DataFlavor> flavorSet = new HashSet<>(formats.length);
for (long format : formats) {
- List<DataFlavor> flavors = map.getFlavorsForNative(getNativeForFormat(format));
+ String nat;
+ try {
+ nat = getNativeForFormat(format);
+ } catch (NullPointerException e) {
+ // protect against bogus atoms, see https://hg.mozilla.org/releases/mozilla-1.9.1/rev/62f3d28797e2
+ continue;
+ }
+ List<DataFlavor> flavors = map.getFlavorsForNative(nat);
for (DataFlavor flavor : flavors) {
// Don't explicitly test for String, since it is just a special
// case of Serializable
--
2.38.0