Skip to content

Commit

Permalink
Add minimum set of classes so that SXSSFSheet can be constructed
Browse files Browse the repository at this point in the history
This avoids exceptions when trying to initialize the Java Font System

This fixes the test-item for issue 89
  • Loading branch information
centic9 committed Aug 27, 2024
1 parent b4998ad commit d309159
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 3 deletions.
7 changes: 5 additions & 2 deletions poishadow/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,13 @@ shadowJar {

// java.awt is not available, but class Color is used in APIs in POI, therefore
// relocate this class to another one where we can include a rewrite
relocate 'java.awt.Color', 'org.apache.poi.java.awt.Color'
relocate 'java.awt.font.FontRenderContext', 'org.apache.poi.java.awt.font.FontRenderContext'
relocate 'java.awt.font.TextLayout', 'org.apache.poi.java.awt.font.TextLayout'
relocate 'java.awt.geom.AffineTransform', 'org.apache.poi.java.awt.geom.AffineTransform'
relocate 'java.awt.geom.Dimension2D', 'org.apache.poi.java.awt.geom.Dimension2D'
relocate 'java.awt.Dimension', 'org.apache.poi.java.awt.Dimension'
relocate 'java.awt.image.BufferedImage', 'org.apache.poi.java.awt.image.BufferedImage'
relocate 'java.awt.Color', 'org.apache.poi.java.awt.Color'
relocate 'java.awt.Dimension', 'org.apache.poi.java.awt.Dimension'

relocate 'javax.imageio.ImageIO', 'org.apache.poi.javax.imageio.ImageIO'
relocate 'javax.imageio.ImageReader', 'org.apache.poi.javax.imageio.ImageReader'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.apache.poi.java.awt.font;

import java.awt.geom.AffineTransform;

public class FontRenderContext {
public FontRenderContext(AffineTransform o, boolean a, boolean b) {
//You can't crash here yet! If you do, a static field in SheetUtil will fail to load.
//Then next time SheetUtil will have to be accessed, a NoClassDefFoundError("SheetUtil")
//will be thrown!
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.apache.poi.java.awt.font;

import java.text.AttributedCharacterIterator;

public class TextLayout {
public TextLayout(AttributedCharacterIterator iterator, FontRenderContext fontRenderContext) {
//This is called in:
//SXSSFSheet.java:106
//AutoSizeColumnTracker.java:117
//SheetUtil.java:353
//This tricks SXSSFSheet constructor into not creating AutoSizeColumnTracker.
throw new NoClassDefFoundError("X11FontManager");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.apache.poi.java.awt.geom;

import java.awt.font.FontRenderContext;

/**
* Just an empty class, so we can have a correct {@link FontRenderContext} constructor
*/
public class AffineTransform {
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ protected void onCreate(Bundle savedInstanceState) {
System.setProperty("org.apache.poi.javax.xml.stream.XMLOutputFactory", "com.fasterxml.aalto.stax.OutputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLEventFactory", "com.fasterxml.aalto.stax.EventFactoryImpl");

System.setProperty("org.apache.poi.ss.ignoreMissingFontSystem", "true");

try {
// create all the list items
setupContent();
Expand Down Expand Up @@ -269,7 +271,7 @@ private void setupContent() throws IOException {
}));

// reproducer for https://github.com/centic9/poi-on-android/issues/89
DummyContent.addItem(new DummyItemWithCode("c" + (idCount++), "Test Issue 89 - Crashes!!", () -> {
DummyContent.addItem(new DummyItemWithCode("c" + (idCount++), "Test Issue 89", () -> {
try (OutputStream outputStream = openFileOutput("issue89.xlsx", Context.MODE_PRIVATE)) {
TestIssue89.saveExcelFile(outputStream);
}
Expand Down

2 comments on commit d309159

@PhpXp
Copy link

@PhpXp PhpXp commented on d309159 Aug 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, I'm the guy who proposed this workaround here: https://bz.apache.org/bugzilla/show_bug.cgi?id=69288#c4
I strongly encourage you to also improve TestIssue89 test.

The reason you can't throw in FontRenderContext is because it would work the first time, but not the second time:
The second time SXSSFSheet would try to construct AutoSizeColumnTracker, Java would throw NoClassDefFoundError("SheetUtil") and the exception would have a cause NoClassDefFoundError("X11FontManager") (the original exception).
It's an interesting detail of how Java class loading works if a static field throws an exception.

The test is missing another call to create a new sheet. Just add this line:

Sheet sheet = wb1.createSheet("Sheet2");

@centic9
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the note, added this to the test now

Please sign in to comment.