Skip to content

v1.1.0

Choose a tag to compare

@hooji hooji released this 22 Mar 22:40
· 141 commits to main since this release
77b27b1

What's New in v1.1.0

Immutable JDK type support

Freeze/restore now correctly handles immutable JDK types whose final fields can't be set via Objenesis. Each type is captured via JDI field reads and reconstructed via parse/valueOf on restore.

Supported types: BigDecimal, BigInteger, UUID, LocalDate, LocalTime, LocalDateTime, Instant, Duration, ZonedDateTime, OffsetDateTime, Period, Year, YearMonth, MonthDay, ZoneOffset, ZoneId, URI

Enum support

Enum constants are captured by name and restored via Enum.valueOf(), preserving:

  • == identity (critical for switch statements and comparisons)
  • ordinal() values and custom enum fields
  • Use as HashMap/HashSet keys
  • Works for both user-defined enums and JDK enums like TimeUnit
  • Correctly handles Java 8 enum constants with method overrides (anonymous subclasses)

Fail-fast validation (UncapturableTypeException)

freeze() now throws UncapturableTypeException immediately when it encounters a type that cannot be restored correctly:

Type Advice
Optional Use T directly with null instead
Unmodifiable collections Use mutable collections
Thread, ClassLoader Remove from captured state
I/O / network types Close or remove before freezing
Pattern Store pattern string, recompile after restore

JDI reliability improvements

  • Double-suspend — All JDI suspend/resume operations use suspend count = 2 for resilience against spurious JDI resume events
  • Event draining — Pending JDI events from prior freeze/restore cycles are drained before each suspend to prevent races
  • Exponential backoff — Retry with up to 10 attempts (50ms → 800ms backoff) on InvalidStackFrameException
  • Pre-load classes — All classes referenced by snapshot locals are force-loaded before frame manipulation, preventing ClassNotLoadedException during restore
  • JDWP bypass for Java 8 — When JDI's classloader lookup fails for bootstrap-loaded classes on Java 8, the library sets slot values directly via JDWP reflection, bypassing the broken client-side type check
  • Automatic class loading — Classes referenced by local variables are automatically force-loaded via Class.forName() through JDI when a ClassNotLoadedException is encountered during restore

Bug fixes

  • Fixed boxed primitives (Integer, Long, etc.) inside collections losing their values during restore
  • Fixed latch deadlock when freeze worker thread completed before caller reached wait
  • Fixed JDI connection races during concurrent freeze attempts
  • Fixed field mutations being duplicated during skip-pass replay
  • Fixed resume stub using dummy receiver instead of heap-restored object

CI coverage expansion

Test matrix now covers 7 JDK versions × 3 platforms = 21 combinations:

  • JDK versions: 8, 9, 11, 17 (LTS), 21 (LTS), 24, 25
  • Platforms: Ubuntu, macOS (ARM), Windows
  • 127 unit tests + 35 integration tests per combination