-
Bug
-
Resolution: Fixed
-
P1
-
8
-
b36
-
b122
-
generic
-
generic
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8030715 | 9 | Sergey Malenkov | P1 | Resolved | Fixed | b06 |
JDK-8031294 | 8u5 | Sergey Malenkov | P1 | Resolved | Fixed | b03 |
Related NetBeans bug:
https://netbeans.org/bugzilla/show_bug.cgi?id=239364
Prior JDK8 the document listeners were fired INSIDE of the document lock upon insert while in JDK8 they are fired OUTSIDE of the lock. That means that the DocumentListener implementations can no longer rely that the offset and length contained in the document events correspond to the actual document state.
The regression was introduced with a fix of issueJDK-7146146.
The following test demonstrates that a document listener can no longer rely on the document's content on JDK8 (the test passes fine on JDK7):
public void testInsertedTextIsPresent() throws Exception {
final PlainDocument doc = new PlainDocument();
final CountDownLatch insertDone = new CountDownLatch(1);
final CountDownLatch removeDone = new CountDownLatch(1);
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent evt) {
insertDone.countDown();
try {
removeDone.await(1, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
throw new IllegalStateException(ex);
}
try {
String insertedText = evt.getDocument().getText(evt.getOffset(), evt.getLength());
} catch (BadLocationException ex) {
throw new IllegalStateException(
"Inserted text not present in document !!! docLen=" + doc.getLength(), ex);
}
}
public void removeUpdate(DocumentEvent evt) {
}
public void changedUpdate(DocumentEvent evt) {
}
});
new Thread(new Runnable() {
@Override
public void run() {
try {
insertDone.await();
doc.remove(0, doc.getLength());
removeDone.countDown();
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
}).start();
doc.insertString(0, "Hello", null);
}
https://netbeans.org/bugzilla/show_bug.cgi?id=239364
Prior JDK8 the document listeners were fired INSIDE of the document lock upon insert while in JDK8 they are fired OUTSIDE of the lock. That means that the DocumentListener implementations can no longer rely that the offset and length contained in the document events correspond to the actual document state.
The regression was introduced with a fix of issue
The following test demonstrates that a document listener can no longer rely on the document's content on JDK8 (the test passes fine on JDK7):
public void testInsertedTextIsPresent() throws Exception {
final PlainDocument doc = new PlainDocument();
final CountDownLatch insertDone = new CountDownLatch(1);
final CountDownLatch removeDone = new CountDownLatch(1);
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent evt) {
insertDone.countDown();
try {
removeDone.await(1, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
throw new IllegalStateException(ex);
}
try {
String insertedText = evt.getDocument().getText(evt.getOffset(), evt.getLength());
} catch (BadLocationException ex) {
throw new IllegalStateException(
"Inserted text not present in document !!! docLen=" + doc.getLength(), ex);
}
}
public void removeUpdate(DocumentEvent evt) {
}
public void changedUpdate(DocumentEvent evt) {
}
});
new Thread(new Runnable() {
@Override
public void run() {
try {
insertDone.await();
doc.remove(0, doc.getLength());
removeDone.countDown();
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
}).start();
doc.insertString(0, "Hello", null);
}
- backported by
-
JDK-8030715 Document listeners fired outside document lock
- Resolved
-
JDK-8031294 Document listeners fired outside document lock
- Resolved
- relates to
-
JDK-7146146 Deadlock between subclass of AbstractDocument and UndoManager
- Closed
-
JDK-8030702 Deadlock between subclass of AbstractDocument and UndoManager
- Resolved