# 리프가 선언하는 export 목록 135: private static final Set EXPORTED_PACKAGES = 136- Set.of( 137- // The contracts other leaves are meant to speak. 138- "api", 139- // Capability configuration facades, each assembling its own capability's internals. 140- "notification.configuration", 141- // Cross-cutting seams a composition root legitimately wires. 142- "transaction", 143- "security", 144- "observation", 145- "migration", 146- "hibernate", 147- "fileserver", 148- "failure", 149- "config"); # 컴포지션 루트의 소비자 규칙이 같은 목록을 다시 적는다 * implementation types by name — every store, every repository, the record mapper — which made * each of them a cross-leaf source contract: moving one to another package, or reducing its * visibility, broke this module's compile. The notification wiring is a facade the leaf owns now, * and this keeps the surface from re-growing one convenient import at a time. * *

The list is the leaf's export allowlist, mirrored here because this is the consumer side of * the same boundary. {@code JpaModuleBoundaryTest} owns the definition. */ @ArchTest private static final java.util.Set EXPORTED = java.util.Set.of( "api", "notification.configuration", "transaction", "security", "observation", "migration", "hibernate", "fileserver", "failure", "config", // The two vendor entry points. A vendor configuration imports the core JPA // config rather than the reverse, so there is no single internal entry the // composition root could gate instead — inverting the import to make one // produced a package cycle. Admitting exactly these two, and no other // vendor // internals, is the narrower price. "postgresql", "h2"); # 두 집합의 차이 # 리프 10개 / 루트 12개 # 루트에만 있는 것: ['h2', 'postgresql'] # 리프에만 있는 것: [] # 사본은 정본을 이름으로 적는다 1118: * the same boundary. {@code JpaModuleBoundaryTest} owns the definition. # app-bootstrap 에서 그 정본 클래스를 언급하는 줄: 1 # 선언 파일 밖에서 EXPORTED_PACKAGES 를 참조하는 자바 코드: 0 # 리프의 export 목록을 쓰는 두 시험이 무엇을 보는가 380: @DisplayName("the export list names only packages that exist") 381- void theExportListNamesOnlyPackagesThatExist() { 382- java.nio.file.Path root = sourceRoot().resolve(ROOT.replace('.', '/')); 396: @DisplayName("every exported package is one the catalog governs") 397- void everyExportedPackageIsGoverned() { 398- Set ungoverned = new TreeSet<>();