What’s Changed & Migration
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
Baseline date: 2026-10-09. This page was written against Apache POI 5.5.1 (the latest release on that date, published on 30 November 2025). POI 6.0.0 has not been released: the POI site lists it as in development, so everything about 6.0 below is the planned or announced scope, not shipped behaviour. Java 21 and later, Spring Boot 4.x on Spring Framework 7 and Jakarta EE 11 are assumed for the examples.
Most Apache POI code found on the web was written for 3.x or 4.x, and a lot of it no longer compiles against 5.5.x. This page is the map between the old code and the code used in the rest of this section: what each major version changed, what the 5.1 to 5.5 releases added or tightened, and what 6.0 is expected to change. It is a summary built from the official release notes (https://poi.apache.org/changes.html) and the versioning page (https://poi.apache.org/versioning.html), not a replacement for them. Where a claim could not be confirmed there, the page says so.
Version timeline
Dates and the content of each release are those of the POI changes page: 4.0.0 on 2018-09-07, 5.0.0 on 2021-01-20, 5.1.0 on 2021-11-01, 5.2.0 on 2022-01-14, 5.3.0 on 2024-07-02, 5.4.0 on 2025-01-08, 5.5.0 on 2025-11-15 and 5.5.1 on 2025-11-30.
How POI versions its releases
Since 4.0.0 POI follows the principles of Semantic Versioning 2.0.0. Before it, the version was an X.Y pair and minor releases sometimes carried large changes. The versioning page gives the rules that matter when upgrading:
-
An API may be deprecated in one major version and removed in the next. Compile with deprecation warnings on, fix them while still on the old major, then move.
-
Minor versions may add features, deprecate APIs or fix bugs in a way that changes existing behaviour (the 5.4.0 and 6.0 notes below are examples).
-
When jumping several majors, move one major at a time and test in between.
-
4.x and earlier are no longer supported. 5.5.x still receives critical bug fixes and security patches, and support for 5.5.x continues for a limited time after 6.0.0 is released (the length is not decided yet).
Source: Apache POI versioning
3.x to 4.0
The 4.0.0 release (2018-09-07) is the first SemVer release and the one that cleaned up the 3.x API:
-
Java 8 is the minimum. Support for Java 6 and 7 was dropped.
-
Deprecated classes were removed, as the release notes say ("Remove deprecated classes"), and the OPOIFS classes were removed, which the notes list as breaking backwards compatibility.
-
The
CellTypeenum replaces the int constants. Before 4.0,getCellType()returned anint, compared with constants such asCell.CELL_TYPE_STRING; the 3.17 Javadoc marks those constants as deprecated since 3.15 and due for removal in 4.0, and offers the transitionalgetCellTypeEnum(), which returns the enum. The 4.1 Javadoc ofCelldocuments the end of the transition:getCellType()returnsCellType, andgetCellTypeEnum()is deprecated with the note that it "will be renamed togetCellType()when we make the CellType enum transition in POI 4.0", and a removal notice for 4.2.
In 5.5.1 the Cell interface has getCellType(), getCachedFormulaResultType() and setCellType(CellType), no
getCellTypeEnum() and no CELL_TYPE_* constants.
4.x to 5.0
The 5.0.0 release (2021-01-20) changed the artifacts, the module system and the XML schemas:
-
Jar renames. The release notes say "Change artifact names of poi-/ooxml-schemas to poi-ooxml-lite/full". The old
ooxml-schemasartifact is nowpoi-ooxml-fulland the oldpoi-ooxml-schemasis nowpoi-ooxml-lite. Lite is the default dependency ofpoi-ooxml; full is needed for the low-levelCT*beans that lite does not contain. See Setup & Dependencies for the coordinates and for theNoClassDefFoundErrorthat appears when a bean is missing from lite. -
JPMS. POI provides JigSaw modules, and the release notes warn that "some classes moved between packages for the JDK 9+ support". Code that imported a moved class needs a new import. The module names are in the JPMS section of Setup & Dependencies.
-
ECMA-376 5th edition schemas. POI upgraded to the transitional schemas of the 5th edition of ECMA-376, with the warning "expect API breaks when using XmlBeans directly". Code that only uses the usermodel types (
XSSFWorkbook,XWPFDocument) is not affected; code that touchesCT*classes may be. -
CellTypeeverywhere. The notes list "Add some more methods to allow to use CellType everywhere".
The practical migration is to change the dependency artifacts, recompile, fix imports of moved classes and fix any
CT* code against the new schemas. Do not mix POI jars of different versions.
Source: Apache POI changes, Apache POI versioning
The 5.1 to 5.5 highlights
All of these are minor releases. The table lists items from the release notes that change what a server application sees; it is a selection, not the full changelog.
| Release | Change (as in the release notes) | What it means for your code |
|---|---|---|
5.1.0 (2021-11-01) |
"Internal logging in POI now uses Apache Log4J 2". POI depends only on |
Add a |
5.1.0 |
"By default, no DTDs will be accepted in XML files." |
A file with a DOCTYPE is refused instead of being parsed, which closes the XXE door. See Security & Untrusted Files. |
5.1.0 |
|
Workbooks that use them can be evaluated by |
5.1.0 |
|
The entry size limit can be raised for large legitimate files, if you accept the risk. |
5.2.0 (2022-01-14) |
|
|
5.2.0 |
|
Formula cells are formatted from a fresh evaluation unless you opt in to the cached value. |
5.2.3 and 5.2.4 |
|
Containers without system fonts no longer break SXSSF, which matters for column auto-sizing in slim images. |
5.3.0 (2024-07-02) |
"SXSSFWorkbook now removes temp files when closed - removing need for a separate dispose call". |
Use try-with-resources on |
5.3.0 |
|
Some zip variants that were rejected can be read. |
5.4.0 (2025-01-08) |
A breaking change: some invalid compressed content in OOXML files now fails parsing. Files with duplicate zip entry names throw an exception. |
Some files that used to open now fail. The duplicate-entry check relates to CVE-2025-31672 (see below). |
5.4.0 |
|
Use the BOM to keep log4j versions aligned. The POI site advises against |
5.4.1 (2025-04-06) |
Custom |
Temp-file location can be set per thread. Formatted dates and numbers may differ on JDK 24; test formatting. |
5.5.0 (2025-11-15) |
New API for reading XLSB files. A fix for images in .xlsx files that could fill the disk with temporary files. |
Binary workbooks can be read without converting them first. Re-test the temp directory usage of image-heavy exports. |
5.5.1 (2025-11-30) |
"Add back module-info classes that were omitted from the 5.5.0 jars by accident". |
JPMS users should skip 5.5.0. |
The POI site also announces CVE-2025-31672 (8 April 2025): a crafted OOXML file with duplicate zip entry names could make different products read different data, and from poi-ooxml 5.4.0 duplicate entries cause an exception. The recommendation is to be on 5.4.0 or later.
Source: Apache POI changes, Apache POI news
What 6.0 is expected to change
POI 6.0.0 is in development on the trunk branch, with no release date. According to the versioning page and the draft 6.0.0 section of the changes page, the scope that is currently listed is:
-
JDK 17 is the minimum, "was JDK 8 in POI 5.x". The Java 8 support is removed.
-
DataFormatteruses cached values for formula cells by default. The notes call it a breaking change:setUseCachedValuesForFormulaCells(boolean)now defaults totrue(it wasfalsesince 5.2.0). -
Removed deprecated APIs. The draft notes name
getCodepointsandhasOOXMLHeader(OOXML) andAddDimensionedImage(SS common) as removed. The versioning page says the final scope is not decided. -
log4j-api2.26.1. -
Zip hardening, for example duplicate ZIP entry validation against path separator bypasses.
-
XLSB reading no longer depends on XMLBeans.
-
Fixes in XSSF and XWPF, such as drawing anchors that move with shifted rows and columns, and theme font helpers in XWPF.
The draft items can change before the release. The sensible preparation, which works today, is to compile against 5.5.1
with deprecation warnings enabled, to set the DataFormatter flag explicitly instead of relying on the default, and to
run on Java 17 or later.
Source: Apache POI changes, Apache POI versioning
Outdated idioms and their current code
| Outdated idiom | Current code | Since |
|---|---|---|
|
|
4.0 (renamed), gone in 5.x |
|
|
4.0; the constants are not in 5.5.1 |
|
|
5.0 |
Log4j 1.x or |
|
5.1 |
|
|
Long-standing advice; lower memory |
|
|
5.3.0 |
Relying on |
|
5.2.0; the default flips in 6.0 |
Assuming a DOCTYPE in a part is parsed |
DTDs are refused; remove the DOCTYPE from the producing tool |
5.1.0 |
Importing |
The |
Always |
The "current code" column was compiled and run against POI 5.5.1 for this page:
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
public class Migrated {
public static void main(String[] args) throws IOException {
File out = new File("target/migrated.xlsx");
try (SXSSFWorkbook wb = new SXSSFWorkbook(100);
FileOutputStream os = new FileOutputStream(out)) {
Sheet s = wb.createSheet("Books");
Row r = s.createRow(0);
r.createCell(0).setCellValue("Dune");
r.createCell(1).setCellValue(12.5);
r.createCell(2).setCellFormula("B1*2");
wb.write(os);
} // close() deletes the temp files since 5.3.0, no dispose() needed
DataFormatter formatter = new DataFormatter(Locale.ENGLISH);
// false in 5.2.0 to 5.5.x, true by default in 6.0: set it explicitly
formatter.setUseCachedValuesForFormulaCells(false);
try (Workbook wb = WorkbookFactory.create(out)) {
FormulaEvaluator ev = wb.getCreationHelper().createFormulaEvaluator();
Row r = wb.getSheetAt(0).getRow(0);
for (Cell c : r) {
CellType t = c.getCellType();
if (t == CellType.FORMULA) {
System.out.println("formula, cached " + c.getCachedFormulaResultType());
}
System.out.println(t + " -> " + formatter.formatCellValue(c, ev));
}
}
}
}
Output observed with POI 5.5.1:
STRING -> Dune
NUMERIC -> 12.5
formula, cached NUMERIC
FORMULA -> 25
The old code in the left column is not shown as a compilable snippet, because by definition it does not compile against 5.5.1.
Upgrade checklist
-
Read the changes page for every release between your version and the target, and move one major at a time.
-
Compile with deprecation warnings on before changing the version, and fix them.
-
Replace the schema artifacts with
poi-ooxml-liteorpoi-ooxml-fullwhen coming from 4.x. -
Provide a
log4j-apibridge or implementation, and align the log4j versions with the BOM. -
Move to 5.4.0 or later for the stricter zip handling, and test the files your users really upload.
-
Set the
DataFormattercached-values flag explicitly, so 6.0 does not change your output. -
Run on Java 17 or later in preparation for 6.0.
References
-
Apache POI changes: https://poi.apache.org/changes.html
-
Apache POI versioning: https://poi.apache.org/versioning.html
-
Apache POI home page, news and CVE list: https://poi.apache.org/
-
Apache POI download: https://poi.apache.org/download.html
-
CellJavadoc (4.1): https://poi.apache.org/apidocs/4.1/org/apache/poi/ss/usermodel/Cell.html -
Javadoc (development): https://poi.apache.org/apidocs/dev/