Files
spring-boot-demo/custom-validation/src/test/java/com/ankurm/customvalidation/ClasspathVersionTest.java
T
Claude e4b5636f7c Add custom-validation, etag-caching, restclient-basic-auth: Boot 4.1 API pass
Three companion modules verifying and rewriting the Boot 4.1.1 / Framework
7.0.9 story for three older articles: the javax->jakarta.validation namespace
fix plus Jakarta Validation 3.1 record-validation clarification, ETag/
conditional-request APIs re-verified unchanged plus the starter rename, and
RestTemplate Basic Auth rebuilt on RestClient with the exchange() trap called
out. 19 real passing tests generate every transcript quoted from the three
companion articles.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EQNA6DJ9VgCtW6zhCE8Xud
2026-09-19 10:17:09 +00:00

72 lines
3.5 KiB
Java

package com.ankurm.customvalidation;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Reads the real jar manifests off the classpath directly with {@link JarFile}, rather than
* trusting a version number typed into a pom.xml or a blog post -- the same "unzip the jar"
* standard used for the version-of-record facts elsewhere in this repo. {@code
* Class.getResourceAsStream("/META-INF/MANIFEST.MF")} is NOT reliable for this on a flat
* classpath (as opposed to the module path): it resolves to whichever jar's manifest the
* classloader happens to find first, not necessarily the jar the anchor class was loaded from.
* Opening the anchor class's own code-source location as a {@link JarFile} is unambiguous.
*/
class ClasspathVersionTest {
private static Manifest manifestOf(Class<?> anchor) throws IOException, URISyntaxException {
Path jarPath = Path.of(anchor.getProtectionDomain().getCodeSource().getLocation().toURI());
try (JarFile jar = new JarFile(jarPath.toFile())) {
return jar.getManifest();
}
}
@Test
void jakartaValidationApiIs3_1() throws IOException, URISyntaxException {
Class<?> anchor = jakarta.validation.Validation.class;
Path jarPath = Path.of(anchor.getProtectionDomain().getCodeSource().getLocation().toURI());
Manifest mf = manifestOf(anchor);
Attributes attrs = mf.getMainAttributes();
StringBuilder sb = new StringBuilder();
sb.append("Class: ").append(anchor.getName()).append('\n');
sb.append("Jar file: ").append(jarPath.getFileName()).append('\n');
sb.append("Bundle-SymbolicName: ").append(attrs.getValue("Bundle-SymbolicName")).append('\n');
sb.append("Bundle-Version: ").append(attrs.getValue("Bundle-Version")).append('\n');
sb.append("Implementation-Version: ").append(attrs.getValue("Implementation-Version")).append('\n');
Transcript.write("00-jakarta-validation-api-manifest.txt", sb.toString());
// The jar file name and its own manifest both say 3.1.x -- Spring Boot 4.1.1 pins
// Jakarta Validation 3.1 (renamed from "Bean Validation" in the 3.1 spec revision),
// confirmed two independent ways rather than one.
assertThat(jarPath.getFileName().toString()).startsWith("jakarta.validation-api-3.1");
}
@Test
void hibernateValidatorIs9_1() throws IOException, URISyntaxException {
Class<?> anchor = org.hibernate.validator.internal.engine.ValidatorFactoryImpl.class;
Path jarPath = Path.of(anchor.getProtectionDomain().getCodeSource().getLocation().toURI());
Manifest mf = manifestOf(anchor);
Attributes attrs = mf.getMainAttributes();
StringBuilder sb = new StringBuilder();
sb.append("Class: ").append(anchor.getName()).append('\n');
sb.append("Jar file: ").append(jarPath.getFileName()).append('\n');
sb.append("Implementation-Title: ").append(attrs.getValue("Implementation-Title")).append('\n');
sb.append("Implementation-Version: ").append(attrs.getValue("Implementation-Version")).append('\n');
Transcript.write("00b-hibernate-validator-manifest.txt", sb.toString());
assertThat(jarPath.getFileName().toString()).startsWith("hibernate-validator-9.1");
}
}