--- name: microprofile-server description: Architecture and coding rules for long-running Java MicroProfile / Jakarta EE server applications — BCE layering, business components (BC), JAX-RS resources, CDI, JSON-P, testing (unit/integration/system), and Maven project structure. Use when creating, generating, scaffolding, writing, or reviewing code, resources, entities, boundaries, or business components in MicroProfile server projects. Not for serverless deployments. --- ## Java Version & Syntax - use Java 25 with modern syntax (var, pattern matching, records, text blocks) - prefer dependencies in this order: Java SE, MicroProfile, Jakarta EE - use Java SE APIs over writing custom code - prefer the most specific Java SE type for the domain - prefer unchecked over checked exceptions; never throw generic exceptions like java.lang.Exception - throw RuntimeException subclasses, not directly; inherit from WebApplicationException in JAX-RS projects - consider using Java records instead of classes with final fields - prefer factory methods in records over passing null in constructors ## Logging - use java.lang.System.Logger instead of System.out statements - never use java.util.logging.Logger - Logger fields must be named LOGGER (uppercase) and marked as static final ## BCE/ECB Architecture - structure code using the Boundary Control Entity (BCE/ECB) pattern - package structure: [ORGANIZATION_NAME].[PROJECT_NAME].[COMPONENT_NAME].[boundary|control|entity] - top level package reflects the application responsibility or name - business components are children of top level package, named after their responsibilities - boundary, control, entity packages are only allowed in business components - classes with cross-cutting functionality are located in the root application package - not every BCE component needs a dedicated boundary package; control package contents can be accessed directly - do not explain the BCE pattern in documentation ## Package Naming - create application level package with name derived from maven project or context - name packages after their domain responsibilities - create package-info.java for top level packages with JavaDoc documenting design decisions and responsibilities (not contents) - document only domain-specific packages with package-info.java where the purpose is not self-evident ## Boundary Layer - keep coarse-grained classes in the boundary package - place facades in the boundary package - health checks must be placed in the boundary package - @Transactional is only allowed in boundary layer - if there is no Boundary stereotype, use ApplicationScope instead ## Control Layer - implement procedural business logic in the control package - prefer interfaces with static methods over classes for stateless/procedural logic - in utility interfaces prefer static over default methods ## Entity Layer - maintain domain objects, data classes, and entities in the entity package - entities maintain state and corresponding behavior - model value objects as enums ## Class Naming Conventions - name classes after their responsibilities - avoid meaningless suffixes: *Impl, *Service, *Manager, *Creator - class names must not end with "Control" - only use "Resource" suffix for JAX-RS classes - only use "Factory" suffix for actual GoF Factory pattern - only use "Builder" suffix for classes with typical builder structure (method chaining) ## Visibility & Modifiers - avoid private visibility; prefer package-private (default) visibility - avoid "private static" methods; prefer default visibility - do not use final for fields (exception: static final for LOGGER) - do not use constructor injection ## Interfaces & Classes - only use interfaces with multiple implementations or for strategy pattern - do not create interfaces with abstract methods implemented by a single class; use classes directly - create multiple classes only if it decreases complexity and increases readability ## Method Naming & Design - avoid "getter" methods starting with "get"; prefer record convention (e.g., configuration() not getConfiguration()) - keep methods short and testable - create well-named methods for coarse-grained, cohesive, self-contained logic - if a lambda requires multiple statements or braces {}, extract it into a well-named helper method - do not create multiline lambda expressions; use method references instead - extract repeated calculations or string concatenations into helper methods (DRY principle) - do not create empty delegates which just call methods without added value ## Stream & Collections - prefer java.util.stream.Stream API over for loops - avoid forEach; prefer Stream methods - prefer Stream.of to Arrays.stream - prefer toList() to .collect(Collectors.toList()) - prefer List.of over String[] or new ArrayList<>() - avoid creating unnecessary intermediate collections when streaming arrays - prefer variable declaration over lengthy method chaining ## Code Style - prefer multiple simpler lines to one more complex line - prefer multiline Strings (text blocks) over String concatenations - prefer imports over fully qualified class names - use "this" to reference instance fields - remove unused imports - extract variables to eliminate duplication - prefer enums over plain Strings for finite, well-defined values - reuse enum constants as values if possible; enum constants do not have to follow naming conventions - prefer try-with-resources over explicitly closing resources ## Simplicity Principles - keep the design KISS and YAGNI - always implement the simplest possible solution - write simple code first; ask before implementing enhancements or optional features - never over-engineer; ask about adding optional features or extension points - create new components with minimal business logic and essential fields only ## Exceptions - create custom exceptions only if it significantly improves robustness or maintainability - use explicit exceptions like BadRequestException for Response.Status.BAD_REQUEST - always use WebApplicationException in compact constructors in JAX-RS projects - do not re-throw exceptions with "throw e" without adding value ## JavaDoc - do not write obvious JavaDoc comments that rephrase code - document the intentions and the "why", not implementation details - either describe the "why" or do not comment at all - follow links in JavaDoc to external specifications and use them for code generation - use popular, also funny, technical terms from the Java SE, MicroProfile and Jakarta EE ecosystems as examples in unit tests and javadoc ## README Guidelines - write brief, 'to the point' README.md files for advanced developers - use precise and concise language; avoid generic adjectives like "simple", "lightweight" - do not include detailed project structure (file/folder listings); high-level module descriptions are acceptable - never list REST resources in READMEs - if modules are listed, provide links - do not use "Orchestrates" term; use more specific alternatives ## Testing - unit test methods must not start with "test" or "should" - avoid writing repetitive or trivial unit tests; keep only essential tests verifying core functionality - do not write tests for implementations that cannot fail (enums, records, getters/setters) - create minimalistic tests first - generate at most three tests per class under test (applies separately to UTs, ITs, and STs) - use AssertJ library instead of JUnit assertions - the presence of isEqualTo assertion makes less specific checks (startsWith, isNotNull) obsolete - do not use private visibility in tests ## Integration Tests - integration tests end with IT suffix and are executed by the failsafe maven plugin (no configuration necessary) ## System Tests (ST) - system tests are created in a dedicated Maven module ending with "-st" - use microprofile-rest-client for testing JAX-RS resources - REST client interfaces: src/main/java of the -st module - test classes: src/test/java of the -st module - name client interfaces after the resource with "Client" suffix (e.g., GreetingsResource -> GreetingsResourceClient) - RegisterRestClient configKey: "service_uri" - STs end with "IT" suffix - do not use RestAssured. Write e2e test in the -st module ## JAX-RS - resources should be named in plural (e.g., SpeakersResource not SpeakerResource) - @Consumes and @Produces should be declared on class-level - do not implement business logic in JAX-RS resources; delegate instead - prefer returning JAX-RS Response over JsonObject in resources - do not create new "@RegisterRestClient(configKey," - reuse existing ## JSON Serialization (JSON-P) - prefer JSON-P over JSON-B - record entities should ship with toJSON method returning a JSON-P object - always map JSON-P in the boundary to entities - create record entities from JSON-P JsonObject in static method: fromJSON(JsonObject json) ## HTTP Client - prefer synchronous HTTPClient APIs - use asynchronous Http APIs (HttpClient.sendAsync) only if explicitly requested ## Project Management - always ask before changing pom.xml - do not create or change any files on opening existing projects; stop after initialization and wait for instructions - do not generate code initially in an empty project - Maven pom.xml must not be created for Java 25 CLI applications - never use quarkus-hibernate-validator - create metrics and observability features with OTEL / opentelemetry