Skip to main content

java

Use this skill when the user asks about Java build tools, Maven, Gradle, module system, records, streams, Optional, concurrency, testing, or production deployment. Focus on tooling, modern Java features, and ecosystem — not syntax.

소스 정보

저장소
j4flmao/agent-skills
최근 소스 활동
2026년 9월 1일 08:13
감지된 SKILL.md 언어
영어
스타
34
포크
3

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
10 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
java
description
Use this skill when the user asks about Java build tools, Maven, Gradle, module system, records, streams, Optional, concurrency, testing, or production deployment. Focus on tooling, modern Java features, and ecosystem — not syntax.
version
1.0.0
author
j4flmao
license
MIT
compatibility
{"claude-code":true,"cursor":true,"codex":true,"windsurf":true}
tags
["java","language","build","jvm"]
# Java ## Purpose Guide for Java build tools (Maven/Gradle), module system, modern language features (records, sealed classes, pattern matching), streams, concurrency, testing, and production deployment. ## Agent Protocol ### Trigger Keywords: `java build`, `maven`, `gradle`, `java module`, `record`, `stream`, `optional`, `completablefuture`, `junit`, `spring boot`, `jakarta`. ### Input Context - Build tool (Maven, Gradle) - Java version - Framework (Spring Boot, Quarkus, Micronaut, Jakarta EE) - Deployment target ## Decision Trees ### Build Tool Selection ``` Team preference? ├── Declarative, XML, convention → Maven (stable, predictable, standard) │ ├── pom.xml, lifecycle phases (compile, test, package) │ └── Best for: large orgs, strict conventions, established projects ├── Flexible, programmable, fast → Gradle (Kotlin DSL, incremental builds) │ ├── build.gradle.kts, task-based, build cache │ └── Best for: Android, multi-module, custom build logic └── Modern, fast, no-nonsense → Maven + mvnd (Maven Daemon, parallel builds) ``` ### Framework Selection ``` What kind of application? ├── Full-stack web app → Spring Boot (most mature, vast ecosystem, auto-config) ├── Cloud-native / low-resource → Quarkus (GraalVM native, fast startup) ├── Microservices / reactive → Micronaut (compile-time DI, AOT) ├── REST API / lightweight → JAX-RS (Jakarta REST) + Helidon / Dropwizard └── Batch processing → Spring Batch / Apache Beam ``` ### Module Strategy ``` Project size? ├── Small (<10k LOC) → Single module, package-based organization ├── Medium (10-100k LOC) → Multi-module with clear boundaries (api, core, infra) ├── Large (>100k LOC) → Java Platform Module System (JPMS) with module-info.java └── Library → Single module, minimize exports, use JPMS for strong encapsulation ``` ## Build & Dependency Management ### Maven pom.xml ```xml <project> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.0</version> </parent> <properties> <java.version>21</java.version> <maven.compiler.source>21</maven.compiler.source> <maven.compiler.target>21</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project> ``` ### Gradle build.gradle.kts ```kotlin plugins { java id("org.springframework.boot") version "3.3.0" id("io.spring.dependency-management") version "1.1.5" } java { toolchain { languageVersion = JavaLanguageVersion.of(21) } } dependencies { implementation("org.springframework.boot:spring-boot-starter-web") testImplementation("org.springframework.boot:spring-boot-starter-test") compileOnly("org.projectlombok:lombok") annotationProcessor("org.projectlombok:lombok") } ``` ### Version Catalog (Gradle) ```toml # gradle/libs.versions.toml [versions] spring-boot = "3.3.0" testcontainers = "1.19.0" [libraries] spring-boot-starter = { module = "org.springframework.boot:spring-boot-starter-web", version.ref = "spring-boot" } testcontainers = { module = "org.testcontainers:testcontainers", version.ref = "testcontainers" } ``` ## Language-Specific Patterns ### Records (Java 16+) ```java // Immutable data carrier — replaces Lombok @Data, manual POJOs public record Order(Long id, String customer, BigDecimal total, OrderStatus status) { // Compact constructor for validation public Order { if (total.compareTo(BigDecimal.ZERO) < 0) { throw new IllegalArgumentException("total must be positive"); } if (status == null) status = OrderStatus.PENDING; } // Static factory public static Order create(String customer, BigDecimal total) { return new Order(null, customer, total, OrderStatus.PENDING); } } ``` ### Sealed Classes (Java 17+) ```java // Exhaustive hierarchy — compiler knows all subtypes public sealed interface Payment permits CreditCard, PayPal, CryptoPayment {} public record CreditCard(String lastFour, String expiry) implements Payment {} public record PayPal(String email) implements Payment {} public record CryptoPayment(String walletAddress, String currency) implements Payment {} // Switch with pattern matching (Java 21+) public String processPayment(Payment payment) { return switch (payment) { case CreditCard c -> "Processing card ending in " + c.lastFour(); case PayPal p -> "Redirecting to PayPal for " + p.email(); case CryptoPayment cp -> "Verifying " + cp.currency() + " transfer"; }; } ``` ### Streams & Optional ```java // Stream pipeline List<String> activeCustomerEmails = orders.stream() .filter(Order::isPaid) .map(Order::customer) .distinct() .sorted() .toList(); // Java 16+ — no need for .collect(Collectors.toList()) // Optional usage public Customer findCustomer(Long id) { return repository.findById(id) .orElseThrow(() -> new CustomerNotFoundException(id)); } // Optional chaining String city = customer .flatMap(Customer::getAddress) .map(Address::getCity) .orElse("Unknown"); ``` ### CompletableFuture ```java public CompletableFuture<OrderResult> processOrderAsync(OrderRequest request) { return CompletableFuture .supplyAsync(() -> validateOrder(request), executor) .thenCompose(validated -> CompletableFuture.supplyAsync(() -> saveOrder(validated), executor)) .thenApplyAsync(this::enrichResult, executor) .exceptionally(throwable -> { log.error("Order processing failed", throwable); return OrderResult.failed(throwable.getMessage()); }); } // Combine multiple async results CompletableFuture<Void> all = CompletableFuture.allOf(f1, f2, f3); all.thenRun(() -> { /* all complete */ }); ``` ## Testing & Tooling ### JUnit 5 ```java import org.junit.jupiter.api.*; class OrderServiceTest { @Test void createOrder_setsPendingStatus() { var order = service.createOrder(customerId, items); assertEquals(OrderStatus.PENDING, order.status()); } @ParameterizedTest @CsvSource({ "1, 10.0", "2, 20.0", "5, 50.0" }) void calculateTotal_multipliesQuantity(int qty, double expected) { assertEquals(BigDecimal.valueOf(expected), service.calculateTotal(item, qty)); } @TestFactory Stream<DynamicTest> dynamicTests() { return testCases.stream() .map(tc -> DynamicTest.dynamicTest(tc.name(), () -> { assertEquals(tc.expected(), service.process(tc.input())); })); } } ``` ### Spring Boot Test ```java @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @AutoConfigureMockMvc class OrderControllerTest { @Autowired private MockMvc mockMvc; @Test void createOrder_returns201() throws Exception { mockMvc.perform(post("/api/orders") .contentType(MediaType.APPLICATION_JSON) .content(""" {"customerId": 1, "items": [{"productId": 1, "qty": 2}]} """)) .andExpect(status().isCreated()) .andExpect(jsonPath("$.id").isNumber()); } } ``` ### Tooling ```bash # Build and test ./mvnw clean verify # Maven wrapper (no local install needed) ./gradlew build # Gradle wrapper # JVM tuning java -Xms512m -Xmx2g -XX:+UseZGC -jar app.jar # ZGC for low-latency GC # Profiling jcmd <pid> VM.native_memory # Native memory tracking jmap -dump:live,format=b <pid> # Heap dump jstack <pid> # Thread dump async-profiler -e cpu -d 30 -f profile.jfr ``` ## Anti-Patterns - **Raw `null` returns**: Forces callers to null-check. Use `Optional` for possibly-empty returns - **Checked exceptions overused**: Callers forced to catch or declare. Use unchecked exceptions for non-recoverable - **`synchronized` on hot methods**: Contention kills throughput. Use `ReentrantLock`, `StampedLock`, or `ConcurrentHashMap` - **God class with 5000+ lines**: Impossible to test, modify, or understand. Split by responsibility - **`System.out.println` in production code**: Use SLF4J + Logback/Log4j2 with proper levels - **`new Date()` / `System.currentTimeMillis()` in tight loops**: Creates objects. Cache or use `Instant.now()` - **Double-checked locking without `volatile`**: Broken without volatile on the field. Use `Thread-safe` holder pattern - **`Vector`, `Hashtable`, `StringBuffer`**: Legacy synchronized classes — use `ArrayList`, `HashMap`, `StringBuilder` - **`finalize()`**: Deprecated, unpredictable. Use `Cleaner` or try-with-resources - **No explicit charset in String.getBytes()**: Platform-dependent. Always `getBytes(StandardCharsets.UTF_8)` ## Performance Patterns - `StringBuilder` for concatenation in loops (not `+` operator) - `record` for lightweight data carriers (no boilerplate, value-based) - `ConcurrentHashMap` over synchronized maps for concurrent access - `ZGC` or `Shenandoah` for sub-millisecond GC pauses (Java 17+) - Flyweight pattern for repeated small objects (Integer cache, custom pools) - Off-heap storage with `ByteBuffer.allocateDirect` for large caches - `var` keyword doesn't affect performance but reduces noise - Profile with async-profiler before optimizing — JVM is already very good - Use `--enable-preview` in development to test upcoming features (pattern matching, string templates) ## Virtual Threads & Structured Concurrency (Java 21+) Virtual threads (Project Loom) enable lightweight concurrency without the complexity of reactive frameworks. Create via `Thread.ofVirtual().start(task)` or `Executors.newVirtualThreadPerTaskExecutor()`. Each virtual thread is a Java object (~200 bytes), not an OS thread (~1MB). Use for I/O-bound workloads: HTTP calls, database queries, file I/O. Structured Concurrency (`StructuredTaskScope`) ensures all subtasks complete or are cancelled together. Usage: `try (var scope = new StructuredTaskScope.ShutdownOnFailure())` creates a scope, `scope.fork(callable)` submits tasks, `scope.join()` waits for all, `scope.throwIfFailed()` propagates first error, `scope.result()` returns successful results. Anti-pattern: pinning virtual threads with `synchronized` blocks. Use `ReentrantLock` when virtual threads are involved. Pin detection: JVM logs "Thread X pinned" — investigate and fix. ## Modern Bean Validation & Error Handling Use Jakarta Bean Validation 3.0+ for input validation instead of manual if/else chains. Annotations on records/POJOs: `@NotBlank`, `@Email`, `@Positive`, `@Size(min=1, max=100)`, `@Pattern(regexp="...")`. Group validation: separate Create vs Update validation rules. Custom validators: implement `ConstraintValidator<Annotation, Type>`. Error handling with `@ControllerAdvice` (Spring) or `ExceptionMapper` (JAX-RS): return structured error responses with field-level errors. Pattern: validation exception → `MethodArgumentNotValidException` → extract field errors → `ErrorResponse` with code, message, fieldErrors list. Never return raw stack traces or Hibernate validation errors to clients. ## Testing Strategy Beyond JUnit Modern Java testing requires multiple layers: (a) unit tests with JUnit 5 + AssertJ (fluent assertions), (b) Mockito for mock dependencies, (c) `@SpringBootTest` for integration tests with real DB (Testcontainers), (d) `@WebMvcTest` for controller slice tests, (e) `@DataJpaTest` for repository tests. Testcontainers: write integration tests against real PostgreSQL/MySQL/Redis in Docker containers, not in-memory databases that behave differently. Use `@Testcontainers` annotation and `@Container` fields. Performance: use `@SpringBootTest(webEnvironment = NONE)` to avoid starting the full server for non-HTTP tests. Test slicing: `@JsonTest` for JSON serialization, `@RestClientTest` for REST clients. Mockito best practice: verify interactions, don't just stub — `verify(repository).save(expectedOrder)`. ## JVM Garbage Collection Strategy | GC | Java Version | Best For | Pause Time | |----|-------------|----------|------------| | G1GC | 9+ (default 9-21) | General purpose, balanced | <10ms | | ZGC | 15+ (incubating 11-14) | Large heaps (>100GB), low latency | <1ms | | Shenandoah | 15+ (incubating 12-14) | Concurrent compaction | <1ms | | Serial | All | Small heaps, single core | Longer pauses | | Parallel | All (default 8) | Throughput, batch processing | Longer pauses | GC flags for modern apps: `-XX:+UseZGC -XX:MaxHeapSize=2g -XX:ParallelGCThreads=4 -XX:ConcGCThreads=2`. Monitor GC with `-Xlog:gc*:file=gc.log:time,uptime,tags` and visualize with GCeasy or GCViewer. Heap dump on OOM: `-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/dump.hprof`. Memory leak detection: take 3 heap dumps at intervals, compare with Eclipse MAT for growing object graphs. ## Production Decision Trees ``` Build tool for greenfield project? ├── Spring Boot project → Gradle (Kotlin DSL) — faster incremental builds ├── Standard enterprise → Maven (stable, predictable) └── Android → Gradle (Groovy or Kotlin DSL) ``` ``` Microservices framework? ├── Full Spring ecosystem → Spring Boot + Spring Cloud │ Service discovery: Eureka / Consul │ Config: Spring Cloud Config / Vault ├── Low-resource, fast startup → Quarkus │ GraalVM native: <100ms startup, <10MB RSS │ Suitable for: serverless, high-density containers ├── Reactive, non-blocking → Micronaut │ AOT compilation, compile-time DI │ Suitable for: streaming, real-time └── Minimal, no framework → JAX-RS + Helidon SE ``` ``` Java version for new project? ├── Latest LTS (21) → All modern features │ Virtual threads, records, sealed classes, pattern matching, string templates ├── Current non-LTS (22, 23) → Cutting edge │ Statement before super, unnamed patterns, scoped values └── Older LTS (17) → Widespread ecosystem support Most libraries target 17+ ``` ## OpenAPI & API-First Development
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기