# Eo / Ejb

## Overview

The `eo.ejb` package is a Java EE / EJB demonstration package that showcases enterprise Java patterns across three sub-modules. It represents an educational reference for how to define persistent entities, build business logic with dependency injection, and use reflection for runtime class loading. The package is not a production system -- the `example` naming convention and stub implementations indicate it exists as learning material and pattern reference.

Together, the three child modules illustrate the layers of a typical EJB application:

- **Data model** (`example`) -- defining JPA entities that map Java objects to database tables
- **Business orchestration** (`service`) -- coordinating multiple microservices through EJBs with dependency injection
- **Reflection utilities** (`wiki`) -- dynamic class loading and method invocation at runtime

The central theme running through all three sub-modules is the pattern of dynamic behavior -- either through JPA's runtime persistence mapping, EJB container-managed lifecycle injection, or Java reflection for runtime class loading.

## Sub-module Guide

### Example: Data Model and Dynamic Loading

The `eo.ejb.example` package is the shallowest of the three, containing just two classes that demonstrate foundational patterns:

- **`EntityClass`** -- a simple JPA entity mapped to the `entity_class` database table with a `Long` primary key (`id`) and a `String` name field (`item_name`). This class has no relationships to other entities and exposes only getter methods, suggesting read-only access through JPA.
- **`PatternOneVar`** -- a stateless utility that loads and instantiates classes at runtime via `Class.forName()` and `newInstance()`. This demonstrates the plugin/factory pattern used in frameworks that determine types from configuration rather than hard-coding them.

These two classes are independent -- there is no workflow connecting them. They serve as isolated illustrations of persistence and dynamic loading respectively.

### Service: Business Logic Orchestration

The `eo.ejb.service` package is the most complex sub-module and the only one with a real workflow. It implements an order-placement flow through `OrderService`, which orchestrates three specialized services:

1. **`PaymentGateway`** -- processes customer charges (injected via CDI `@Inject`)
2. **`InventoryService`** -- reserves inventory for ordered items (injected via EJB `@EJB`)
3. **`NotificationService`** -- sends order confirmations (injected via Spring `@Autowired`)

`OrderService` mixes three dependency injection frameworks (CDI, EJB, Spring) plus JNDI resource injection -- a deliberate demonstration of multi-container coexistence. Two additional classes (`StatelessBean` and `EJBWithArgs`) show bare-minimum EJB patterns: a minimal stateless session bean and named EJB injection respectively.

The payment flow is sequential and fire-and-forget: charge first, reserve second, notify last. This ordering is a design gap -- if reservation fails after a successful charge, there is no rollback logic visible in this code.

### Wiki: Reflection Utilities and Data Models

The `eo.ejb.wiki` package contains two independent utility classes:

- **`PlainClass`** -- a basic data-bearing class with a single `name` field and a `greet()` method. This is a simple JavaBeans-style model with no side effects.
- **`ReflectiveClass`** -- a reflection bridge that loads arbitrary classes by name (`loadByReflection()`) and invokes convention-based `execute()` methods dynamically (`invokeMethod()`). Like `PatternOneVar` in the example package, it uses Java reflection for runtime dispatch.

Notably, the wiki package declares a dependency on `eo.ejb.service`, making it the only sub-module with a cross-module reference. This suggests it may have been intended as a test or integration layer for the service package.

### How the Sub-modules Relate

The three packages are largely independent, each illustrating different patterns within the EJB ecosystem:

```mermaid
flowchart TD
    EJBSvc["MyService"]
    WI["Wiki Package"]
    EX["Example Package"]
    SVC["Service Package"]
    WI -->|"depends on"| SVC
    WI -->|"PlainClass"| P1["PlainClass"]
    WI -->|"ReflectiveClass"| R1["ReflectiveClass"]
    EX -->|"EntityClass"| E1["EntityClass"]
    EX -->|"PatternOneVar"| P2["PatternOneVar"]
    SVC -->|"OrderService"| O1["OrderService"]
    SVC -->|"PaymentGateway"| P3["PaymentGateway"]
    SVC -->|"InventoryService"| I1["InventoryService"]
    SVC -->|"NotificationService"| N1["NotificationService"]
```

The `wiki` package is the only one with a documented cross-module dependency -- it imports from `eo.ejb.service`. The `example` package is fully self-contained with no external references. All three packages share a common reliance on reflection or runtime mechanisms, though only `wiki` and `example` use it explicitly.

## Key Patterns and Architecture

### Multi-Framework Dependency Injection

The most architecturally significant pattern in the `eo.ejb` module is the mixed injection approach used by `OrderService`. It simultaneously uses:

| Injection Type | Annotation | Framework |
|---------------|-----------|-----------|
| CDI | `@Inject` | Java CDI (Contexts and Dependency Injection) |
| EJB | `@EJB` | Enterprise JavaBeans 3.x |
| Spring | `@Autowired` | Spring Framework |
| JNDI | `@Resource` | Java EE Naming Context |

This demonstrates that the application server or runtime environment is configured to support all four injection mechanisms. While functional, this introduces significant coupling -- developers must understand the coexistence model across containers. In production code, a single injection framework is typically preferred.

### Sequential Business Flow Without Compensation

`OrderService.placeOrder()` executes a linear chain of three operations:

```mermaid
sequenceDiagram
    participant Client
    participant OS as OrderService
    participant PG as PaymentGateway
    participant IS as InventoryService
    participant NS as NotificationService

    Client->>OS: placeOrder
    OS->>PG: charge
    OS->>IS: reserve
    OS->>NS: notify
```

This pattern is simple but has a critical flaw: charges are processed before inventory is confirmed reserved. In a production order system, the typical approach would be to either reserve inventory first (to fail fast on stock issues) or use a compensating transaction / Saga pattern to roll back charges if subsequent steps fail.

### Dynamic Class Loading as a Recurring Theme

Both the `example` and `wiki` packages feature reflection-based class loading:

- `PatternOneVar.load()` in `example` takes a class name string and returns an instance
- `ReflectiveClass.loadByReflection()` in `wiki` does the same, plus `invokeMethod()` for dynamic method dispatch

This appears to be an intentional pattern demonstration -- showing how frameworks like dependency injectors, plugin systems, and test runners load classes dynamically. Both implementations use the deprecated `Class.newInstance()`, which has been superseded since Java 9 by `Constructor.newInstance()`.

### Stateless Session Bean as Execution Context

`StatelessBean` in the service package demonstrates the simplest EJB lifecycle -- a `@Stateless` bean with a single `execute()` method. Stateless beans are the most common EJB type because they are thread-safe by design (no conversational state) and can be pooled by the container for concurrent request handling.

### JPA Entity Without Lifecycle Methods

`EntityClass` is annotated with `@Entity` and `@Table` but contains no JPA lifecycle callbacks (`@PrePersist`, `@PostLoad`, etc.) and no setters. This suggests the entity is intended for read-only access through the JPA `EntityManager`, with modifications handled through proper persistence operations rather than direct field mutation.

## Dependencies and Integration

### External Dependencies

- **JPA (Java Persistence API)** -- required by `EntityClass` for `@Entity`, `@Table`, `@Id`, `@Column` annotations. A JPA persistence unit must be configured in the application server or Spring context.
- **CDI (Contexts and Dependency Injection)** -- required by `PaymentGateway` injection via `@Inject`.
- **EJB 3.x** -- required by `InventoryService` injection via `@EJB` and `StatelessBean` via `@Stateless`.
- **Spring Framework** -- required by `NotificationService` injection via `@Autowired`.
- **JNDI** -- required for `DataSource` resource lookup via `@Resource`.

### Internal Dependencies

The `eo.ejb.wiki` package depends on `eo.ejb.service`, creating a one-way dependency from wiki to service. The `example` package has no internal dependencies and is fully self-contained. The `service` package has no dependencies on the other child packages.

### How This Module Connects to the Rest of the System

The `eo.ejb` module appears to be a top-level demonstration package (at the root of the module tree). The three sub-modules are primarily educational -- they illustrate patterns that would appear in a production EJB application, but with stub implementations and broad exception handling that suggest they are not deployed to production.

## Notes for Developers

1. **Reflection uses deprecated APIs.** Both `PatternOneVar.load()` and `ReflectiveClass.loadByReflection()` use `Class.newInstance()`, deprecated since Java 9. Replace with `clazz.getDeclaredConstructor().newInstance()` to avoid hiding checked exceptions inside `InvocationTargetException`.

2. **Broad exception declarations.** `PatternOneVar.load()` and `ReflectiveClass` methods declare `throws Exception`. Narrow these to `ReflectiveOperationException` for more precise error handling.

3. **No rollback in order flow.** The sequential charge-then-reserve pattern in `OrderService.placeOrder()` leaves the system in an inconsistent state if later steps fail. Consider adding compensating logic or restructuring the order to reserve inventory before charging.

4. **Mixed DI frameworks.** `OrderService` uses CDI, EJB, Spring, and JNDI injection simultaneously. While this demonstrates multi-container coexistence, it makes the codebase harder to maintain. A production system should standardize on one injection mechanism.

5. **No setters on `EntityClass`.** The entity only exposes getters, implying it is used for read-only access or that all mutations go through JPA `EntityManager` operations. Do not assume direct field access will be persisted.

6. **`EJBWithArgs` uses named injection.** The `@EJB(name = "myBean")` pattern explicitly names the injected EJB reference. This is useful when the same type has multiple implementations and disambiguation is needed.

7. **Example package is illustrative.** Classes in `eo.ejb.example` are marked as examples and may be removed or refactored. Treat them as learning material rather than production code.

8. **Thread safety.** All EJB components in the `service` package are stateless, making them inherently thread-safe. `PlainClass` and `PatternOneVar` are also stateless. `EntityClass` follows standard JPA concurrency rules -- do not share entities across threads without proper synchronization.
