# Eo / Ejb

## Overview

The `eo.ejb` package is a subpackage under `eo` that provides a collection of small, focused utilities and enterprise components across three child packages. Collectively, this area demonstrates three distinct Java EE / J2EE patterns:

- **Reflection-based dynamic instantiation** (`eo.ejb.example`, `eo.ejb.wiki`) -- loading and creating classes at runtime from their fully qualified names.
- **EJB stateless session beans** (`eo.ejb.service`) -- lightweight container-managed beans with no conversational state.
- **Dependency injection via `@EJB`** (`eo.ejb.service`) -- wiring external service references through the EJB container.

This appears to serve as a reference collection and teaching module for understanding reflective class loading, stateless EJBs, and EJB-style dependency injection, rather than representing a production-grade subsystem.

## Sub-module Guide

### eo.ejb.example

The `example` package (`eo.ejb.example`) contains a single class, `PatternOneVar`, which demonstrates a reflective class-loading pattern. Its `load(String clsName)` method accepts a fully qualified class name as a string, resolves it via `Class.forName()`, instantiates it via `newInstance()`, and prints the result to stdout.

This is a standalone utility with no dependencies beyond the Java standard library. It is intended as a reference example -- it does not interact with any other sub-module.

**Key class:** `PatternOneVar.load(String clsName)`

### eo.ejb.service

The `service` package (`eo.ejb.service`) provides two lightweight EJB components:

- **`StatelessBean`** -- a `@Stateless` session bean that implements a trivial `execute()` method. It represents the simplest possible EJB structure -- no instance state, pooled by the container, thread-safe by design. This appears to be a template or demo bean for validating the EJB container setup.
- **`EJBWithArgs`** -- a container-managed class that holds an injected `MyService` reference (resolved via `@EJB(name = "myBean")`) and forwards calls through `run()` to `service.process()`. It contains no local business logic; its sole purpose is to demonstrate injection-based delegation.

These two classes illustrate the two ends of EJB usage: a bare stateless bean (`StatelessBean`) and a bean that consumes another injected dependency (`EJBWithArgs`).

### eo.ejb.wiki

The `wiki` package (`eo.ejb.wiki`) provides two utility classes:

- **`PlainClass`** -- a simple name-based greeting utility. It stores a `String name` and returns `"Hello, "` + name via `greet()`. This is an immutable utility with no complex behavior.
- **`ReflectiveClass`** -- a reflection-based factory and invoker. It stores a fully qualified class name and provides `loadByReflection()` (which uses `Class.forName()` + `newInstance()`, mirroring `PatternOneVar` from `eo.ejb.example`) and `invokeMethod(Class<?>)` (which looks up a public static `execute()` method on a given class and invokes it via reflection).

Notably, `eo.ejb.wiki` declares a package-level outgoing dependency on `eo.ejb.service`. This is the only cross-package relationship in the entire `eo.ejb` hierarchy.

### How the sub-modules relate

```
eo.ejb
├── example   → standalone reflective loading demo (no dependencies)
├── service   → EJB stateless beans + injection client
└── wiki      → string utility + reflection factory (depends on service)
```

- **`example` and `wiki` overlap in purpose**: both demonstrate reflection-based class loading. `PatternOneVar` in `example` is a simplified, one-method version of what `ReflectiveClass` does in `wiki`. One could view `example` as a distilled reference derived from the more capable pattern in `wiki`.
- **`wiki` depends on `service`**: The `wiki` package has an explicit package-level dependency on `eo.ejb.service`, suggesting it may use or reference service-layer classes at runtime.
- **`service` is the only package with EJB-specific behavior**: `@Stateless` and `@EJB` annotations appear only in `service`. Neither `example` nor `wiki` interact with the EJB container.

## Key Patterns and Architecture

### Reflection-based dynamic instantiation (repeated across two packages)

Both `PatternOneVar` (`example`) and `ReflectiveClass` (`wiki`) use the same core reflection pattern:

1. Resolve a `Class` object from its fully qualified name via `Class.forName()`.
2. Instantiate via `newInstance()` (no-arg constructor required).
3. Return or act on the resulting `Object`.

This pattern is repeated independently in two packages. `ReflectiveClass` adds a second dimension: `invokeMethod()`, which uses reflection to find and call a public static `execute()` method on an arbitrary class. This creates a reflection-based "command invoker" pattern.

### EJB stateless pattern

`StatelessBean` (`service`) follows the classic EJB stateless session bean pattern:

- Marked with `@Stateless` -- the container pools instances and routes calls efficiently.
- No instance fields hold conversational state -- inherently thread-safe.
- Single public method (`execute()`) performs a trivial side-effect (stdout logging).

### Dependency injection via @EJB

`EJBWithArgs` (`service`) demonstrates EJB-style dependency injection:

- The `@EJB(name = "myBean")` annotation tells the container to inject a `MyService` reference resolved from JNDI.
- `run()` is a pass-through -- it exists purely as a delegation point.

This is the "thin client" pattern: the class adds no local logic, acting as an injected bridge between an entry point and the actual service.

### Architecture diagram

The following diagram shows how the three sub-modules interact and depend on each other:

```mermaid
flowchart TD
    ROOT["eo.ejb Package"]
    ROOT --> EX["eo.ejb.example
reflective class-loading example"]
    ROOT --> SVC["eo.ejb.service
EJB stateless beans + injection client"]
    ROOT --> WIKI["eo.ejb.wiki
string utility + reflection factory"]
    EX --> PAT["PatternOneVar.load()
Class.forName + newInstance"]
    SVC --> BEAN["StatelessBean
@Stateless container bean"]
    SVC --> CLIENT["EJBWithArgs
@EJB injection + delegation"]
    WIKI --> PLAIN["PlainClass
name-based greeting"]
    WIKI --> REFLECT["ReflectiveClass
loadByReflection + invokeMethod"]
    REFLECT --> TARGET["Target class via reflection
execute() invocation"]
    WIKI -->|depends on| SVC
```

### Typical interaction flows

The following sequence diagram illustrates how callers might interact with both the reflection-based and EJB-based components:

```mermaid
sequenceDiagram
    participant CALL as Caller
    participant REF as ReflectiveClass
    participant WIKI as eo.ejb.wiki
    participant SVC as eo.ejb.service
    participant EJB as EJB Container
    CALL->>REF: loadByReflection(targetClass)
    REF->>WIKI: Class.forName(targetClass)
    WIKI-->>REF: Class object
    REF->>WIKI: newInstance()
    WIKI-->>REF: Object instance
    REF-->>CALL: loaded Object
    CALL->>EJB: lookup StatelessBean
    EJB-->>CALL: StatelessBean instance
    CALL->>SVC: invoke EJBWithArgs.run()
    SVC->>EJB: resolve @EJB MyService
    EJB-->>SVC: MyService reference
    SVC->>SVC: service.process()
```

## Dependencies and Integration

### Internal dependencies

Within the `eo.ejb` package, there is one known cross-package dependency:

| Source       | Target           | Direction |
|-------------|-----------------|-----------|
| `eo.ejb.wiki` | `eo.ejb.service` | Outgoing  |

`eo.ejb.wiki` depends on `eo.ejb.service` at the package level. No other cross-package relationships exist.

### External dependencies

| Package       | Types Used                              |
|--------------|----------------------------------------|
| `example`    | `java.lang.Class`, `java.lang.System`  |
| `service`    | `javax.ejb.EJB`, `javax.ejb.Stateless` |
| `wiki`       | `java.lang.String`, `java.lang.reflect` (plus transitive `eo.ejb.service`) |

### No third-party libraries

None of the sub-modules import external frameworks or libraries. The entire `eo.ejb` hierarchy depends solely on the Java standard library and the Java EE EJB API (`javax.ejb`).

## Notes for Developers

### Reflection caveats (example, wiki)

Both `PatternOneVar` (`example`) and `ReflectiveClass` (`wiki`) use `Class.newInstance()`, which was deprecated in Java 9. If migrating to newer Java versions, consider replacing `Class.newInstance()` with `Class.getDeclaredConstructor().newInstance()`.

- `ReflectiveClass.loadByReflection()` requires the target class to have an accessible no-argument constructor. There is no way to pass constructor arguments through the current API.
- `ReflectiveClass.invokeMethod()` expects a **public static** `execute()` method -- it calls `m.invoke(null)`. This is a contract that callers must ensure is met.
- Neither class validates its class name arguments. Passing untrusted input to `loadByReflection()` or `PatternOneVar.load()` is a potential security risk. Consider whitelisting allowed class names.
- Both classes declare `throws Exception` without catching specific exception types. Callers must handle `ClassNotFoundException`, `InstantiationException`, `IllegalAccessException`, and `NoSuchMethodException` (for `invokeMethod`).

### EJB caveats (service)

- `StatelessBean` is a template -- the current implementation only prints to stdout. When extending it, maintain the stateless contract: do not add instance fields that hold conversational state, as the container pools instances and those fields would not be safe across pooled invocations.
- `EJBWithArgs` depends on `MyService` being available in the container under the JNDI name `"myBean"`. If the bean is missing or misconfigured, injection will fail at deployment time.
- `EJBWithArgs` contains no business logic of its own. It is a pure delegation class -- this is intentional by design, not an oversight.

### Structural notes

- `eo.ejb` is a subpackage directly under `eo` with no parent-level Java source files of its own.
- `eo.ejb.example` and `eo.ejb.wiki` have no child subpackages.
- `eo.ejb.service` has no child subpackages.
- There are no entity classes, DTOs, or persistent data models in any of the three sub-packages.
