# Eo / Ejb / Wiki

The `eo.ejb.wiki` package contains two utility classes focused on object creation and method invocation. One class (`PlainClass`) provides a straightforward data-holder with a greeting method, while the other (`ReflectiveClass`) uses Java reflection to dynamically load classes and invoke methods at runtime. This appears to be an experimental or testing package demonstrating basic object-oriented patterns alongside Java reflection capabilities.

## Key Classes and Interfaces

### PlainClass

`PlainClass` is a simple value object that stores a name and returns a personalized greeting. It has no dependencies on external frameworks and serves as a basic example of encapsulated state with behavior.

**Fields:**

- `name` (`String`) — the name stored in this instance, set at construction time and never modified.

**Methods:**

- **[PlainClass(String name)](PlainClass.java:6)** — Constructor. Initializes the `name` field with the provided value. No validation is performed on the input.

- **[greet()](PlainClass.java:10)** — Returns a greeting string in the format `"Hello, " + name`. Does not mutate internal state.

### ReflectiveClass

`ReflectiveClass` is a reflection-based utility that dynamically loads classes by name and invokes methods on them. It demonstrates how to use Java's reflection API (`java.lang.Class`, `java.lang.reflect.Method`) to achieve runtime polymorphism without compile-time type knowledge.

**Fields:**

- `targetClass` (`String`) — the fully-qualified name of a class to load via reflection. Set at construction time.

**Methods:**

- **[ReflectiveClass(String targetClass)](ReflectiveClass.java:6)** — Constructor. Stores the provided class name for later use by `loadByReflection()`. No validation is performed; invalid class names will throw at runtime when `loadByReflection()` is called.

- **[loadByReflection()](ReflectiveClass.java:10)** — Dynamically loads a class by name and creates a new instance. Uses `Class.forName(targetClass).newInstance()`. Returns an `Object` — the caller must cast to the appropriate type. Throws `Exception` if the class is not found, is not accessible, or has no no-arg constructor. This is a convenience wrapper around the reflection API; in production code, consider using `Class.getMethod().newInstance()` or dependency injection frameworks.

- **[invokeMethod(Class<?> cls)](ReflectiveClass.java:14)** — Reflectively invokes a method named `execute` (with no parameters) on the given class. Gets the method via `cls.getMethod("execute")` and invokes it statically (`m.invoke(null)`) — meaning `execute` must be a `public static` method. Throws `Exception` if the method is not found, is not static, or throws during invocation. This appears to be a simple bridge for calling a standardized `execute()` entry point on any class without knowing its type at compile time.

## How It Works

The two classes in this package take different approaches to creating and using objects:

**PlainClass — Compile-time binding:** The object's behavior is determined at compile time. You construct an instance with a name and call `greet()` to get the greeting. There is no flexibility — the class, its methods, and their signatures are all known at compile time.

**ReflectiveClass — Runtime binding:** This class defers type resolution until runtime. `loadByReflection()` accepts a class name as a string, loads the class dynamically, and returns an instance. `invokeMethod()` accepts any `Class<?>` and invokes a method named `execute` on it without knowing the class ahead of time.

This contrast between the two classes appears intentional, illustrating the trade-offs between compile-time type safety (PlainClass) and runtime flexibility (ReflectiveClass).

## Data Model

Both classes follow a simple field-based pattern with no complex relationships:

```
PlainClass
  +-- name: String

ReflectiveClass
  +-- targetClass: String
```

`ReflectiveClass.invokeMethod()` accepts a `Class<?>` parameter, which allows the caller to specify the type at runtime, decoupling the method invocation from any particular class.

## Mermaid Diagram: Class Structure

```mermaid
flowchart TD
    Wiki["eo.ejb.wiki package"]
    PC["PlainClass"]
    RC["ReflectiveClass"]
    PC -->|fields| PName["name : String"]
    PC -->|methods| PGreet["greet() : String"]
    RC -->|fields| RTarget["targetClass : String"]
    RC -->|methods| RLoad["loadByReflection() : Object"]
    RC -->|methods| RInvoke["invokeMethod(Class) : void"]
    Wiki --> PC
    Wiki --> RC
```

## Dependencies and Integration

- **Internal package dependencies:** None. This package is self-contained.
- **External dependencies:** `ReflectiveClass` uses the standard Java reflection API (`java.lang.Class`, `java.lang.reflect.Method`) from the JDK. No third-party libraries are required.
- **Cross-module relationships:** None detected. This package does not appear to be consumed by or import from other modules.

## Notes for Developers

- **ReflectiveClass throws broadly:** Both `loadByReflection()` and `invokeMethod()` declare `throws Exception`. Callers must handle `ClassNotFoundException`, `InstantiationException`, `IllegalAccessException`, `NoSuchMethodException`, and `InvocationTargetException`. Consider catching and wrapping these in more specific runtime exceptions in usage code.

- **Static method contract:** `invokeMethod()` expects the target method to be `public static`. There is no enforcement of this at compile time — a non-static `execute()` method will cause an `IllegalAccessException` at runtime. Document or add a check if this contract is important.

- **No-null safety:** Neither class validates constructor arguments. Passing `null` for `name` or `targetClass` will work for `PlainClass` (resulting in `"Hello, null"`) but will cause `NullPointerException` in `ReflectiveClass` when `Class.forName()` is called.

- **`newInstance()` deprecation:** `Class.newInstance()` has been deprecated since Java 9 in favor of `getConstructor().newInstance()`. Consider updating if this code is maintained for newer JDKs.

- **Extension points:** To add more reflection behavior to `ReflectiveClass`, you could add methods that pass parameters to `Method.invoke()`, or support field access via reflection. The class structure makes it straightforward to add new reflective operations.

- **Testing suggestion:** `PlainClass` is easy to unit test with simple string assertions. `ReflectiveClass` tests will need to provide valid classes on the classpath that conform to the expected `public static void execute()` signature.
