Skip to content

Add V3→V2 boundary check tool#221

Merged
em3s merged 11 commits intomainfrom
feature/v3v2-boundary-check
Mar 26, 2026
Merged

Add V3→V2 boundary check tool#221
em3s merged 11 commits intomainfrom
feature/v3v2-boundary-check

Conversation

@em3s
Copy link
Copy Markdown
Contributor

@em3s em3s commented Mar 25, 2026

Summary

Tool to find V3→V2 direct dependencies — candidates for decoupling via adapter abstractions (same pattern as #201).

Note

Remove this tool when dependencies reach zero.

Related: #200, #201

Changes

  • Add tools/v3v2-boundary-check Gradle subproject (Kotlin + ASM)
    • Config.kt — V2 target classes, exclude/include rules, adapter class prefixes
    • BoundaryCheck.kt — bytecode call graph extraction + reports
  • Include subproject in settings.gradle.kts

How it works

  1. Loads .class files, builds class hierarchy for virtual dispatch resolution
  2. Maps Kotlin inner classes (lambdas) back to enclosing methods
  3. Finds all callers of 30 V2 target classes via bytecode instructions (method calls + field access)

Two reports

By Class — which V3 classes directly call V2 targets

  • Class exclude (V2Backed*, V2Compat*) — adapter/bridge classes, always OK
  • Package include (v2.engine.v3) — overrides exclude for monitoring
  • Package exclude (v2.engine, v2.core, server.api.graph.v2) — V2 internals OK

By Path — which V3 API paths have V2 dependencies

  • Auto-scans all classes for Spring annotations to discover /graph/v3 endpoints
  • BFS from each endpoint method to detect reachable V2 target classes
  • Stops at adapter classes (V2Backed*, V2Compat*) — calls through adapters are not direct dependencies
  • Groups by path with HTTP methods

How to Test

./gradlew :tools:v3v2-boundary-check:run                     # summary
./gradlew :tools:v3v2-boundary-check:run --args="--verbose"   # detailed

em3s and others added 2 commits March 25, 2026 18:40
Bytecode-level static analysis tool (ASM) that finds V3→V2 direct calls
bypassing the adapter layer. Validates decoupling progress from #200/#201.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Mar 25, 2026
…l detection

Instead of classifying all 134 packages into v3/adapter/v2/shared,
detect leaks by finding all callers of Graph class and applying
exclude/include rules:

1. Class exclude (V2Backed*) — adapter classes always OK
2. Package include (v2.engine.v3) — overrides exclude for monitoring
3. Package exclude (v2.engine, server.api.graph.v2) — V2 internals OK
4. Everything else calling Graph = leak

Config reduced from 208 lines to 38 lines. Validated against pre-#201
code: correctly detects V3MutationService as leak (6 edges).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@em3s em3s changed the title Add V3→V2 direct call detector Add V3→V2 boundary check tool Mar 25, 2026
em3s and others added 8 commits March 25, 2026 20:47
Track direct references to Graph, Entity classes, DDL requests,
StorageType, and ScanFilter — not just Graph alone. Reveals 103 leaks
across 6 classes (was 25/4 with Graph-only).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Prepare for renaming V3Compat*/V3MetadataConverter/V3TableDescriptor
to V2Compat* convention. Once renamed, these bridge classes will be
automatically excluded from leak detection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add 11 v2.core type/metadata classes to targets (Direction, Field, etc.)
- Add v2.core to excluded packages (V2 internal usage is OK)
- Track GETSTATIC/GETFIELD/PUTSTATIC/PUTFIELD for enum constants and
  field access, not just method calls
- Include <init> calls (constructor usage = direct V2 dependency)

176 leaks across 7 classes (was 103/6 with method-calls-only).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Default output shows class names and edge counts only.
Pass -Pverbose for full method-level detail.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-scan all classes for Spring MVC endpoints (no manual seed list)
- Filter to /graph/v3 paths, BFS trace to V2 target classes
- Skip adapter classes (V2Backed*, V2Compat*) during traversal
- Group output by path with HTTP methods: /path (GET, POST)
- Unify terminology: "leak/boundary" → "V2 dependency"
- Default shows both by-class and by-path reports
- --verbose shows call chains

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Auto-scan all endpoints instead of manual seed list
- Extract shared targets set as lazy field
- Merge annPaths/annMethods into generic annStrings/annEnums
- Add isAdapter() helper, Endpoint.controller property
- Simplify report grouping

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@em3s
Copy link
Copy Markdown
Contributor Author

em3s commented Mar 26, 2026

current output:

$  ./gradlew :tools:v3v2-boundary-check:run

> Task :tools:v3v2-boundary-check:run
=== V2 Dependencies by Class ===

  176 edges, 7 classes

  [1] com.kakao.actionbase.server.api.graph.v3.datastore.hbase.DatastoreHBaseService (13 edges)
  [2] com.kakao.actionbase.server.api.graph.v3.metadata.TableCreateRequest (2 edges)
  [3] com.kakao.actionbase.server.api.graph.v3.metadata.V3CompatService (43 edges)
  [4] com.kakao.actionbase.server.api.graph.v3.metadata.V3MetadataConverter (60 edges)
  [5] com.kakao.actionbase.server.configuration.GraphConfiguration (2 edges)
  [6] com.kakao.actionbase.v2.engine.v3.V3QueryService (27 edges)
  [7] com.kakao.actionbase.v2.engine.v3.V3TableDescriptor (9 edges)

=== V2 Dependencies by Path ===

  13/24 paths with direct V2 dependencies

  DatabaseController — /graph/v3/databases
  DatabaseController — /graph/v3/databases/{database}
  AliasController — /graph/v3/databases/{database}/aliases
  AliasController — /graph/v3/databases/{database}/aliases/{alias}
  TableController — /graph/v3/databases/{database}/tables
  TableController — /graph/v3/databases/{database}/tables/{table}
  EdgeQueryController — /graph/v3/databases/{database}/tables/{table}/edges/agg/{group}
  EdgeQueryController — /graph/v3/databases/{database}/tables/{table}/edges/count
  EdgeQueryController — /graph/v3/databases/{database}/tables/{table}/edges/counts
  EdgeQueryController — /graph/v3/databases/{database}/tables/{table}/edges/get
  EdgeQueryController — /graph/v3/databases/{database}/tables/{table}/edges/scan/{index}
  MultiEdgeQueryController — /graph/v3/databases/{database}/tables/{table}/multi-edges/ids
  QueryController — /graph/v3/query

@em3s em3s merged commit 01bb1c3 into main Mar 26, 2026
7 checks passed
eazyhozy pushed a commit that referenced this pull request Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant