Record type support by Abhineshhh · Pull Request #1020 · stleary/JSON-java

Fixes : #1015

Problem

new JSONObject(recordInstance) or JSONObject.wrap(recordInstance) produces an empty object {} when the object is a Java record (or any class using record-style accessors without @JSONPropertyName annotations).

Root Cause

Java records use accessor methods without the traditional JavaBean get/is prefixes:

  • Traditional class: getName() → works
  • Java record: name() → fails (returns {})

The getKeyNameFromMethod() logic only checked for methods starting with get or is, causing it to ignore record accessors.

Solution

Modified getKeyNameFromMethod() in JSONObject.java to recognize record-style accessor methods:

  • Now supports lowercase method names (e.g., name(), age(), active())
  • Excludes methods from Object, Enum, Number, and all java.*/javax.* classes
  • Excludes common method names (hashCode, toString, equals, etc.)

Changes

  • Modified: src/main/java/org/json/JSONObject.java - Added record accessor support
  • Added: src/test/java/org/json/junit/data/PersonRecord.java - Test class mimicking record behavior
  • Added: Test case jsonObjectByRecord() in JSONObjectTest.java

Testing

All 735 existing tests pass
New test for record-style classes passes
No breaking changes - fully backward compatible

Example

// Before: returns {}
record Person(String name, int age) {}
Person person = new Person("John", 30);
JSONObject json = new JSONObject(person);
// Result: {}

// After: returns {"name":"John","age":30}
JSONObject json = new JSONObject(person);
// Result: {"name":"John","age":30}