Java EE
General Java Naming Conventions
These conventions ensure modules and components are easy to identify and organize, enhancing maintenance. All conventions are compliant with standard Java Programming Language code conventions.
- Classes & Interfaces: Use PascalCase (mixed case with the first letter of each internal word capitalized).
- Example:
UserRegistrationService, ContactInfoBean.
- Example:
- Methods: Use camelCase (mixed case with a lower case first letter) and start with a verb.
- Example:
calculateTotal(), performLogin().
- Example:
- Variables & Attributes: Use camelCase; avoid single-letter names except for loop counters.
- Example:
isAccountActive.
- Example:
- Constants & Enumerated Values: Use UPPER_SNAKE_CASE (upper case with words separated by underscores).
- Example:
MAX_RETRY_ATTEMPTS, VISA.
- Example:
- Packages: Use all-lowercase ASCII letters.
- Example:
com.enovate.paymentsystem.service.
- Example:
J2EE Application, Module, and Component Names
This includes archive names and display names in deployment descriptors.
- J2EE Application (EAR): Packaged as an Enterprise Archive with a .ear extension.
- Archive Name: All-lowercase ASCII letters.
- Example:
paymentsystem.ear. - Display Name: Expanded application name in mixed case followed by "EAR".
- Example:
<display-name>PaymentSystemEAR</display-name>.
- EJB Modules: Packaged as JAR files with a .jar extension.
- Archive Name:
<module-name>-ejb.jar. - Client Archive:
<module-name>-ejb-client.jar. - Display Name:
<expanded-module-name> JAR.
- Archive Name:
- Web Modules: Packaged as Web Archives with a .war extension.
- Archive Name:
<module-name>.war. - Display Name:
<expanded-module-name> WAR.
- Archive Name:
EJB Component Naming Standards
Conventions for the different parts of an enterprise bean.
- Entity & Session Beans:
- Local Interface:
<component-name> or <component-name>Local. - Local Home Interface:
<component-name>Home or <component-name>LocalHome. - Remote Interface:
<component-name>Remote. - Implementation Class:
<component-name>Bean. - Primary Key Class:
<component-name>PK.
- Local Interface:
- Message Driven Beans (MDB):
- Implementation Class:
<component-name>Bean. - Display Name:
<expanded-component-name> MDB.
- Implementation Class:
Web Component Naming Standards
Includes Servlets, JSPs, filters, and listeners.
- Servlets:
- Implementation Class:
<component-name>Servlet. - Display Name:
<expanded-component-name> Servlet.
- Implementation Class:
- Filters:
- Implementation Class:
<component-name>Filter.
- Implementation Class:
- Listeners: Implementation class should be
<component-name>Listener. - JavaServer Pages (JSP):
- File Name: Must begin with a lower-case letter; avoid verb-only names.
- Example:
performLogin.jsp. - JSP Segments:
/WEB-INF/jspf/file.jspf. - Tag Files:
/WEB-INF/tags/file.tag.
Web Service Naming (JAX-RPC & Endpoint)
Naming for clients, endpoints, and configuration files.
- Service Name: PascalCase base name of the EJB or JAX-RPC endpoint.
- Example:
WeatherService.
- Example:
- Endpoints:
- Service Endpoint Interface:
<service-name>SEI. - EJB Implementation:
<service-name>Bean. - JAX-RPC Implementation:
<service-name>Impl.
- Service Endpoint Interface:
- Configuration:
- WSDL File:
<service-name>.wsdl. - Mapping File:
<all-lower-case-service-name>-mapping.xml.
- WSDL File:
Reference Names (JNDI & Resources)
All reference names are relative to java:comp/env.
- EJB References: Logical name for JNDI lookup of home interfaces.
- Format:
ejb/<component-name>.
- Format:
- Web Service References:
service/<service-name>. - Resource References:
- JDBC:
jdbc/<resource-name>. - JMS:
jms/<resource-name> [Queue|Topic]. - Mail:
mail/<resource-qualifier>. - Environment Entries:
param/<parameter-name>.
- JDBC:
Database & XML Document Naming
- Database Naming: Name CMP databases after the application (e.g.,
PaymentSystemDB). - Database schema: Use lower_case_with_underscores (e.g.
payment_system_db). - Database tables: Use lower_case_with_underscores (e.g.
payment_records). - Database columns: Use lower_case_with_underscores (e.g.
payment_id). - XML Elements: Follow class naming (
PascalCase). - XML Attributes: Follow variable naming (
camelCase). - Alternative XML Notation: Element names in lower case separated by hyphens (e.g.,
<credit-card>).
Deployment Descriptor & Manifest Standards
- Standard Descriptors:
- Application:
application.xml. - Web:
web.xml. - EJB:
ejb-jar.xml.
- Application:
- Manifest Files: Prototype names used in source directories to distinguish files before they are renamed to
MANIFEST.MFin the archive.- EJB Manifest:
ejb-jar-manifest.mf.
- EJB Manifest:
Modern Jakarta EE Compatibility
While maintaining legacy code, new development must align with modern Jakarta EE practices.
- Dependency Injection (CDI): Use @Inject instead of manual JNDI lookups (relative to java:comp/env) where supported.
- REST Services: Prefer Jakarta REST (JAX-RS) over new Servlet implementations for service interfaces.
- Persistence: Utilize JPA @Entity POJOs to replace legacy CMP Entity Beans.
- Validation: Use Bean Validation annotations (@NotNull, @Size) to replace manual validation in Web components.
Architecture & Layering Strategy
We adhere to a strict Separation of Concerns (SoC). Business logic must never leak into the Database or Web layers.
- Controller (JAX-RS): Handles HTTP requests/responses. Use DTOs (Data Transfer Objects) here; never expose JPA Entities directly to the client.
- Service Layer (EJB/CDI): Contains the "What" of the application. Transaction boundaries (@Transactional) start here.
- Repository Layer (JPA): Contains the "How" of data retrieval. Purely for CRUD and queries.
To prevent "Spaghetti Code," all Java EE applications must follow a Layered Architecture.
- Presentation Layer (Web/API): REST Controllers or Servlets. No business logic.
- Business Layer (Service): Core logic and transaction boundaries (@Transactional).
- Data Access Layer (Repository/DAO): Database interactions using JPA/Hibernate.
General Coding Standards
1. Dependency Injection (DI)
Use constructor injection instead of @Autowired or field injection to ensure the class remains testable and final.
Java
// Recommended
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
2. Avoid "Magic Numbers"
Never hardcode numeric literals in logic. Use constants or Enums.
Java
// Bad
if (status == 1) { ... }
// Good
public static final int STATUS_ACTIVE = 1;
if (status == STATUS_ACTIVE) { ... }
3. Use StringBuilder for Loops
For string manipulation inside loops, use StringBuilder to avoid unnecessary object creation in the heap.
EJB and CDI (Dependency Injection)
Modern Java EE favors CDI over older EJB styles where possible.
- Prefer Constructor Injection: It makes the code immutable and easier to unit test without a container.
Java
@ApplicationScoped
public class OrderService {
private final InventoryClient inventoryClient;
@Inject // Required for CDI constructor injection
public OrderService(InventoryClient inventoryClient) {
this.inventoryClient = inventoryClient;
}
}
- Scope Awareness: Use @RequestScoped for web-related beans and @ApplicationScoped for singleton-like services. Avoid @SessionScoped unless strictly necessary for stateful web apps to save memory.
JPA (Persistence) Best Practices
Database performance is usually the bottleneck of Java EE apps.
- Fetch Type: Always default to FetchType.LAZY for @OneToMany and @ManyToMany relationships to avoid the "N+1" select problem.
- Use Named Queries: This allows the JPA provider to pre-compile the query.
Java
@Entity
@NamedQuery(name="User.findByEmail", query="SELECT u FROM User u WHERE u.email = :email")
public class User { ... }
- Avoid System.out.println for SQL: Use the persistence property javax.persistence.schema-generation.database.action and standard logging.
RESTful API Design (JAX-RS)
- Use Standard HTTP Verbs: *
GET (Read),POST (Create),PUT (Update),DELETE (Remove). - Proper Status Codes: * 201 Created for successful POSTs.
400 Bad Request for validation failures.404 Not Found for missing resources.
- Version your APIs: Always include a version in the URL path.
- Example:
@Path("/v1/orders"
- Example:
Exception Handling
- Don't Swallow Exceptions: Never leave a catch block empty. At least log the error.
- Specific Exceptions: Catch FileNotFoundException rather than a generic Exception.
- Custom Exceptions: Create domain-specific exceptions (e.g.,
UserNotFoundException) to provide better context to the API consumer. - Global Exception Mapper: Use
ExceptionMapper<T>to catch internal exceptions and return a clean JSON response to the user.
Java
@Provider
public class EntityNotFoundMapper implements ExceptionMapper<EntityNotFoundException> {
@Override
public Response toResponse(EntityNotFoundException ex) {
return Response.status(404).entity(new ErrorDTO(ex.getMessage())).build();
}
}
Logging
- SLF4J + Logback: Use placeholders {} instead of string concatenation to improve performance.
- Bad:
logger.info("User " + name + " logged in"); - Good:
logger.info("User {} logged in", name);
- Bad:
Security & Validation Best Practices
- Input Validation: Never trust client data. Use Bean Validation
(@NotNull, @Size, @Email). - Principle of Least Privilege: Class members should be private by default.
- Sensitive Data: Never log passwords, credit card numbers, or PII (Personally Identifiable Information).
- Bean Validation: Use standard constraints to keep logic clean.
Java
public class UserDTO {
@NotBlank(message = "Username is required")
@Size(min = 3, max = 20)
private String username;
@Email
private String email;
}
- Encoding: Always specify UTF-8 encoding for all web responses to prevent character corruption.
- No Hardcoded Credentials: All passwords, API keys, and DB URLs must be stored in environment variables or a microprofile-config.properties file.