Uncaught NPE - Non-Existent CATEGORY used in PREABILITY

Description

Per James request - NPE was not caught at load time. This NPE was due to an uncaught non-existent CATEGORY on the PREABILITY.

Environment

None

Activity

Show:
Tom Parker
June 29, 2014, 9:56 AM

I'm not sure I understand the issue here. Is there an NPE at load that is not caught or is there an NPE at runtime that occurs that someone thinks should have been detected at load?

Andrew Maitland
June 29, 2014, 11:52 AM

Hi Tom,

James and I were speaking last night while doing our tasks (Him Converting base.xml to Freemarker, Me fixing ARG Race Builder) and I noticed a NPE in my log while investigating the reason I didn't qualify. We discovered the cause, and I fixed it. He requested this report to catch the NPE at load time, instead of run-time. The way he spoke he was interested in investigating a way to catch it earlier.

If you append this to any affliction, stand alone.
PREMULT:1,[!PREABILITY:1,CATEGORY=Internal,TYPE.Dress],[PREABILITY:1,CATEGORY=Internel,My Dress]

And load up pcgen and the sets, it displays as a clean load.

Note the bad category in the second section

Until the object containing that is viewed, you have a clean log and green light.

I made a copy of an ability and added "2" to the name. Here is what the log shows once you bring the ability up (which is red) (I.e. the ability is now being invoked by the UI for display purposes and determining whether the PC qualifies.)

11:45:06.371 SEVERE AWT-EventQueue-0 GameMode:2297 Attempt to fetch AbilityCateg
ory: Internel... but it does not exist
11:45:06.373 SEVERE AWT-EventQueue-0 PrereqHandler:191 Problem encountered when
testing PREREQ <prereq operator="GTEQ" operand="1" >
<prereq operator="LT" operand="1" >
<prereq kind="ability" count-multiples="true" category="Internal" key="TYPE.Dres
s" operator="GTEQ" operand="1" >
</prereq>
</prereq>
<prereq kind="ability" count-multiples="true" category="Internel" key="My Dress"
operator="GTEQ" operand="1" >
</prereq>
</prereq>
for Baleful Polymorph Spell2. See following trace for details.
java.lang.NullPointerException
at pcgen.core.prereq.PrerequisiteUtilities.buildAbilityList(Prerequisite
Utilities.java:476)
at pcgen.core.prereq.PrerequisiteUtilities.passesAbilityTest(Prerequisit
eUtilities.java:208)
at plugin.pretokens.test.PreAbilityTester.passes(PreAbilityTester.java:8
8)
at pcgen.core.prereq.PreMult.passes(PreMult.java:56)
at pcgen.core.prereq.PrereqHandler.passes(PrereqHandler.java:179)
at pcgen.core.prereq.PrereqHandler.passesAll(PrereqHandler.java:101)
at pcgen.cdom.base.ConcretePrereqObject.qualifies(ConcretePrereqObject.j
ava:269)
at pcgen.core.PlayerCharacter.isQualified(PlayerCharacter.java:9901)
at pcgen.gui2.facade.CharacterFacadeImpl.isQualifiedFor(CharacterFacadeI
mpl.java:3954)
at pcgen.gui2.tabs.models.QualifiedTreeCellRenderer.getTreeCellRendererC
omponent(QualifiedTreeCellRenderer.java:50)
at javax.swing.plaf.synth.SynthTreeUI.paintRow(Unknown Source)
at javax.swing.plaf.synth.SynthTreeUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthTreeUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at pcgen.gui2.util.JTreeTable$TreeTableCellRenderer.paint(JTreeTable.jav
a:666)
at pcgen.gui2.util.JTreeTable$TreeTableCellRenderer$1.paint(JTreeTable.j
ava:562)
at javax.swing.CellRendererPane.paintComponent(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.paintCell(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.paintCells(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JViewport.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JSplitPane.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JSplitPane.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown S
ource)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1000(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

11:45:07.853 SEVERE AWT-EventQueue-0 GameMode:2297 Attempt to fetch AbilityCateg
ory: Internel... but it does not exist
11:45:07.855 SEVERE AWT-EventQueue-0 PrereqHandler:191 Problem encountered when
testing PREREQ <prereq operator="GTEQ" operand="1" >
<prereq operator="LT" operand="1" >
<prereq kind="ability" count-multiples="true" category="Internal" key="TYPE.Dres
s" operator="GTEQ" operand="1" >
</prereq>
</prereq>
<prereq kind="ability" count-multiples="true" category="Internel" key="My Dress"
operator="GTEQ" operand="1" >
</prereq>
</prereq>
for Baleful Polymorph Spell2. See following trace for details.
java.lang.NullPointerException
at pcgen.core.prereq.PrerequisiteUtilities.buildAbilityList(Prerequisite
Utilities.java:476)
at pcgen.core.prereq.PrerequisiteUtilities.passesAbilityTest(Prerequisit
eUtilities.java:208)
at plugin.pretokens.test.PreAbilityTester.passes(PreAbilityTester.java:8
8)
at pcgen.core.prereq.PreMult.passes(PreMult.java:56)
at pcgen.core.prereq.PrereqHandler.passes(PrereqHandler.java:179)
at pcgen.core.prereq.PrereqHandler.passesAll(PrereqHandler.java:101)
at pcgen.cdom.base.ConcretePrereqObject.qualifies(ConcretePrereqObject.j
ava:269)
at pcgen.core.PlayerCharacter.isQualified(PlayerCharacter.java:9901)
at pcgen.gui2.facade.CharacterFacadeImpl.isQualifiedFor(CharacterFacadeI
mpl.java:3954)
at pcgen.gui2.tabs.models.QualifiedTreeCellRenderer.getTreeCellRendererC
omponent(QualifiedTreeCellRenderer.java:50)
at javax.swing.plaf.synth.SynthTreeUI.paintRow(Unknown Source)
at javax.swing.plaf.synth.SynthTreeUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthTreeUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at pcgen.gui2.util.JTreeTable$TreeTableCellRenderer.paint(JTreeTable.jav
a:666)
at pcgen.gui2.util.JTreeTable$TreeTableCellRenderer$1.paint(JTreeTable.j
ava:562)
at javax.swing.CellRendererPane.paintComponent(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.paintCell(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.paintCells(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.paint(Unknown Source)
at javax.swing.plaf.synth.SynthTableUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.RepaintManager$PaintManager.paintDoubleBuffered(Unknown S
ource)
at javax.swing.RepaintManager$PaintManager.paint(Unknown Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent._paintImmediately(Unknown Source)
at javax.swing.JComponent.paintImmediately(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at javax.swing.RepaintManager$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.prePaintDirtyRegions(Unknown Source)
at javax.swing.RepaintManager.access$1000(Unknown Source)
at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

James Dempsey
June 30, 2014, 2:45 AM

Catching the error at load time is difficult as PREABILITY is used in game modes before all ability categories are loaded. Instead I have fixed the NPE and instead reported an error when the prereq is tested.

Fixed

Assignee

James Dempsey

Reporter

Andrew Maitland

Labels

None

Theme

None

Epic/Theme

None

Pending User Input

None

Components

Fix versions

Affects versions

Priority

Minor
Configure