# Eo / Ejb

## Overview

The `eo.ejb` package is an Enterprise JavaBeans (EJB) module that provides an order-processing system with supporting infrastructure for runtime type discovery. It brings together three sub-packages, each responsible for a distinct concern:

- **`eo.ejb.service`** — the core business service layer, orchestrating order placement across payment, inventory, and notification domains.
- **`eo.ejb.example`** — demonstration subpackage illustrating JPA entity modeling and reflection-based class loading patterns.
- **`eo.ejb.wiki`** — a reflection utility package that dynamically loads and invokes classes at runtime, bridging to other modules without compile-time dependencies.

Together, these packages form a hybrid Java EE system that combines enterprise beans (EJB, CDI, Spring), a JPA data layer, and runtime reflection-based service discovery. The architecture appears to be in a transition period, given the coexistence of multiple dependency injection frameworks and the use of reflection to wire services at runtime.

## Sub-module Guide

### `eo.ejb.service` — Business Services

This is the heart of the module. `OrderService` acts as a central facade that orchestrates the order workflow by delegating to three leaf services:

1. **`PaymentGateway`** — processes customer payments.
2. **`InventoryService`** — reserves stock against incoming orders.
3. **`NotificationService`** — dispatches order confirmations or alerts.

The key design decision here is the fixed execution order: charge payment first, reserve inventory second, notify last. This prevents reserved-but-unpaid inventory but lacks compensation logic — if inventory reservation fails after payment, there is no rollback.

Additionally, this package includes `StatelessBean` (a generic stateless EJB for background tasks) and `EJBWithArgs` (a demonstration of name-based EJB injection via JNDI), both of which serve as reusable infrastructure patterns rather than part of the order flow.

### `eo.ejb.example` — Patterns and Examples

This subpackage serves as a reference implementation for two patterns used elsewhere in the system:

- **`EntityClass`** — a minimal JPA entity mapped to the `entity_class` table, demonstrating persistent entity modeling with no setters (read-only from outside).
- **`PatternOneVar`** — a reflection-based utility that dynamically loads and instantiates arbitrary classes by their fully-qualified name. This is the same general approach used by `ReflectiveClass` in the `wiki` package.

### `eo.ejb.wiki` — Reflection Bridge

The `wiki` package provides runtime type discovery capabilities through two classes:

- **`PlainClass`** — a simple POJO data holder (not an EJB).
- **`ReflectiveClass`** — the most significant class in the entire `eo.ejb` module. It accepts a fully-qualified class name string, loads the class via `Class.forName()`, instantiates it, and can invoke a static `"execute"` method on it. This bridges `eo.ejb.wiki` to `eo.ejb.service` and other modules at runtime without compile-time dependencies.

### How the sub-modules relate

The `wiki` package's `ReflectiveClass` acts as a runtime wiring mechanism — it can dynamically load service classes from `eo.ejb.service` (or any other module on the classpath) by name. This means the service layer doesn't need to be known at compile time; it can be discovered, instantiated, and invoked purely through reflection. The `example` package demonstrates both the JPA entity pattern and the same reflection pattern (`PatternOneVar`) that `wiki` builds on more formally.

## Key Patterns and Architecture

### Mixed Dependency Injection

`OrderService` uses four different injection mechanisms simultaneously:

| Field | Annotation | Framework |
|-------|-----------|-----------|
| `paymentGateway` | `@Inject` | CDI (JSR-346) |
| `inventory` | `@EJB` | EJB dependency injection |
| `notificationService` | `@Autowired` | Spring Framework |
| `dataSource` | `@Resource` | Java EE resource injection |

This suggests the module may be running in a container that supports all four frameworks (e.g., WildFly with Spring integration), or it is in a transition phase where multiple injection strategies were adopted incrementally. For new code, CDI `@Inject` is the recommended default.

### Runtime Type Resolution via Reflection

Both `eo.ejb.example.PatternOneVar` and `eo.ejb.wiki.ReflectiveClass` implement reflection-based class loading, but with different scopes:

- `PatternOneVar.load(String)` accepts a class name, instantiates it, and prints it — a simple demonstration of the pattern.
- `ReflectiveClass` adds a layer of sophistication: it stores a target class name, instantiates the class via `loadByReflection()`, and can invoke a static `"execute"` method on any given class via `invokeMethod(Class<?>)`.

This reflection pattern is notable because it decouples `wiki` from its runtime targets — `eo.ejb.service` classes can be loaded and invoked without any import statement. This is useful for plugin architectures or environments where service implementations may vary across deployments.

**Caveat:** Both classes use `Class.newInstance()`, which has been deprecated since Java 9. Modern Java prefers `cls.getDeclaredConstructor().newInstance()`.

### Stub Implementation Pattern

All leaf services (`PaymentGateway`, `InventoryService`, `NotificationService`) are currently stub implementations with empty method bodies. The order workflow (`OrderService.placeOrder()`) is structurally correct but functionally a no-op. The architecture is established; production logic still needs to be implemented.

### Transaction Management Gap

The current `placeOrder()` workflow has no error handling or transaction management. If `PaymentGateway.charge()` succeeds but `InventoryService.reserve()` fails, the payment has already been captured with no compensation mechanism. In production, this would require either JTA global transactions (`@TransactionAttribute`) or explicit compensation (e.g., refund on inventory failure).

## Module Interaction Diagram

```mermaid
flowchart TD
    A["eo.ejb (Module)"] --> B["eo.ejb.service
Business Services"]
    A --> C["eo.ejb.example
Patterns & Examples"]
    A --> D["eo.ejb.wiki
Reflection Bridge"]

    B --> B1["OrderService"]
    B1 --> B2["PaymentGateway"]
    B1 --> B3["InventoryService"]
    B1 --> B4["NotificationService"]
    B --> B5["StatelessBean"]
    B --> B6["EJBWithArgs"]

    C --> C1["EntityClass"]
    C --> C2["PatternOneVar"]

    D --> D1["PlainClass"]
    D --> D2["ReflectiveClass"]

    D2 -. "dynamically loads" .-> B
```

## Dependencies and Integration

### Internal Dependencies

| From | To | Mechanism |
|------|-----|-----------|
| `eo.ejb.service.OrderService` | `eo.ejb.service.PaymentGateway` | CDI `@Inject` |
| `eo.ejb.service.OrderService` | `eo.ejb.service.InventoryService` | EJB `@EJB` |
| `eo.ejb.service.OrderService` | `eo.ejb.service.NotificationService` | Spring `@Autowired` |
| `eo.ejb.wiki.ReflectiveClass` | `eo.ejb.service` classes | Runtime `Class.forName()` |

### External Dependencies

| Dependency | Used By | Purpose |
|-----------|---------|---------|
| JPA (`javax.persistence`) | `eo.ejb.example.EntityClass` | Entity mapping annotations (`@Entity`, `@Table`, `@Id`) |
| Java EE / EJB (`javax.ejb`) | `eo.ejb.service` | `@Stateless`, `@EJB` annotations |
| CDI (JSR-346) | `eo.ejb.service` | `@Inject` annotation |
| Spring Framework | `eo.ejb.service` | `@Autowired` annotation |
| Java EE Resource API | `eo.ejb.service` | `@Resource` annotation for `DataSource` |
| `java.lang.Class` (JRE) | `eo.ejb.example.PatternOneVar`, `eo.ejb.wiki.ReflectiveClass` | Reflection-based class loading |

## Notes for Developers

- **Consolidate injection frameworks.** `OrderService` mixes CDI, EJB, Spring, and Java EE resource injection. When adding new dependencies, prefer `@Inject` (CDI) for consistency.
- **Implement stub services.** `PaymentGateway`, `InventoryService`, and `NotificationService` have no production logic. Each service's key method (`charge()`, `reserve()`, `notify()`) is a no-op.
- **Add transaction management.** The order workflow has no rollback or compensation on failure. Consider `@TransactionAttribute` or explicit error handling with refund logic.
- **Use modern reflection.** Both `PatternOneVar` and `ReflectiveClass` use deprecated `Class.newInstance()`. Replace with `cls.getDeclaredConstructor().newInstance()` in any new code.
- **No null checks in ReflectiveClass.** `ReflectiveClass` does not validate constructor arguments or handle null. Callers are expected to ensure well-formed input.
- **Read-only entity.** `EntityClass` has no setters. Mutate through the JPA `EntityManager` or add setters if direct field modification is needed.
- **Execution order is intentional.** `placeOrder()` charges payment before reserving inventory — this avoids reserved-but-unpaid stock. If this ordering changes, document the rationale and ensure compensation logic covers the new sequence.
- **StatelessBean purity.** `StatelessBean` fields must not store instance state — the container pools and shares instances across callers.
