@@ -241,7 +241,6 @@ private static void traverse(Class<?> clazz,
241241 }
242242 visited .add (clazz );
243243 for (Field field : clazz .getDeclaredFields ()) {
244- field .setAccessible (true );
245244 String path = prefix .isEmpty ()
246245 ? field .getName ()
247246 : prefix + "." + field .getName ();
@@ -260,7 +259,31 @@ private static boolean isLeafType(Class<?> clazz) {
260259 || Boolean .class .equals (clazz )
261260 || Character .class .equals (clazz )
262261 || Date .class .isAssignableFrom (clazz )
263- || clazz .isEnum ();
262+ || clazz .isEnum ()
263+ || isJdkType (clazz );
264+ }
265+
266+ /**
267+ * Treats platform (JDK) types as opaque leaves so traversal never descends into them. JDK value
268+ * types such as {@code java.time.LocalDate}, {@code java.util.UUID} or {@code java.math.BigDecimal}
269+ * carry no domain-meaningful field paths, and the module system forbids making their internal
270+ * fields accessible (e.g. {@code java.base} does not open {@code java.time} to the unnamed module).
271+ */
272+ private static boolean isJdkType (Class <?> clazz ) {
273+ if (clazz .isArray ()) {
274+ return false ;
275+ }
276+ Package pkg = clazz .getPackage ();
277+ if (pkg == null ) {
278+ return false ;
279+ }
280+ String name = pkg .getName ();
281+ return name .startsWith ("java." )
282+ || name .startsWith ("javax." )
283+ || name .startsWith ("jakarta." )
284+ || name .startsWith ("sun." )
285+ || name .startsWith ("com.sun." )
286+ || name .startsWith ("jdk." );
264287 }
265288
266289 /**
0 commit comments