# Eo / Ejb / Service

## Overview

The `eo.ejb.service` package provides a set of enterprise Java beans (EJBs) and supporting service classes that form the core business logic for order processing and related operations. It demonstrates the use of EJB 3.x annotations (`@Stateless`, `@EJB`, `@Resource`), CDI dependency injection (`@Inject`), and Spring integration (`@Autowired`), all wired together in an order-placement workflow. This package exists to centralize the orchestration of payment, inventory reservation, and notification — the three primary concerns when processing a customer order.

## Key Classes and Interfaces

### [StatelessBean](StatelessBean.java:5)

A stateless session bean annotated with `@Stateless`, making it a managed EJB component. Stateless beans are the default EJB type for short-lived, thread-safe operations that do not retain conversational state across method invocations. This bean is looked up and invoked by the EJB container, which handles pooling and thread assignment.

```java
@Stateless
public class StatelessBean {
    public void execute() {
        System.out.println("stateless execute");
    }
}
```

**Key method:**

- `execute()` — A simple entry point that logs a message. Because the bean is stateless, it can be safely invoked concurrently by multiple clients without synchronization. This is an example of a minimal EJB lifecycle: the container creates an instance, injects any resources, calls the method, and returns the instance to the pool.

### [OrderService](OrderService.java:8)

The central orchestrator for the order-placement workflow. This class demonstrates the use of multiple dependency injection strategies side-by-side — CDI (`@Inject`), EJB (`@EJB`), Spring (`@Autowired`), and generic resource injection (`@Resource`). It composes the full order flow by delegating to three specialized services.

```java
public class OrderService {
    @Inject
    private PaymentGateway paymentGateway;

    @EJB
    private InventoryService inventory;

    @Autowired
    private NotificationService notificationService;

    @Resource
    private DataSource dataSource;

    public void placeOrder() {
        paymentGateway.charge();
        inventory.reserve();
        notificationService.notify();
    }
}
```

**Key methods:**

- `placeOrder()` — The main business flow. Called with no parameters and returning void (errors propagate as exceptions). This method executes three side-effecting operations in sequence:
  1. `paymentGateway.charge()` — Charges the customer's payment method.
  2. `inventory.reserve()` — Reserves the ordered items in inventory.
  3. `notificationService.notify()` — Sends an order confirmation to the customer.

The sequential, fire-and-forget ordering of these calls implies a simple optimistic model: if any step fails, an exception bubbles up to the caller. There is no compensation or rollback logic visible here, which means that if `inventory.reserve()` or `notificationService.notify()` is called after a successful `charge()`, a failed order would leave a charge behind. This is a notable design gap for production use.

**Injection breakdown:**

| Field | Annotation | Framework | Target |
|-------|-----------|-----------|--------|
| `paymentGateway` | `@Inject` | CDI | `PaymentGateway` |
| `inventory` | `@EJB` | EJB 3.x | `InventoryService` |
| `notificationService` | `@Autowired` | Spring | `NotificationService` |
| `dataSource` | `@Resource` | JNDI | `DataSource` |

This class mixes three dependency injection frameworks (CDI, EJB, Spring) plus JNDI resource injection. While this works in practice (a server running all three or a compatible implementation), it introduces coupling to multiple container implementations and may cause confusion for developers unfamiliar with the coexistence model.

### [PaymentGateway](PaymentGateway.java:3)

A service class responsible for processing payments. It is injected into `OrderService` via CDI (`@Inject`), meaning the container resolves it by type during dependency injection.

```java
public class PaymentGateway {
    public void charge() {}
}
```

**Key method:**

- `charge()` — Executes a payment charge. The current stub does nothing, indicating this is a placeholder for integration with a real payment processor (e.g., Stripe, PayPal). When implemented, this method would typically accept an amount and payment method, call the external API, and throw on failure.

### [InventoryService](InventoryService.java:3)

A service class responsible for managing inventory reservations. It is injected into `OrderService` via EJB (`@EJB`), meaning it is expected to be a stateless session bean deployed in the EJB container.

```java
public class InventoryService {
    public void reserve() {}
}
```

**Key method:**

- `reserve()` — Reserves inventory for an order. Like `charge()`, this is a stub awaiting real implementation. In production, this would check stock levels, decrement the available quantity, and potentially set an expiry on the reservation. Failure to reserve should ideally cause the `placeOrder()` flow to roll back the preceding `charge()` call.

### [NotificationService](NotificationService.java:3)

A service class responsible for sending notifications (e.g., order confirmation emails, SMS). It is injected into `OrderService` via Spring's `@Autowired` annotation, meaning this class is managed by the Spring application context rather than CDI or the EJB container.

```java
public class NotificationService {
    public void notify() {}
}
```

**Key method:**

- `notify()` — Sends a notification about the order. This is a stub awaiting real implementation. In production, this would populate an email template, queue a message, or call an external notification service.

### [EJBWithArgs](EJBWithArgs.java:5)

A demonstration EJB that shows how to inject a named EJB reference using `@EJB(name = "...")` and invoke its methods. It references a `MyService` of type `MyService` (defined outside this package) via a named EJB injection.

```java
public class EJBWithArgs {
    @EJB(name = "myBean")
    private MyService service;

    public void run() {
        service.process();
    }
}
```

**Key methods:**

- `run()` — Invokes `service.process()` on the injected `MyService`. This is a thin delegator pattern: the class exists primarily to demonstrate the `@EJB(name = "myBean")` annotation pattern, where the EJB name is bound explicitly rather than by type.

## How It Works

### The Order Placement Flow

When `OrderService.placeOrder()` is called, the following sequence occurs:

```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()
```

1. **Client calls `placeOrder()`** on the `OrderService` instance (obtained via lookup or injection).
2. **`PaymentGateway.charge()`** is called first. The actual payment is processed — if this fails (e.g., card declined), the method throws an exception and the order is abandoned before any side effects.
3. **`InventoryService.reserve()`** is called next. Inventory is reserved for the items in the order. If this fails (e.g., stock insufficient), the charge has already been processed — see "Notes for Developers" for implications.
4. **`NotificationService.notify()`** is called last. The customer receives an order confirmation.

### Dependency Injection Walkthrough

`OrderService` demonstrates a multi-framework injection scenario. Here's how each dependency is wired:

```mermaid
flowchart LR
    OS["OrderService"]
    PG["PaymentGateway"]
    IS["InventoryService"]
    NS["NotificationService"]
    SB["StatelessBean"]
    EJB["EJBWithArgs"]
    EJBSvc["MyService"]
    Container["EJB Container"]

    OS -->|"@Inject"| PG
    OS -->|"@EJB"| IS
    OS -->|"@Autowired"| NS
    OS -->|"@Resource"| DataSource["DataSource"]
    OS -->|calls| PG
    OS -->|calls| IS
    OS -->|calls| NS
    EJB -->|"@EJB"| EJBSvc
    EJB -->|calls| EJBSvc
    SB -->|"@Stateless"| Container
```

- **`PaymentGateway`** — Resolved by CDI (`@Inject`). The container looks up a bean of type `PaymentGateway` in the CDI bean archive and injects it.
- **`InventoryService`** — Resolved by the EJB container (`@EJB`). The container expects `InventoryService` to be deployed as an EJB (typically `@Stateless`) and performs a JNDI lookup using the field type.
- **`NotificationService`** — Resolved by Spring (`@Autowired`). This means the Spring application context manages this bean and `OrderService` itself must be a Spring-managed bean for the injection to work.
- **`DataSource`** — Resolved via JNDI lookup (`@Resource`). The container looks up a `DataSource` in the Java EE naming context (typically configured in the server's resource configuration).

### EJBWithArgs: Named Injection Pattern

`EJBWithArgs` shows a different injection style:

```java
@EJB(name = "myBean")
private MyService service;
```

The `name = "myBean"` attribute explicitly names the EJB to inject. This is useful when:
- The service type is shared by multiple implementations and you need to disambiguate by name.
- You want to reference an EJB from a remote deployment or a different module using a JNDI name.

## Data Model

This package does not define any entity classes, DTOs, or data model objects. All classes are thin service wrappers around external operations (payment, inventory, notifications). The `DataSource` field in `OrderService` hints that database access may occur at the level of the injected dependencies, but no data structures are modeled within this package.

## Dependencies and Integration

### Internal Dependencies

All five service classes (`PaymentGateway`, `InventoryService`, `NotificationService`, `StatelessBean`, `EJBWithArgs`) are part of the same package and are designed to work together as a cohesive unit. `OrderService` is the orchestrator, depending on the other four services.

### External Frameworks

| Framework | Annotation Used | Classes Affected |
|-----------|----------------|-----------------|
| Java EE EJB | `@Stateless`, `@EJB` | `StatelessBean`, `OrderService`, `EJBWithArgs` |
| CDI (JSR-365) | `@Inject` | `OrderService` |
| Spring Framework | `@Autowired` | `OrderService` |
| Java EE Resource | `@Resource` | `OrderService` |

### Cross-Package References

- `EJBWithArgs` references `MyService`, which is defined outside this package. This appears to be a utility or domain service used as a reference for EJB injection patterns.

## Notes for Developers

### Mixed Dependency Injection

`OrderService` uses four different injection annotations simultaneously (CDI, EJB, Spring, JNDI). While this is technically supported on many Java EE application servers, it creates several concerns:

1. **Fragility** — If any of the three containers (EJB container, CDI bean manager, Spring context) are not configured to coexist properly, injection will fail silently or at runtime.
2. **Maintenance burden** — New team members may be confused about which annotation applies to which dependency and why.
3. **Testing difficulty** — Unit testing `OrderService` requires wiring up all three injection mechanisms, or extracting the class into a test-double-friendly interface.

**Recommendation:** Consider consolidating to a single injection framework. If you are already using Spring, prefer `@Autowired` for all dependencies (and declare them as `@Component`/`@Service` beans). If you are on a pure Jakarta EE server, prefer `@Inject` + `@Named` or `@Stateless` across all services.

### Lack of Transaction Management

The `placeOrder()` method performs three side-effecting operations sequentially without any visible `@TransactionAttribute` or programmatic transaction handling. This means:

- **Partial failure risk** — If `charge()` succeeds but `reserve()` fails, the customer is charged for an order that was not placed in inventory.
- **No compensation** — There is no visible rollback, refund, or inventory release logic.

**Recommendation:** Wrap `placeOrder()` in a transaction (e.g., `@TransactionAttribute(REQUIRED)`) or use a saga/outbox pattern to ensure all three operations succeed or all three are compensated.

### Empty Stub Methods

`PaymentGateway.charge()`, `InventoryService.reserve()`, and `NotificationService.notify()` are all empty stubs. These are clearly placeholders awaiting real implementation. When filling these in:

- Add clear exception types so callers can distinguish between different failure modes (e.g., `PaymentDeclinedException`, `StockInsufficientException`).
- Consider adding parameters to match real-world usage (e.g., `charge(Order order)`, `reserve(List<OrderItem> items)`).

### StatelessBean

`StatelessBean` is a self-contained stateless session bean that simply prints a message. It is not referenced by any other class in this package, so it likely serves as:

- A test or example bean for EJB deployment verification.
- A placeholder for a future stateless business service.

There is no constructor, no injected resources, and no business logic beyond a console print.

### EJBWithArgs

`EJBWithArgs` demonstrates named EJB injection but depends on `MyService` from an external module. When working on this class, be aware that:

- `MyService` may not exist in the current codebase — it could be in a different module, a dependency JAR, or generated at build time.
- The `name = "myBean"` binding suggests the actual JNDI name used at runtime is `myBean`, which should match the `@EJB(name = "myBean")` lookup key.

### Concurrency

`StatelessBean` and `InventoryService` (when deployed as `@Stateless`) are thread-safe by contract. The container guarantees that only one thread executes a method on a given instance at a time. Do not store mutable state as instance fields in these classes — if you need state, use instance fields only within a single method call, or switch to a `@Singleton` with appropriate concurrency management.
