Skip to content

Add session export/import to jfr-shell - #40

Draft
jbachorik wants to merge 2 commits into
mainfrom
jb/sessions
Draft

Add session export/import to jfr-shell#40
jbachorik wants to merge 2 commits into
mainfrom
jb/sessions

Conversation

@jbachorik

Copy link
Copy Markdown
Collaborator

Summary

Implements complete session state export/import functionality for jfr-shell, enabling users to:

  • Save analysis progress and resume later
  • Share analysis sessions with team members
  • Create reusable analysis templates
  • Document incident investigations

Changes

New Features

  • Session Export: Save complete session state to JSON file

    • Export variables (scalars, maps, lazy queries)
    • Export recording information and metadata
    • Export session settings
    • Optional: include cached query results (--include-results)
    • Row limiting to control file size (--max-rows)
  • Session Import: Restore previously exported sessions

    • Recreate all variables and queries
    • Path remapping for cross-machine sharing (--remap-path)
    • Custom alias assignment (--alias)
    • Pre-populate cached results if included in export

Implementation

  • SessionSnapshot.java - Immutable data model for session state (~200 lines)
  • SessionExporter.java - Export service with JSON serialization (~400 lines)
  • SessionImporter.java - Import service with JSON parsing (~500 lines)
  • SessionExportImportTest.java - Integration tests (2 tests, all passing)

Commands

# Export
export [--include-results] [--max-rows N] [--format json] <path>

# Import  
import [--alias NAME] [--remap-path PATH] <session-file>

Integration

  • Added export/import commands to CommandDispatcher
  • Updated tab completion (CommandCompleter, OptionCompleter)
  • Comprehensive help documentation (help export, help import)

Documentation

  • Updated README.md with feature overview and examples (~100 lines)
  • Updated jfr-shell-tutorial.md with detailed use cases (~140 lines)
  • Updated jfr_shell_usage.md with command reference
  • Updated CLAUDE.md with feature description

Test plan

  • Unit tests for SessionSnapshot serialization
  • Integration tests for export/import roundtrip
  • Manual testing with various variable types
  • All existing tests passing
  • Code formatting applied (spotless)

Testing checklist

Tested scenarios:

  • Export session with scalar, map, and lazy variables
  • Import session and verify variables restored
  • Export with --include-results option
  • Import with --alias option
  • Import with --remap-path for different file location
  • Export/import with session settings preserved
  • Handle missing recording file on import
  • Tab completion for export/import commands

Example usage

# Save analysis
jfr> open recording.jfr --alias analysis
jfr> set threshold = 1000
jfr> set bigReads = events/jdk.FileRead[bytes>${threshold}]
jfr> export my-analysis.json

# Resume later
jfr> import my-analysis.json
jfr> vars  # All variables restored
jfr> show ${bigReads}

Future enhancements (Phase 2)

  • Markdown export format
  • HTML export format with interactive tables
  • Command history capture and replay
  • Bookmarks and annotations
  • Improved JSON parsing with proper library

Notes

  • Phase 1 implements JSON format only (Markdown/HTML in Phase 2)
  • Simplified JSON parsing sufficient for current needs
  • Format version 1.0 with backward compatibility support

🤖 Generated with Claude Code

@jbachorik jbachorik added the AI AI-generated code or contributions label Jan 9, 2026
@github-actions

github-actions Bot commented Jan 9, 2026

Copy link
Copy Markdown

Combined JUnit Test Report

  • Total: 1955
  • Passed: 1939
  • Failures: 0
  • Errors: 0
  • Skipped: 16

HTML Test Reports

Run artifacts: https://github.com/btraceio/jafar/actions/runs/33555098506

jbachorik added a commit to btraceio/drydock that referenced this pull request Jul 30, 2026
The first pass keyed recognition off the review-requested list, which meant
it only worked for somebody else's PR. Verified against btraceio/jafar#40 --
your own PR, no reviewers requested -- and the row read "pr-40": no number,
no branch, nothing to say what it merges into.

gh pr list already returns every open PR, so carry number and head with the
base (OpenPullRequest) instead of just the base, and resolve a pr-<n>
worktree against that. The same call, one richer value.

REQUESTED still means "somebody asked you for a review", so a PR of your own
groups where any branch of yours groups; it just carries its real name now.

Verified in the running app against jafar#40: "PR #40 jb/sessions ·
jafar · vs main", 12 files, 12 intents -- against gh's own changedFiles of
12. It read "pr-40 [base=main]" before this commit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Implements complete session state export/import functionality allowing users to save and share analysis sessions including variables, queries, and settings.

- Add SessionSnapshot data model for serializable state
- Add SessionExporter service with JSON export support
- Add SessionImporter service with path remapping
- Add export/import commands to CommandDispatcher
- Add comprehensive help documentation
- Add tab completion for new commands
- Add integration tests for roundtrip export/import
- Update all documentation (README, tutorial, usage guide)

Export options: --include-results, --max-rows, --format json
Import options: --alias, --remap-path

Use cases: save progress, share with team, create templates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator Author

Rebased this PR onto current main and diagnosed the original JDK 21 CI failure.

Rebase: jb/sessions was 8 months stale (branched 2026-01-09, base 2249e07). Rebased cleanly onto main (bc55bd5) with a few conflicts from the shell-core module split that happened in between:

  • CLAUDE.md now redirects to AGENTS.md; moved this PR's feature description there instead of reviving the old file.
  • CommandDispatcher.java / OptionCompleter.java: merged import lists and option-completion entries added independently on both sides.
  • API drift from the module split (SessionManager/Session became generic to support pprof/hprof, LazyQueryValue moved out of VariableStore, getAvailableEventTypes() renamed to getAvailableTypes()): updated SessionExporter, CommandDispatcher, and SessionExportImportTest to match.

JDK 21 failure diagnosis: the CI matrix only runs spotlessCheck on the JDK 21 leg (JDK 8 excludes it explicitly). This PR's new files (SessionImporter.java and SessionExportImportTest.java) had formatting violations — an unused same-package import and two lines exceeding the wrap width — that spotlessCheck would have caught but were never run through spotlessApply before the original push. That's the most likely root cause of the original JDK 21 job failing while JDK 8 passed (JDK 8 doesn't run that check). Ran spotlessJavaApply to fix.

Verification: :jfr-shell:compileJava, :jfr-shell:compileTestJava, and spotlessJavaCheck all pass. Ran the full :jfr-shell:test suite (719 tests, 84 classes) — 56 classes pass cleanly; the other 28 fail solely because this sandbox can't reach Dropbox to fetch the binary JFR test fixtures (test-ap.jfr/test-jfr.jfr/test-dd.jfr, egress-blocked here), confirmed by tracing every failure back to that same missing-file cause. The new SessionExportImportTest itself passes (its two tests self-skip gracefully when the fixture is absent, by design). Note: spotlessGroovy couldn't be verified here either (same network restriction, unrelated dependency), so worth a final CI run to confirm the Groovy build-script formatting is untouched.


Generated by Claude Code

The shell-core module split (after this branch's base) made SessionManager
and Session generic to support pprof/hprof backends and moved LazyQueryValue
out of VariableStore. Update SessionExporter, CommandDispatcher, and the
export/import test to compile against the current API, and apply spotless
formatting that was missing from the original commit.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DWghAjvEb1zR5BLkxz3LWm
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI AI-generated code or contributions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants