Claude-skill-registry cui-java-core
Core Java development standards for CUI projects including coding patterns, null safety, Lombok, modern features, and logging
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cui-java-core" ~/.claude/skills/majiayu000-claude-skill-registry-cui-java-core && rm -rf "$T"
skills/data/cui-java-core/SKILL.mdCUI Java Core Development Skill
Foundational Java development standards for all CUI projects, covering core patterns, null safety, Lombok usage, modern Java features, and the CUI logging framework.
Workflow
Step 1: Load Core Java Standards
CRITICAL: Load all foundational Java standards (always required for Java development).
Read: standards/java-core-patterns.md Read: standards/java-null-safety.md Read: standards/java-lombok-patterns.md Read: standards/java-modern-features.md Read: standards/logging-standards.md
These standards are fundamental to all CUI Java development and should be loaded together for consistent, comprehensive guidance.
Step 2: Load Additional Knowledge (Optional)
When needed: Load domain-specific knowledge on demand.
DSL-Style Constants (load when needed):
Read: standards/dsl-constants.md
Use when: Implementing LogMessages classes, creating structured constant hierarchies, or needing guidance on organizing related constants with nested static classes and the @UtilityClass pattern.
LogMessages Documentation (load when needed):
Read: standards/logmessages-documentation.md
Use when: Writing or maintaining AsciiDoc documentation for LogMessages classes, or needing guidance on documenting log message standards.
CUI HTTP Client (load when needed):
Read: standards/cui-http.md
Use when: Working with HTTP client code, implementing HTTP request/response handling, or needing guidance on the HttpResult pattern, retry logic, ETag caching, or HTTP error handling.
Step 3: Extract Key Requirements
From all loaded standards, extract and organize:
-
Core Patterns:
- Code organization (packages, classes, methods)
- Naming conventions
- Exception handling patterns
- Best practices for immutability and collections
- Parameter object guidelines
-
Null Safety:
- @NullMarked package configuration
- API return type patterns (non-null vs Optional)
- Implementation requirements
- Nullable parameter handling
-
Lombok Patterns:
- @Delegate for delegation over inheritance
- @Builder for complex objects
- @Value for immutable objects
- When to use each annotation
-
Modern Features:
- Records for data carriers
- Switch expressions
- Stream processing patterns
- Text blocks and pattern matching
- Optional enhancements
-
Logging:
- CuiLogger configuration
- LogRecord usage and organization
- Log level guidelines
- Exception logging patterns
Step 4: Analyze Existing Code (if applicable)
If working with existing Java code:
-
Assess standards compliance:
- Check null-safety annotations (@NullMarked in package-info.java)
- Verify logger configuration (CuiLogger, not SLF4J)
- Review Lombok usage (appropriate annotations)
- Check for modern Java features (records, switch expressions)
- Review exception handling patterns
-
Identify improvement opportunities:
- Missing null-safety annotations
- Legacy logging (System.out, SLF4J annotations)
- Inefficient patterns (deep inheritance, god classes)
- Missing modern features (classic switch, manual data classes)
- Verbose boilerplate that Lombok could handle
-
Check code organization:
- Package structure (feature-based)
- Class responsibilities (Single Responsibility Principle)
- Method sizes (< 50 lines preferred)
- Parameter counts (≤ 3 preferred)
Step 5: Write/Refactor Java Code According to Standards
When writing or refactoring Java code:
-
Apply core patterns:
- Organize packages by feature
- Keep classes focused and small
- Use meaningful names throughout
- Handle exceptions appropriately
- Prefer immutability
- Use parameter objects for 3+ parameters
-
Implement null safety:
- Add @NullMarked to package-info.java
- Never use @Nullable for return types (use Optional instead)
- Add defensive null checks at API boundaries
- Use Objects.requireNonNull() for validation
- Document null-safety contracts
-
Use Lombok appropriately:
- @Delegate for composition over inheritance
- @Builder for classes with 3+ parameters or optional parameters
- @Value for immutable value objects and DTOs
- @UtilityClass for utility classes
- Consider records vs @Value for simple data carriers
-
Apply modern Java features:
- Use records for simple immutable data carriers
- Replace classic switch with switch expressions
- Use streams for complex data transformations
- Apply text blocks for multi-line strings
- Use pattern matching for instanceof
- Leverage modern collection factories (List.of(), Set.of())
-
Implement CUI logging:
- Declare logger:
private static final CuiLogger LOGGER = new CuiLogger(YourClass.class); - Create LogMessages class for structured logging
- Use LogRecord for INFO/WARN/ERROR/FATAL
- Exception parameter always comes first
- Use %s for all string substitutions
- Organize identifiers by log level ranges
- Declare logger:
Step 6: Verify Standards Compliance
Before completing the task:
-
Core patterns check:
- Classes follow Single Responsibility Principle
- Methods are short and focused (< 50 lines)
- Meaningful names used throughout
- Exception handling is appropriate
- Immutability used where possible
- No magic numbers or god classes
-
Null safety check:
- @NullMarked in package-info.java
- No @Nullable used for return types
- Optional used for "no result" scenarios
- Defensive null checks at API boundaries
- Unit tests verify non-null contracts
-
Lombok check:
- @Builder used for complex construction
- @Value used for immutable objects
- @Delegate used for composition
- No @Slf4j or logging annotations (use CuiLogger)
-
Modern features check:
- Records used for simple data carriers
- Switch expressions used instead of statements
- Streams used appropriately
- Text blocks used for multi-line strings
- Modern collection factories used
-
Logging check:
- CuiLogger used (not SLF4J/Log4j)
- Logger is private static final named LOGGER
- LogRecord used for important messages
- Exception parameter comes first
- %s used for substitutions
- No System.out or System.err
-
Run build and tests:
Task: subagent_type: maven-builder description: Build and verify project prompt: | Execute Maven build to verify all tests pass and code compiles correctly. Parameters: - command: clean verify CRITICAL: Wait for build to complete. Inspect results and respond to any failures.
Step 7: Report Results
Provide summary of:
- Standards applied: Which core Java standards were followed
- Code improvements: Changes made to align with standards
- Null safety: Package-level @NullMarked and Optional usage
- Lombok usage: Which annotations were applied and why
- Modern features: Records, switch expressions, streams implemented
- Logging: CuiLogger and LogRecord implementation
- Build verification: Confirm successful build and test execution
Common Patterns and Examples
Complete Class Example
// package-info.java @NullMarked package de.cuioss.portal.authentication; import org.jspecify.annotations.NullMarked; // TokenValidator.java import de.cuioss.tools.logging.CuiLogger; import static de.cuioss.portal.authentication.TokenLogMessages.INFO; import static de.cuioss.portal.authentication.TokenLogMessages.ERROR; @Value @Builder public class TokenValidator { private static final CuiLogger LOGGER = new CuiLogger(TokenValidator.class); String issuer; @Builder.Default Duration validity = Duration.ofHours(1); public ValidationResult validate(String token) { Objects.requireNonNull(token, "token must not be null"); try { String userId = extractUserId(token); boolean isValid = performValidation(token); if (isValid) { LOGGER.info(INFO.VALIDATION_SUCCESS, userId); return ValidationResult.valid(); } LOGGER.error(ERROR.VALIDATION_FAILED, userId, "Invalid signature"); return ValidationResult.invalid("Invalid signature"); } catch (TokenException e) { LOGGER.error(e, ERROR.VALIDATION_FAILED, "unknown", e.getMessage()); throw new ValidationException("Validation failed", e); } } public Optional<UserInfo> extractUserInfo(String token) { return parseToken(token).map(this::extractUser); } }
LogMessages Example
@UtilityClass public final class TokenLogMessages { public static final String PREFIX = "TOKEN"; @UtilityClass public static final class INFO { public static final LogRecord VALIDATION_SUCCESS = LogRecordModel.builder() .template("Token validated successfully for user %s") .prefix(PREFIX) .identifier(1) .build(); } @UtilityClass public static final class ERROR { public static final LogRecord VALIDATION_FAILED = LogRecordModel.builder() .template("Token validation failed for user %s: %s") .prefix(PREFIX) .identifier(200) .build(); } }
Record with Validation Example
public record TokenConfig(String issuer, Duration validity, Set<String> requiredClaims) { public TokenConfig { Objects.requireNonNull(issuer, "issuer must not be null"); Objects.requireNonNull(validity, "validity must not be null"); if (validity.isNegative() || validity.isZero()) { throw new IllegalArgumentException("Validity must be positive"); } requiredClaims = Set.copyOf(requiredClaims); // Defensive copy } public static TokenConfig defaultConfig() { return new TokenConfig( "https://auth.example.com", Duration.ofHours(1), Set.of("sub", "exp") ); } }
Delegation Example
public class CachedTokenValidator implements TokenValidator { @Delegate private final TokenValidator delegate; private final Cache<String, ValidationResult> cache; public CachedTokenValidator(TokenValidator delegate) { this.delegate = delegate; this.cache = CacheBuilder.newBuilder() .expireAfterWrite(Duration.ofMinutes(5)) .build(); } @Override public ValidationResult validate(String token) { return cache.get(token, () -> delegate.validate(token)); } }
Switch Expression Example
ValidationResult validate(Token token) { return switch (token.getType()) { case JWT -> jwtValidator.validate(token); case OAUTH2 -> oauth2Validator.validate(token); case LEGACY -> ValidationResult.invalid("Legacy tokens not supported"); }; }
Stream Processing Example
List<String> activeUserNames = users.stream() .filter(User::isActive) .map(User::getName) .sorted() .toList(); Map<String, List<User>> usersByRole = users.stream() .collect(Collectors.groupingBy(User::getRole));
Common Development Tasks
Task: Create a new service class
- Load all core Java standards
- Add @NullMarked to package-info.java
- Define class with appropriate Lombok annotations (@Value/@Builder if immutable)
- Declare CuiLogger
- Create LogMessages class following DSL pattern
- Implement methods with proper null safety
- Use modern Java features (records for DTOs, switch expressions, streams)
- Write unit tests verifying behavior
- Run build using maven-builder agent
Task: Refactor existing code to standards
- Load all core Java standards
- Add @NullMarked to package-info.java if missing
- Replace SLF4J/Log4j with CuiLogger
- Apply Lombok where appropriate (@Builder, @Value, @Delegate)
- Replace classic patterns with modern features (records, switch expressions)
- Add null checks at API boundaries
- Update tests to verify compliance
- Run build and verify no regressions
Task: Add comprehensive logging
- Load logging standards and DSL constants standards
- Create LogMessages class with DSL-style nested structure
- Define LogRecord for each important message
- Organize by log level (INFO, WARN, ERROR, FATAL)
- Use correct identifier ranges
- Apply static imports in service classes
- Use LogRecord with proper exception handling
- Add test verification for log messages
- Verify no System.out or System.err usage
Error Handling
If encountering issues:
- Null pointer exceptions: Review null-safety implementation, add @NullMarked and defensive checks
- Lombok not working: Check Lombok dependency, IDE plugin, and annotation placement
- Logger errors: Verify CuiLogger setup, check exception parameter order and %s usage
- Build failures: Check modern Java feature compatibility with target Java version
- Complex refactoring: Break into smaller steps, focus on one standard at a time
References
Core Standards (always loaded):
- Core Patterns: standards/java-core-patterns.md
- Null Safety: standards/java-null-safety.md
- Lombok Patterns: standards/java-lombok-patterns.md
- Modern Features: standards/java-modern-features.md
- Logging: standards/logging-standards.md
Optional Standards (load when needed):
- DSL Constants: standards/dsl-constants.md
- LogMessages Documentation: standards/logmessages-documentation.md
- CUI HTTP Client: standards/cui-http.md