The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
57 lines
3.3 KiB
Plaintext
57 lines
3.3 KiB
Plaintext
# 락파일이 고정한 좌표에서 클래스패스를 만든다. Gradle 실행 없이 재현된다.
|
|
spring-data-jpa 4.0.7 -> <cache>/org.springframework.data/spring-data-jpa/4.0.7/spring-data-jpa-4.0.7.jar
|
|
spring-data-commons 4.0.7 -> <cache>/org.springframework.data/spring-data-commons/4.0.7/spring-data-commons-4.0.7.jar
|
|
querydsl-core 5.1.0 -> <cache>/com.querydsl/querydsl-core/5.1.0/querydsl-core-5.1.0.jar
|
|
querydsl-jpa 5.1.0 -> <cache>/com.querydsl/querydsl-jpa/5.1.0/querydsl-jpa-5.1.0-jakarta.jar
|
|
spring-core 7.0.9 -> <cache>/org.springframework/spring-core/7.0.9/spring-core-7.0.9.jar
|
|
spring-tx 7.0.9 -> <cache>/org.springframework/spring-tx/7.0.9/spring-tx-7.0.9.jar
|
|
jakarta.persistence-api 3.2.0 -> <cache>/jakarta.persistence/jakarta.persistence-api/3.2.0/jakarta.persistence-api-3.2.0.jar
|
|
slf4j-api 2.0.18 -> <cache>/org.slf4j/slf4j-api/2.0.18/slf4j-api-2.0.18.jar
|
|
# app-bootstrap 의 락파일에 querydsl 이 있는가: 0
|
|
|
|
# 제한 없음 명세 팩토리가 어느 람다에 링크되는가
|
|
BootstrapMethods:
|
|
0: #232 REF_invokeStatic java/lang/invoke/LambdaMetafactory.altMetafactory:(Ljava/lang/invoke/MethodHandles$
|
|
Method arguments:
|
|
#233 (Ljakarta/persistence/criteria/Root;Ljakarta/persistence/criteria/CriteriaQuery;Ljakarta/persistenc
|
|
#236 REF_invokeStatic org/springframework/data/jpa/domain/Specification.lambda$0:(Ljakarta/persistence/c
|
|
#237 (Ljakarta/persistence/criteria/Root;Ljakarta/persistence/criteria/CriteriaQuery;Ljakarta/persistenc
|
|
# 그 람다의 본문
|
|
private static jakarta.persistence.criteria.Predicate lambda$0(jakarta.persistence.criteria.Root, jakarta.persistence.criteria.CriteriaQuery, jakarta.persistence.criteria.CriteriaBuilder);
|
|
Code:
|
|
0: aconst_null
|
|
1: areturn
|
|
|
|
# 그 명세와 자바 널을 두 검사에 각각 넣는다
|
|
Specification.unrestricted() 가 널인가 : false
|
|
그 명세의 toPredicate 가 돌려주는 값 : null
|
|
requireBounded(토큰 없이) : 통과
|
|
requirePredicate : 통과
|
|
requireBounded(널 명세) : 거절 — a specification query requires a bounded predicate, or the explicit 'allow-unbounded-scan' token
|
|
requirePredicate(널 명세) : 거절 — a specification query requires a bounded predicate
|
|
|
|
# 페이지 경계 검사는 그대로 남아 있다
|
|
34: if (pageable.isUnpaged()) {
|
|
35- throw new IllegalArgumentException(
|
|
36- "a specification query requires a bounded page; unpaged reads whatever the table holds");
|
|
37- }
|
|
# 반면 requirePredicate 는 Pageable 을 받지 않는다
|
|
47: public static void requirePredicate(Specification<?> specification) {
|
|
|
|
# 형제 정책에 Querydsl 쪽 대응물을 넣는다
|
|
빈 BooleanBuilder 가 널인가 : false
|
|
hasValue : false
|
|
PredicatePolicy 판정 : 통과
|
|
|
|
# 형제 쪽 진입점은 항상 limit 을 붙이고, 그 리프에서 Querydsl 은 compileOnly 다
|
|
JPAQuery<T> query = queryFactory.selectFrom(root);
|
|
if (predicate != null) {
|
|
query = query.where(predicate);
|
|
}
|
|
return query.offset(page.offset()).limit(page.size()).setHint(COMMENT_HINT, name.value());
|
|
}
|
|
69: compileOnly 'com.querydsl:querydsl-jpa:5.1.0:jakarta'
|
|
* <p>Querydsl is an Advanced opt-in and is {@code compileOnly} for this leaf, so the Stable runtime
|
|
* classpath never carries it. A deployment that wants it adds the artifact; one that does not is
|
|
* unaffected by the existence of this class.
|