Bug 60417 - autoSizeColumn(int i) swallows interrupted exception and resets interrupted flag
Summary: autoSizeColumn(int i) swallows interrupted exception and resets interrupted flag
Status: RESOLVED WONTFIX
Alias: None
Product: POI
Classification: Unclassified
Component: XSSF (show other bugs)
Version: 3.16-dev
Hardware: PC All
: P2 normal (vote)
Target Milestone: ---
Assignee: POI Developers List
URL:
Keywords:
Depends on: 58896
Blocks:
  Show dependency tree
 
Reported: 2016-11-25 00:16 UTC by derblaueklabautermann
Modified: 2024-02-25 19:13 UTC (History)
1 user (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description derblaueklabautermann 2016-11-25 00:16:24 UTC
Invoking 

org.apache.poi.ss.usermodel.Sheet.autoSizeColumn(int column)

in an interrupted thread (interrupted flag = "true") swallows the interrupted exception and resets the interrupted flag to "false". 
Therefore further checks whether the thread was interrupted or not will fail. This might cause some trouble.

This bug can be observed using both "HSSF" and "XSSF" workbooks (tested with the current beta-version (3.16-beta1-20161120)).

Code example to reproduce the bug:


import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public class MainClass {

	public static void main(String[] args) {

		Thread workerThread = new WorkerThread();
		workerThread.start();

		System.out.println("Main thread will go to sleep for 2 seconds...");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			Thread.currentThread().interrupt();
			System.out.println("Main thread interrupted while sleeping...");
		}
		System.out.println("Main thread woke up...");
		workerThread.interrupt();
		System.out.println("Interrupting worker thread...");
	}

	public static class WorkerThread extends Thread {

		private final Workbook workbook;

		public WorkerThread() {
			// this.workbook = new XSSFWorkbook();
			this.workbook = new HSSFWorkbook();
		}

		@Override
		public void run() {
			Sheet sheet = this.workbook.createSheet();

			for (int i = 0; i < 10; ++i) {
				sheet.createRow(i).createCell(0).setCellValue("Row " + i);
				System.out.println("\tWorkerThread - Before autosize: interrupted = " + this.isInterrupted());
				sheet.autoSizeColumn(0);
				System.out.println("\tWorkerThread - After autosize: interrupted = " + this.isInterrupted());
				++i;
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					this.interrupt();
					System.out.println("\tWorkerThread - Interrupted while sleeping...");
				}
			}
		}
	}
}


Output:

Main thread will go to sleep for 2 seconds...
	WorkerThread - Before autosize: interrupted = false
	WorkerThread - After autosize: interrupted = false
	WorkerThread - Before autosize: interrupted = false
	WorkerThread - After autosize: interrupted = false
Main thread woke up...
Interrupting worker thread...
	WorkerThread - Interrupted while sleeping...
	WorkerThread - Before autosize: interrupted = true
	WorkerThread - After autosize: interrupted = false
	WorkerThread - Before autosize: interrupted = false
	WorkerThread - After autosize: interrupted = false
	WorkerThread - Before autosize: interrupted = false
	WorkerThread - After autosize: interrupted = false

As one can clearly see, the interrupted flag is reset when autoSizeColumn(int i) is invoked.

The problem seems to occur somewhere deep in java.awt.font.TextLayout. Thus it's probably out of your scope to fix "the real bug".
However, I think it's still worth to have a look at it (and to be aware of this bug).
Comment 1 Javen O'Neal 2017-01-05 09:43:33 UTC
Auto-sizing columns is one of the slowest functions in POI relative to what users expect (auto-sizing is nearly instantaneous in Excel even for large workbooks). Bug 58896 and past discussion on the dev@ mailing list discuss ways to improve the speed of calculating the best-fit-width for a column.

Merged cells and rich text severely slow down the auto-size calculations (though our implementation of auto-sizing may not be much faster for plain text).

If the problem resides in java.awt.font.TextLayout, maybe one way we could side-step this problem is by rewriting auto-sizing without TextLayout.

POI does very little with threads or interruptions, so you're probably right that the interruption isn't originating from POI code. The only thing in POI that gets close to this is creating ThreadLocal variables in LocaleUtil and a few other locations. A quick grep didn't reveal an usages of Thread or interrupt outside of our test suite for unencrypted HSSF workbooks.
Comment 2 Dominik Stadler 2024-02-25 19:13:38 UTC
Tried to analyze this, but I fear there is nothing we can do about it. 

It seems to happen deep inside AWT text handling and it seems to be related to how much time elapsed, i.e. doing the calls quicker allows more iterations until the state is cleared. 

So I believe AWT is doing some "time-based cleanup" here, so likely not much we can do.