Menu

As simple as possible, as complex as necessary

Fixing problems using spreadsheet-CFML on Linux

26 July 2022

There have been a few reports lately of issues with the Spreadsheet-CFML library on Linux.

Unfortunately I have very limited Linux expertise having spent most of my dev career working exclusively with Windows servers.

However, I've recently started to use Linux a bit more as a result of slowly moving into the world of containers, and I now have a better handle on the issue affecting the spreadsheet library.

Fonts

The problem arises when using either of two features: autoSizeColumns or the streaming XML format (SXSSF). In fact it boils down to same thing in both cases as SXSSF processing needs to track the column autosizing option.

Running code such as the following to download a streamed spreadsheet from a query:

data = QueryNew( "column1,column2", "VarChar,VarChar", [ [ "a", "b" ], [ "c", "d" ] ] );
spreadsheet = New Spreadsheet();
spreadsheet.downloadFileFromQuery( data=data, filename="test", streamingXml=true );

results in an exception, which may be a null pointer such as:

java.lang.NullPointerException
at sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1264)
...

or a slightly more specific error such as:

java.lang.reflect.InvocationTargetException
at java.desktop/sun.font.FontManagerFactory$1.run(Unknown Source)
...

The stack trace in both cases points to a problem invoking basic java font functionality.

"Headless" builds

As I say, the world of Linux remains largely mysterious to me, but I have learned that the OS can come in many different forms. Not just different distributions and versions, but also "builds", particularly in the context of docker/containers.

It seems that to save precious megabytes it's not uncommon for certain builds to exclude components that are assumed to be superfluous in the context of a "headless" operation, where there's no need for a human user interface.

Fonts fit into this category because obviously a machine doesn't need to read text on a screen.

But the machine may be tasked with generating output which a human will read eventually. A spreadsheet, for example.

Alpine

One such minimal build which seems to be popular in the container world is "Alpine" Linux.

I've been using the commandbox:alpine container image from Ortus for Lucee servers which is currently based on the eclipse-temurin:11-jre-alpine OpenJDK image, and was seeing the problem described above when generating spreadsheets.

Solution

The fairly straightforward fix is to add back in the font capability.

How this is done will vary depending on the specific Linux build, but adding the following line to my Lucee commandbox:alpine based Dockerfile and rebuilding did the trick in my case.

RUN apk add fontconfig ttf-dejavu

This installs the Linux font management package along with a single font to activate the functionality. Now when POI (the java library which powers spreadsheet-CFML), needs to invoke auto column sizing or other operations which relate to fonts, it has the resources to do so. The change only seems to add around 20MB to the image size.

Incidentally, a recent ticket on the eclipse-temurin project seems to suggest that this fix may soon be unnecessary with their Alpine builds. A consensus appears to be forming that fonts are necessary in headless environments.

Posted on . Updated

Comments

  • Formatting comments: See this list of formatting tags you can use in your comments.
  • Want to paste code? Enclose within <pre><code> tags for syntax higlighting and better formatting and if possible use script. If your code includes "self-closing" tags, such as <cfargument>, you must add an explicit closing tag, otherwise it is likely to be mangled by the Disqus parser.
Back to the top