javabuilders
javabuilders copied to clipboard
NPE and other Exception building an int property
Starting from Swing sample PersonApp, if you just add a simple int property to class PersonApp:
[PersonApp.java]
private int number;
public void setNumber(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
[PersonApp.yml]
JFrame(name=frame, title=frame.title, size=packed, defaultCloseOperation=exitOnClose):
- JButton(name=save, text=button.save, onAction=[$validate,save,done])
- JButton(name=cancel, text=button.cancel, onAction=[$confirm,cancel])
- MigLayout: |
[pref] [grow,100] [pref] [grow,100]
"label.firstName" txtFirstName "label.lastName" txtLastName
"label.email" txtEmail+*
>save+*=1,cancel=1
- number: 1
bind:
- txtFirstName.text: person.firstName
- txtLastName.text: person.lastName
- txtEmail.text: person.emailAddress
validate:
- txtFirstName.text: {mandatory: true, label: label.firstName}
- txtLastName.text: {mandatory: true, label: label.lastName}
- txtEmail.text: {mandatory: true, emailAddress: true, label: label.email}
results in a NPE
Unable to process property PersonApp.number : null
java.lang.NullPointerException: null
at org.javabuilders.Builder.handleProperty(Builder.java:862)
at org.javabuilders.Builder.processDocumentNode(Builder.java:560)
at org.javabuilders.Builder.processDocumentNode(Builder.java:543)
at org.javabuilders.Builder.handleType(Builder.java:708)
at org.javabuilders.Builder.processDocumentNode(Builder.java:510)
at org.javabuilders.Builder.executeBuild(Builder.java:449)
at org.javabuilders.Builder.buildFromString(Builder.java:324)
at org.javabuilders.Builder.build(Builder.java:265)
at org.javabuilders.Builder.build(Builder.java:185)
at org.javabuilders.Builder.build(Builder.java:144)
at org.javabuilders.swing.SwingJavaBuilder.build(SwingJavaBuilder.java:89)
at person.app.PersonApp.<init>(PersonApp.java:47)
at person.app.PersonApp$1.run(PersonApp.java:98)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
Caused by: java.lang.NullPointerException
at org.javabuilders.Builder.handleProperty(Builder.java:850)
... 26 more
changing Buider.java, lines 850 to (bold text) could resolve problem..:
String sValue = parent.getStringProperty(currentKey); if (sValue != null && sValue.matches(asValueHandler.getRegex())) { //replace the value from the file with the corresponding object instance parent.getProperties().put(currentKey, asValueHandler.getValue(process, parent, currentKey, parent.getProperty(currentKey))); } else { throw new BuildException("Invalid {0} value \"{1}\" for {2}.{3}. Must in be in \"{4}\" format, e.g. \"{5}\"", propertyType.getSimpleName(), sValue, parent.getMainObject().getClass().getSimpleName(), currentKey, asValueHandler.getRegex(), asValueHandler.getInputValueSample()); }
unfortunately, this does not solve the issue.. the subsequent exception is throws:
Invalid int value "null" for PersonApp.number. Must in be in "\d+|[a-zA-Z0-9_]+" format, e.g. "3 | SOME_CONSTANT_VALUE | someConstantValue"
at org.javabuilders.Builder.handleProperty(Builder.java:855)
... 26 more
My question at this point is, is it possible to use properties other than String in yml files, and assign them to java class?
I suspect I don't support primitive types. Can you try it with Integer and see if that works?
Also, everything in the "child" document under a JFrame refers to children objects that get added to it and not to properties on the actual JFrame.
Maybe
JFrame(name=frame, title=frame.title, size=packed, defaultCloseOperation=exitOnClose, number=1):
may work, but I am not sure, Never used it on custom properties.
Let me know.
Thanks for your interest!
resuming: changing the property to Integer does not results anymore in any exception.
Leaving the definition of the frame as is (I mean as a child, - number = 1) the value is not populated.
Instead, as you suggested, using
JFrame(name=frame, title=frame.title, size=packed, defaultCloseOperation=exitOnClose, number=1):
works as expected.
Maybe, it would be worth adding a check to property "- number = 1" for existence instead of leaving that simply null without any exception reported to user..
what do you think about?