internal/skills/content/java-guide/SKILL.md
Java language guardrails, patterns, and best practices for AI-assisted development. Use when working with Java files (.java), pom.xml, build.gradle, or when the user mentions Java. Provides modern Java patterns (records, sealed classes, streams), testing standards, and Spring conventions specific to this project's coding standards.
npx skillsauth add ar4mirez/samuel java-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Applies to: Java 17+, Spring Boot, Maven/Gradle, Enterprise Applications
final fields, and unmodifiable collectionsObjects.requireNonNull liberallyjava.util, java.time, java.nio before adding dependenciespom.xml) or Gradle (build.gradle.kts)1.+)mvn dependency:analyze or gradle dependencies to detect unused/undeclared depsmvn org.owasp:dependency-check-maven:checkPascalCase | Methods/fields: camelCase | Constants: UPPER_SNAKE_CASEcom.company.project.module (lowercase, no underscores)var for local variables only when the type is obvious from the right sideimport java.util.* is forbidden)record for immutable data carriers instead of manual POJOssealed classes/interfaces for restricted type hierarchiesswitch expressions with pattern matchingpublic record UserId(String value) {
public UserId {
Objects.requireNonNull(value, "UserId must not be null");
if (value.isBlank()) {
throw new IllegalArgumentException("UserId must not be blank");
}
}
}
public sealed interface PaymentResult
permits PaymentResult.Success, PaymentResult.Declined, PaymentResult.Error {
record Success(String transactionId, BigDecimal amount) implements PaymentResult {}
record Declined(String reason) implements PaymentResult {}
record Error(Exception cause) implements PaymentResult {}
}
Optional.get() -- use orElseThrow(), orElse(), map(), flatMap()Optional as a method parameter or field type (only as a return type)toList() (Java 16+) over collect(Collectors.toList())List<String> activeEmails = users.stream()
.filter(User::isActive)
.map(User::email)
.toList();
String displayName = userRepository.findById(id)
.map(User::displayName)
.orElseThrow(() -> new UserNotFoundException(id));
AutoCloseable typesfinalize() (deprecated and unreliable)try (var connection = dataSource.getConnection();
var statement = connection.prepareStatement(sql);
var resultSet = statement.executeQuery()) {
while (resultSet.next()) {
results.add(mapRow(resultSet));
}
}
myproject/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/com/company/project/
│ │ │ ├── Application.java # Entry point
│ │ │ ├── config/ # Configuration classes
│ │ │ ├── controller/ # REST controllers / API layer
│ │ │ ├── service/ # Business logic
│ │ │ ├── repository/ # Data access
│ │ │ ├── model/ # Domain entities and records
│ │ │ ├── dto/ # Data transfer objects (records)
│ │ │ └── exception/ # Custom exceptions
│ │ └── resources/
│ │ ├── application.yml
│ │ └── db/migration/ # Flyway/Liquibase migrations
│ └── test/java/com/company/project/ # Mirrors main structure
└── target/ # Build output (gitignored)
resources/ flat; use db/migration/ for schema changespublic static double area(Shape shape) {
return switch (shape) {
case Shape.Circle c -> Math.PI * c.radius() * c.radius();
case Shape.Rectangle r -> r.width() * r.height();
case Shape.Triangle t -> 0.5 * t.base() * t.height();
};
}
List<String> roles = List.of("ADMIN", "USER", "GUEST");
Map<String, String> config = Map.ofEntries(
Map.entry("host", "localhost"),
Map.entry("port", "8080"));
List<Item> snapshot = List.copyOf(mutableList);
String query = """
SELECT u.id, u.email, u.created_at
FROM users u
WHERE u.active = true
ORDER BY u.created_at DESC
LIMIT ?
""";
// Fallback chain: cache -> database -> remote
User user = cache.findUser(id)
.or(() -> database.findUser(id))
.or(() -> remoteService.fetchUser(id))
.orElseThrow(() -> new UserNotFoundException(id));
// Conditional execution without get()
userRepository.findById(userId)
.ifPresentOrElse(
u -> log.info("Found user: {}", u.name()),
() -> log.warn("User {} not found", userId));
src/test/javaClassNameTest (not TestClassName)@Test void shouldDescribeBehavior()@DisplayName for complex scenarios, @Nested to group related testsclass UserServiceTest {
private UserRepository userRepository;
private UserService userService;
@BeforeEach
void setUp() {
userRepository = mock(UserRepository.class);
userService = new UserService(userRepository);
}
@Test
void shouldReturnUserWhenFound() {
var expected = new User("1", "[email protected]", "Alice");
when(userRepository.findById("1")).thenReturn(Optional.of(expected));
User result = userService.getUser("1");
assertThat(result).isEqualTo(expected);
verify(userRepository).findById("1");
}
@Test
void shouldThrowWhenUserNotFound() {
when(userRepository.findById("999")).thenReturn(Optional.empty());
assertThatThrownBy(() -> userService.getUser("999"))
.isInstanceOf(UserNotFoundException.class)
.hasMessageContaining("999");
}
}
@ParameterizedTest
@CsvSource({
"[email protected], true",
"[email protected], true",
"invalid-email, false",
"'', false",
})
void shouldValidateEmail(String email, boolean expected) {
assertThat(EmailValidator.isValid(email)).isEqualTo(expected);
}
@ParameterizedTest
@MethodSource("provideMoneyAdditions")
void shouldAddMoneySameCurrency(Money a, Money b, Money expected) {
assertThat(a.add(b)).isEqualTo(expected);
}
static Stream<Arguments> provideMoneyAdditions() {
var usd = Currency.getInstance("USD");
return Stream.of(
Arguments.of(new Money(BigDecimal.ONE, usd),
new Money(BigDecimal.TEN, usd),
new Money(new BigDecimal("11"), usd))
);
}
mvn clean install # Build and install locally
mvn test # Run all tests
mvn verify # Run tests + integration tests
mvn dependency:tree # Show dependency tree
mvn dependency:analyze # Find unused/undeclared deps
mvn spotbugs:check # Static analysis
mvn checkstyle:check # Style check
./gradlew build # Full build with tests
./gradlew test # Run unit tests
./gradlew check # Run all verification tasks
./gradlew dependencies # Show dependency tree
./gradlew jacocoTestReport # Generate coverage report
For detailed patterns and examples, see:
development
Zig language guardrails, patterns, and best practices for AI-assisted development. Use when working with Zig files (.zig), build.zig, or when the user mentions Zig. Provides comptime patterns, allocator conventions, C interop guidelines, and testing standards specific to this project's coding standards.
tools
WordPress framework guardrails, patterns, and best practices for AI-assisted development. Use when working with WordPress projects, or when the user mentions WordPress. Provides theme development, plugin architecture, REST API, blocks, and security guidelines.
tools
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs. Use when testing web apps, automating browser interactions, or debugging frontend issues.
tools
Suite of tools for creating elaborate, multi-component web applications using modern frontend technologies (React, Tailwind CSS, shadcn/ui). Use for complex projects requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX pages.