# Eo / Ejb / Wiki

## Overview

The `eo.ejb.wiki` package contains two classes that demonstrate contrasting programming approaches within the same package: a simple, straightforward data class and a reflection-based utility class. The `PlainClass` serves as a basic model that wraps a string value with a greeting method, while `ReflectiveClass` provides runtime class discovery and method invocation capabilities via Java Reflection. Together, they appear to serve as example or demo code illustrating both direct and reflective programming patterns.

## Key Classes and Interfaces

### PlainClass

**Source:** [PlainClass.java](PlainClass.java:3)

`PlainClass` is a simple POJO (Plain Old Java Object) that wraps a single `name` string field and provides a greeting method. It has no dependencies, no external interaction, and no side effects — it is purely a data carrier with a single derived operation.

#### Constructor

`PlainClass(String name)` ([PlainClass.java:6](PlainClass.java:6))

Initializes the instance with the given name. The name is stored in a private field and is immutable for the lifetime of the object (there is no setter).

**Parameter:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `name` | `String` | The name to use for greeting output. May be `null`, which would produce `"Hello, null"`. |

#### Methods

`greet()` ([PlainClass.java:10](PlainClass.java:10))

Returns a greeting string in the format `"Hello, " + name`.

- **Returns:** `String` — the greeting message
- **Side effects:** None
- **Notes:** This is a pure, stateless computation based on the stored name. No validation is performed on the name value.

### ReflectiveClass

**Source:** [ReflectiveClass.java](ReflectiveClass.java:3)

`ReflectiveClass` uses Java Reflection to dynamically load classes by their fully qualified name and invoke methods at runtime. This class is a utility for runtime class discovery, which is fundamentally different from `PlainClass`'s compile-time approach. It should be noted that the code uses `Class.newInstance()`, which has been deprecated since Java 9 in favor of `Class.getDeclaredConstructor().newInstance()`.

#### Constructor

`ReflectiveClass(String targetClass)` ([ReflectiveClass.java:6](ReflectiveClass.java:6))

Stores the fully qualified class name string to be used later for reflection.

**Parameter:**

| Parameter | Type | Description |
|-----------|------|-------------|
| `targetClass` | `String` | The fully qualified name of a class that must be loadable by the system class loader (e.g., `"java.lang.String"`). |

#### Methods

`loadByReflection()` ([ReflectiveClass.java:10](ReflectiveClass.java:10))

Dynamically loads a class by name and creates an instance of it using reflection.

- **Returns:** `Object` — a new instance of the class specified by `targetClass`
- **Throws:** `Exception` — wraps `ClassNotFoundException` if the class name is invalid, `InstantiationException` if the class cannot be instantiated, and `IllegalAccessException` if the constructor is not accessible
- **Notes:** This method uses the deprecated `Class.newInstance()`. Consider migrating to `Class.getDeclaredConstructor().newInstance()` for Java 9+ compatibility. The `targetClass` string is used directly via `Class.forName()`, so it must be a fully qualified class name.

`invokeMethod(Class<?> cls)` ([ReflectiveClass.java:14](ReflectiveClass.java:14))

Reflectively looks up and invokes a method named `execute` on the given class.

- **Parameter:**

  | Parameter | Type | Description |
  |-----------|------|-------------|
  | `cls` | `Class<?>` | The class whose `execute` method should be invoked. |

- **Returns:** `void`
- **Throws:** `Exception` — wraps `NoSuchMethodException` if `execute` is not found, `IllegalAccessException` if it is not accessible, and `InvocationTargetException` if the invoked method itself throws an exception
- **Notes:** The method invokes `execute` as a **static** (zero-argument) method — it passes `null` as the instance argument to `Method.invoke()`. This means the target class must declare a public static no-arg method `void execute()`. If multiple `execute` methods exist (overloaded), the one matching exactly zero parameters will be selected.

## How It Works

These two classes are independent — there is no direct interaction between them. They demonstrate two different approaches to the same fundamental concept: performing an operation (producing a result).

### Flow: PlainClass (Direct Approach)

1. Create an instance with a name via the constructor: `new PlainClass("World")`
2. Call `greet()` to get the result: `"Hello, World"`

This is a direct, compile-time-safe approach. No exceptions are thrown. The behavior is fully known at compile time.

### Flow: ReflectiveClass (Reflective Approach)

1. Create an instance with a class name: `new ReflectiveClass("java.lang.String")`
2. Call `loadByReflection()` — the class is looked up at runtime via `Class.forName()`, and a new instance is created
3. Optionally, call `invokeMethod(String.class)` — the `execute` method is resolved at runtime and invoked on the class

This approach defers all type resolution to runtime. This provides flexibility (you can load any class whose name is stored in a string) at the cost of compile-time safety. Errors in class or method names will only surface at runtime.

## Class Relationship Diagram

```mermaid
flowchart LR
    PKG["Package eo.ejb.wiki"]
    subgraph PKG_CONTENT [ ]
        PC["PlainClass"]
        RC["ReflectiveClass"]
    end
    PKG --> PKG_CONTENT
    PC ---|independent| RC
```

Both classes live in the same package but have no dependencies on each other. They serve as contrasting examples within the same namespace.

## Dependencies and Integration

- **No external dependencies** — this package does not depend on any other package or external library
- **No child modules** — there are no sub-packages within `eo.ejb.wiki`
- **Reflection usage** — `ReflectiveClass` uses the standard `java.lang.reflect` API which is part of the JDK core (`java.base`), so no additional libraries are needed
- **No cross-module relationships** — this package is self-contained

## Notes for Developers

1. **Reflection deprecation**: `ReflectiveClass.loadByReflection()` uses `Class.newInstance()`, which has been deprecated since Java 9. When updating to newer Java versions, replace it with:
   ```java
   Class.forName(targetClass).getDeclaredConstructor().newInstance();
   ```

2. **Null safety**: Neither class performs null checks on constructor parameters. Passing `null` as the name in `PlainClass` or as the class name in `ReflectiveClass` will result in a runtime exception or unexpected output.

3. **Static method invocation**: `ReflectiveClass.invokeMethod()` assumes the target class has a static no-arg method called `execute`. There is no validation that such a method exists until runtime.

4. **Exception handling**: Both reflective methods declare `throws Exception` broadly rather than specific exception types. Callers should handle the specific subclasses (`ClassNotFoundException`, `NoSuchMethodException`, etc.) for cleaner error handling.

5. **Security**: Dynamically loading and invoking classes via reflection can be a security concern if the `targetClass` or `cls` parameters originate from untrusted input. Validate and sanitize these values before use.
