mcpField
J
java

java

github.com/claude-dev-suiteDevelopment4643 installsUpdated 4d ago
Repository

About java

A Java core knowledge skill for developers, with examples spanning modern language features, coding patterns, quality checks, and production readiness. It also summarizes static-analysis tools, testing, error handling, performance, and troubleshooting.

Key features

  1. 01Modern Java language examples
  2. 02Collections and stream patterns
  3. 03Static-analysis and style references
  4. 04Production-readiness practices
  5. 05Testing and performance guidance
  6. 06Troubleshooting common errors

Use cases

  1. 01Reviewing modern Java language patterns
  2. 02Selecting static-analysis rules
  3. 03Preparing a service for production
  4. 04Investigating common Java runtime issues

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/claude-dev-suite/claude-dev-suite --skill java

After installing, type/javain Claude Code to confirm it loaded.

Details

From the project README

Java Core Knowledge

Modern Java Features (17+)

// Records (immutable data classes)
public record User(Long id, String name, String email) {}

// Sealed classes
public sealed interface Shape permits Circle, Rectangle {}
public final class Circle implements Shape { }
public final class Rectangle implements Shape { }

// Pattern matching for instanceof
if (obj instanceof String s) {
    System.out.println(s.toUpperCase());
}

// Switch expressions
String result = switch (status) {
    case ACTIVE -> "Active";
    case INACTIVE -> "Inactive";
    default -> "Unknown";
};

// Text blocks
String json = """
    {
        "name": "John",
        "age": 30
    }
    """;

Collections & Streams

// Stream operations
List<String> names = users.stream()
    .filter(u -> u.isActive())
    .map(User::getName)
    .sorted()
    .collect(Collectors.toList());

// Grouping
Map<Status, List<User>> byStatus = users.stream()
    .collect(Collectors.groupingBy(User::getStatus));

// Optional handling
Optional<User> user = findById(id);
String name = user.map(User::getName).orElse("Unknown");

Common Patterns

// Builder pattern
User user = User.builder()
    .name("John")
    .email("[email protected]")
    .build();

// Factory method
public static User of(String name, String email) {
    return new User(null, name, email);
}

// Dependency Injection (constructor)
@Service
public class UserService {
    private final UserRepository repository;

    public UserService(UserRepository repository) {
        this.repository = repository;
    }
}

Exception Handling

// Custom exception
public class UserNotFoundException extends RuntimeException {
    public UserNotFoundException(Long id) {
        super("User not found: " + id);
    }
}

// Try-with-resources
try (var reader = new BufferedReader(new FileReader(file))) {
    return reader.lines().collect(Collectors.toList());
}

Static Analysis & Linting

Official Rules References
ToolRules CountDocumentation
SonarJava733https://rules.sonarsource.com/java/
Checkstyle200+https://checkstyle.org/checks.html
PMD400+https://pmd.github.io/latest/pmd_rules_java.html
SpotBugs400+https://spotbugs.readthedocs.io/en/latest/bugDescriptions.html
Style Guides
GuideLink
Google Java Stylehttps://google.github.io/styleguide/javaguide.html
Oracle Code Conventionshttps://www.oracle.com/java/technologies/javase/codeconventions-contents.html
Key Rules Categories
<!-- pom.xml - Maven Checkstyle Plugin -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>3.3.1</version>
    <configuration>
        <configLocation>google_checks.xml</configLocation>
    </configuration>
</plugin>
Critical Rules to Enable
CategoryRuleTool
BugNullPointerException risksSonarJava S2259
BugResource leaksSonarJava S2095
SecuritySQL InjectionSonarJava S3649
SecurityHardcoded credentialsSonarJava S2068
MaintainabilityCognitive complexitySonarJava S3776
MaintainabilityToo many parametersCheckstyle

Production Readiness

Error Handling
// Custom exception hierarchy
public abstract class BaseException extends RuntimeException {
    private final String errorCode;
    private final int httpStatus;

    protected BaseException(String message, String errorCode, int httpStatus) {
        super(message);
        this.errorCode = errorCode;
        this.httpStatus = httpStatus;
    }

    public String getErrorCode() { return errorCode; }
    public int getHttpStatus() { return httpStatus; }
}

public class EntityNotFoundException extends BaseException {
    public EntityNotFoundException(String entity, Object id) {
        super(
            String.format("%s not found with id: %s", entity, id),
            "NOT_FOUND",
            404
        );
    }
}

// Global exception handler
@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(BaseException.class)
    public ResponseEntity<ErrorResponse> handleBaseException(BaseException ex) {
        log.warn("Business error: {}", ex.getMessage());
        return ResponseEntity
            .status(ex.getHttpStatus())
            .body(new ErrorResponse(ex.getErrorCode(), ex.getMessage()));
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<ErrorResponse> handleUnexpected(Exception ex) {
        log.error("Unexpected error", ex);
        return ResponseEntity
            .status(500)
            .body(new ErrorResponse("INTERNAL_ERROR", "An unexpected error occurred"));
    }
}
Null Safety
// Use Optional properly
public Optional<User> findById(Long id) {
    return repository.findById(id);
}

// Never return null from Optional
public User getById(Long id) {
    return findById(id)
        .orElseThrow(() -> new EntityNotFoundException("User", id));
}

// Use @Nullable and @NonNull annotations
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

public User updateUser(@NonNull Long id, @Nullable String email) {
    User user = getById(id);
    if (email != null) {
        user.setEmail(email);
    }
    return repository.save(user);
}

// Validation
import jakarta.validation.constraints.*;

public record CreateUserRequest(
    @NotBlank @Size(min = 2, max = 100) String name,
    @NotBlank @Email String email,
    @NotNull @Min(0) Integer age
) {}
Logging
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

@Service
public class UserService {
    private static final Logger log = LoggerFactory.getLogger(UserService.class);

    public User createUser(CreateUserRequest request) {
        MDC.put("operation", "createUser");
        MDC.put("email", request.email());

        log.info("Creating user");

        try {
            User user = userRepository.save(User.from(request));
            log.info("User created successfully: {}", user.getId());
            return user;
        } catch (Exception e) {
            log.error("Failed to create user", e);
            throw e;
        } finally {
            MDC.clear();
        }
    }
}
Testing
// Unit test with Mockito
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
    @Mock
    private UserRepository repository;

    @InjectMocks
    private UserService service;

    @Test
    void shouldCreateUser() {
        // Given
        var request = new CreateUserRequest("John", "[email protected]", 30);
        var expected = new User(1L, "John", "[email protected]", 30);
        when(repository.save(any())).thenReturn(expected);

        // When
        var result = service.createUser(request);

        // Then
        assertThat(result).isEqualTo(expected);
        verify(repository).save(any());
    }

    @Test
    void shouldThrowWhenUserNotFound() {
        // Given
        when(repository.findById(1L)).thenReturn(Optional.empty());

        // When/Then
        assertThatThrownBy(() -> service.getById(1L))
            .isInstanceOf(EntityNotFoundException.class)
            .hasMessageContaining("User not found");
    }
}

// Integration test
@SpringBootTest
@AutoConfigureMockMvc
@Testcontainers
class UserControllerIT {
    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16-alpine");

    @Autowired
    private MockMvc mockMvc;

    @Test
    void shouldCreateUser() throws Exception {
        mockMvc.perform(post("/api/users")
                .contentType(MediaType.APPLICATION_JSON)
                .content("""
                    {"name": "John", "email": "[email protected]", "age": 30}
                    """))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.id").exists());
    }
}
Performance
// Connection pooling (HikariCP)
// application.yml
spring:
  datasource:
    hikari:
      maximum-pool-size: 10
      minimum-idle: 5
      connection-timeout: 30000
      idle-timeout: 600000

// Caching
@Cacheable(value = "users", key = "#id")
public User findById(Long id) {
    return repository.findById(id).orElseThrow();
}

@CacheEvict(value = "users", key = "#user.id")
public User save(User user) {
    return repository.save(user);
}
Monitoring Metrics
MetricTarget
Test coverage> 80%
Cyclomatic complexity< 10
SonarQube bugs0
Security vulnerabilities0
Checklist
  • Custom exception hierarchy
  • Global exception handler
  • Bean validation on DTOs
  • Optional for nullable returns
  • @NonNull/@Nullable annotations
  • Structured logging with MDC
  • Unit tests with Mockito
  • Integration tests with Testcontainers
  • Connection pool configured
  • Caching for hot data

When NOT to Use This Skill

ScenarioUse Instead
Spring Boot frameworkbackend-spring-boot skill
Lombok annotationslombok skill
MapStruct mappingmapstruct skill
JPA/HibernateORM-specific skills
Testing with JUnittesting-junit skill

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Returning nullNullPointerExceptionUse Optional
Catching generic ExceptionHides specific errorsCatch specific exceptions
Not closing resourcesResource leaksUse try-with-resources
Mutable static fieldsThread-safety issuesUse immutable or synchronized
String concatenation in loopsO(n²) performanceUse StringBuilder
Empty catch blocksSilent failuresLog or rethrow
Using == for stringsCompares referencesUse .equals()
Not overriding equals/hashCodeBroken collectionsOverride both or neither

Quick Troubleshooting

IssueCauseSolution
NullPointerExceptionAccessing null referenceCheck for null, use Optional
ClassCastExceptionWrong type castUse instanceof before casting
ConcurrentModificationExceptionModifying while iteratingUse Iterator.remove()
OutOfMemoryErrorHeap exhaustedIncrease heap, fix memory leaks
StackOverflowErrorInfinite recursionAdd base case, use iteration
"Cannot find symbol"Compilation errorCheck imports, spelling
DeadlockCircular lock dependencyUse consistent lock ordering
Resource leakNot closing streamsUse try-with-resources

Reference Documentation

Comments

Markdown supported