DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT <http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22456>. ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND INSERTED IN THE BUG DATABASE.
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=22456 Synchronization problem in HSSFDataFormat Summary: Synchronization problem in HSSFDataFormat Product: POI Version: 1.5.1 Platform: PC OS/Version: Windows NT/2K Status: NEW Severity: Normal Priority: Other Component: HSSF AssignedTo: [EMAIL PROTECTED] ReportedBy: [EMAIL PROTECTED] Hi *, there's a synchronization problem in HSSFDataFormat. The populating of the formats array list is static synchronized, but not all accesses are synchronized. Two concurrent threads may enter one of the methods; the first will be stopped immedeately after entering the method. The second one will enter a method and see the formats as null. It now enters the static populate method and will create a List and start to add formats to it. The scheduler will then interrupt the thread. Now the bug happens: The first thread will see the (not-fully) initialized List (which is not null!) and try to access it. This'll lead to an IndexOutOfBoundsException. I ran into this situation while unit-testing one of my classes. The solution is simple. Do the populating of the formats list as static initialization. This way the vm guarantees, that the list will be populated before any methods of the class are called. Below is the fixed (but untested) version of the class... Regards and keep up the good work; I really enjoy using POI!!! Andreas package org.apache.poi.hssf.usermodel; import java.util.ArrayList; import java.util.List; /** * Utility to identify builin formats. The following is a list of the formats as * returned by this class.<P> *<P> * 0, "General"<P> * 1, "0"<P> * 2, "0.00"<P> * 3, "#,##0"<P> * 4, "#,##0.00"<P> * 5, "($#,##0_);($#,##0)"<P> * 6, "($#,##0_);[Red]($#,##0)"<P> * 7, "($#,##0.00);($#,##0.00)"<P> * 8, "($#,##0.00_);[Red]($#,##0.00)"<P> * 9, "0%"<P> * 0xa, "0.00%"<P> * 0xb, "0.00E+00"<P> * 0xc, "# ?/?"<P> * 0xd, "# ??/??"<P> * 0xe, "m/d/yy"<P> * 0xf, "d-mmm-yy"<P> * 0x10, "d-mmm"<P> * 0x11, "mmm-yy"<P> * 0x12, "h:mm AM/PM"<P> * 0x13, "h:mm:ss AM/PM"<P> * 0x14, "h:mm"<P> * 0x15, "h:mm:ss"<P> * 0x16, "m/d/yy h:mm"<P> *<P> * // 0x17 - 0x24 reserved for international and undocumented * 0x25, "(#,##0_);(#,##0)"<P> * 0x26, "(#,##0_);[Red](#,##0)"<P> * 0x27, "(#,##0.00_);(#,##0.00)"<P> * 0x28, "(#,##0.00_);[Red](#,##0.00)"<P> * 0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)"<P> * 0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)"<P> * 0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)"<P> * 0x2c, "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)"<P> * 0x2d, "mm:ss"<P> * 0x2e, "[h]:mm:ss"<P> * 0x2f, "mm:ss.0"<P> * 0x30, "##0.0E+0"<P> * 0x31, "@"<P> * * * @author Andrew C. Oliver (acoliver at apache dot org) */ public class HSSFDataFormat { private static ArrayList formats; static { formats = new ArrayList(); formats.add(0, "General"); formats.add(1, "0"); formats.add(2, "0.00"); formats.add(3, "#,##0"); formats.add(4, "#,##0.00"); formats.add(5, "($#,##0_);($#,##0)"); formats.add(6, "($#,##0_);[Red]($#,##0)"); formats.add(7, "($#,##0.00);($#,##0.00)"); formats.add(8, "($#,##0.00_);[Red]($#,##0.00)"); formats.add(9, "0%"); formats.add(0xa, "0.00%"); formats.add(0xb, "0.00E+00"); formats.add(0xc, "# ?/?"); formats.add(0xd, "# ??/??"); formats.add(0xe, "m/d/yy"); formats.add(0xf, "d-mmm-yy"); formats.add(0x10, "d-mmm"); formats.add(0x11, "mmm-yy"); formats.add(0x12, "h:mm AM/PM"); formats.add(0x13, "h:mm:ss AM/PM"); formats.add(0x14, "h:mm"); formats.add(0x15, "h:mm:ss"); formats.add(0x16, "m/d/yy h:mm"); // 0x17 - 0x24 reserved for international and undocumented formats.add(0x17, "0x17"); formats.add(0x18, "0x18"); formats.add(0x19, "0x19"); formats.add(0x1a, "0x1a"); formats.add(0x1b, "0x1b"); formats.add(0x1c, "0x1c"); formats.add(0x1d, "0x1d"); formats.add(0x1e, "0x1e"); formats.add(0x1f, "0x1f"); formats.add(0x20, "0x20"); formats.add(0x21, "0x21"); formats.add(0x22, "0x22"); formats.add(0x23, "0x23"); formats.add(0x24, "0x24"); // 0x17 - 0x24 reserved for international and undocumented formats.add(0x25, "(#,##0_);(#,##0)"); formats.add(0x26, "(#,##0_);[Red](#,##0)"); formats.add(0x27, "(#,##0.00_);(#,##0.00)"); formats.add(0x28, "(#,##0.00_);[Red](#,##0.00)"); formats.add(0x29, "_(*#,##0_);_(*(#,##0);_(* \"-\"_);_(@_)"); formats.add(0x2a, "_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)"); formats.add(0x2b, "_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)"); formats.add(0x2c, "_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)"); formats.add(0x2d, "mm:ss"); formats.add(0x2e, "[h]:mm:ss"); formats.add(0x2f, "mm:ss.0"); formats.add(0x30, "##0.0E+0"); formats.add(0x31, "@"); } public static List getFormats() { return formats; } /** * get the format index that matches the given format string * @param format string matching a built in format * @return index of format or -1 if undefined. */ public static short getFormat(String format) { short retval = -1; for (short k = 0; k < 0x31; k++) { String nformat = ( String ) formats.get(k); if ((nformat != null) && nformat.equals(format)) { retval = k; break; } } return retval; } /** * get the format string that matches the given format index * @param index of a built in format * @return string represented at index of format or null if there is not a builtin format at that index */ public static String getFormat(short index) { return ( String ) formats.get(index); } /** * get the number of builtin and reserved formats * @return number of builtin and reserved formats */ public static int getNumberOfBuiltinFormats() { return formats.size(); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
