Since standard Java Reflection cannot access the `<clinit>` method (class's static initializer), we add a new native function, `HookBridge.getStaticInitializer`, which uses JNI `GetStaticMethodID` to retrieve a `Method` handle for it. The `LSPosedContext` API then passes this handle to the existing `doHook` machinery.
There are two possible exceptions thrown by the API:
- `IllegalArgumentException`: Thrown for user-level errors, such as attempting to hook a class that has no static initializer block (`static { ... }`). This is a predictable failure based on the provided class.
- `HookFailedError`: Thrown when the underlying native hooking engine (`lsplant`) fails to install the hook. This indicates a framework or environment-level issue (e.g., ART incompatibility, method inlining by the JIT/AOT compiler) and is not a fault in the module's logic.
We update `LSPosedBridge` to align with upstream API changes, which have replaced annotation-based hooker discovery with a naming convention.
The `doHook` implementation has been refactored to:
- Remove dependencies on the deleted `io.github.libxposed.api.annotations` package (`XposedHooker`, `BeforeInvocation`, `AfterInvocation`).
- Scan for public static methods explicitly named `before` and `after` instead of relying on annotations.
- Enforce validation on these named methods to ensure they match the required signatures.
To adapt to this change, existing Hooker classes are refactored by removing the deprecated annotations and renaming their callback methods to `before` and `after` respectively.
Co-authored-by: frknkrc44 <krc440002@gmail.com>
Unlike the existing `newInstance` variants which allocate and return a new object, these new APIs execute constructor logic on an existing, pre-allocated instance (`thisObject`). This separation of allocation and initialization allows for invoking original or super constructors within hook callbacks where the object reference is already established.
The implementation leverages the existing JNI `HookBridge` methods, as `invokeOriginalMethod` and `invokeSpecialMethod` already support void-return signatures required for constructor execution.
Co-authored-by: frknkrc44 <krc440002@gmail.com>
Centralize dependencies and migrate to submodules
Move `apache` and `axml` modules to a unified `external` directory and migrate libxposed API and service interfaces from Maven dependencies to Git submodules.
Included changes:
- Updated .gitmodules with new paths.
- Simplified core.yml CI workflow.
- Updated Gradle project references to use the new directory structure.
- Added documentation for external components.
In the LSPosedDexParser constructor, the methodIds array is allocated correctly, but the loop condition is wrong: its length is divided by 3 twice.
We rewrite this class in Kotlin, marking the first commit of refactoring LSPosed into Vector.
Co-authored-by: Willian Wang <git@willian.wang>