[bug-15830]toExcel and Export Excel NullPointerException

I’ve got the below script, and it works if the table is empty or every value is filled in, but in many cases I either have blanks or booleans in columns, and I’m guessing one of these is triggering the NullPointerException. Anyone run into this before or have a suggestion on a path forward?

table = event.source.parent.getComponent("Power Table").data
spreadsheet = system.dataset.toExcel(1, table)
path = system.file.saveFile("data.xlsx")
if path is not None:
   system.file.writeFile(path, spreadsheet)

Can you post the full stack trace of the null pointer exception here? Makes it pretty trivial to backtrack on our end.

Traceback (most recent call last):
  File "<event:actionPerformed>", line 7, in <module>
	at com.inductiveautomation.ignition.common.util.excel.adapters.DatasetExcelAdapter.drawSheet(DatasetExcelAdapter.java:72)
	at com.inductiveautomation.ignition.common.util.excel.adapters.DatasetExcelAdapter.drawWorkbook(DatasetExcelAdapter.java:29)
	at com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities.dataSetToExcelBytes(DatasetUtilities.java:1109)
	at com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities.toExcel(DatasetUtilities.java:925)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
java.lang.NullPointerException: java.lang.NullPointerException

	at org.python.core.Py.JavaError(Py.java:552)
	at org.python.core.Py.JavaError(Py.java:543)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:190)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:206)
	at org.python.core.PyObject.__call__(PyObject.java:497)
	at org.python.core.PyObject.__call__(PyObject.java:501)
	at org.python.pycode._pyx86.f$0(<event:actionPerformed>:10)
	at org.python.pycode._pyx86.call_function(<event:actionPerformed>)
	at org.python.core.PyTableCode.call(PyTableCode.java:171)
	at org.python.core.PyCode.call(PyCode.java:18)
	at org.python.core.Py.runCode(Py.java:1614)
	at com.inductiveautomation.ignition.common.script.ScriptManager.runCode(ScriptManager.java:761)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.runActions(ActionAdapter.java:187)
	at com.inductiveautomation.factorypmi.application.binding.action.ActionAdapter.invoke(ActionAdapter.java:278)
	at com.inductiveautomation.factorypmi.application.binding.action.RelayInvocationHandler.invoke(RelayInvocationHandler.java:57)
	at com.sun.proxy.$Proxy42.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
	at java.desktop/javax.swing.DefaultButtonModel.setPressed(Unknown Source)
	at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
	at java.desktop/java.awt.Component.processMouseEvent(Unknown Source)
	at java.desktop/javax.swing.JComponent.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.Component.processEvent(Unknown Source)
	at java.desktop/java.awt.Container.processEvent(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
	at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.Container.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Window.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.Component.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$4.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.desktop/java.awt.EventQueue$5.run(Unknown Source)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
	at java.desktop/java.awt.EventQueue.dispatchEvent(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(Unknown Source)
	at java.desktop/java.awt.EventDispatchThread.run(Unknown Source)
Caused by: java.lang.NullPointerException
	at com.inductiveautomation.ignition.common.util.excel.adapters.DatasetExcelAdapter.drawSheet(DatasetExcelAdapter.java:72)
	at com.inductiveautomation.ignition.common.util.excel.adapters.DatasetExcelAdapter.drawWorkbook(DatasetExcelAdapter.java:29)
	at com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities.dataSetToExcelBytes(DatasetUtilities.java:1109)
	at com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities.toExcel(DatasetUtilities.java:925)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.python.core.PyReflectedFunction.__call__(PyReflectedFunction.java:188)
	... 48 more

Ignition v8.0.7 (b2019122014)
Java: Azul Systems, Inc. 11.0.5
1 Like

Okay, ticket filed. We’ll probably fix it at the same time as the other issue you noticed.

1 Like

Out of curiosity, what is triggering this one to error out? It works with some datasets, but not others.

It’s the dataset containing nulls - probably in a boolean or numeric typed column. The slightly longer technical explanation - Java represents almost everything as an object, but also has a few “primitive” types, including boolean, double, integer, etc. But, there are corresponding “boxed” classes Integer, Boolean, Double that allow for the same kind of operations you would expect on Java objects. For the most part, the JVM can automatically and transparently treat a Double and a double as the same - except for one crucial difference: primitives cannot be null, but an actual object reference can be. (see the “billion dollar mistake”).

So, the internal function to draw sheets is going through each column of the dataset, which is probably a (boxed) Double, then attempting to retrieve the value at a certain row and pass it into the Cell.setValue function…which expects a primitive. The JVM attempts to automatically “unbox” the Double into a double…and fails, because it’s null.

2 Likes

This issue is fixed in 8.0.10.