EzHook
An AOP framework for KotlinMultiplatform, supporting Kotlin/Native and Kotlin/JS.
Install / Use
/learn @XDMrWu/EzHookREADME
EzHook
An AOP framework for KotlinMultiplatform, supporting Kotlin/Native and Kotlin/JS.
Project Configuration
EzHook consists of two main components: a Gradle plugin and a runtime library. The Gradle plugin handles compile-time data collection and IR transformation, while the library provides essential annotations and runtime support. To enable EzHook, add the Gradle plugin in your top-level project configuration:
// Root-level build.gradle.kts
buildscript {
dependencies {
classpath("io.github.xdmrwu:ez-hook-gradle-plugin:0.0.2")
}
}
// Apply the EzHook plugin in your top-level module
plugins {
id("io.github.xdmrwu.ez-hook-gradle-plugin")
}
Then add the EzHook runtime library to any module where you want to use its features:
kotlin {
sourceSets {
commonMain.dependencies {
implementation("io.github.xdmrwu:ez-hook-library:0.0.2")
}
}
}
To ensure EzHook works correctly, you need to disable Kotlin/Native caching by adding the following line to your gradle.properties file:
// gradle.properties
kotlin.native.cacheKind=none
Usage
EzHook is an AOP framework similar to Lancet. It allows you to replace any method at compile time with a specified custom method.
To use EzHook, create a hook method and annotate it with @EzHook, specifying the target method’s fully qualified name.
Example:
@HiddenFromObjC
@EzHook("kotlin.time.Duration.toInt")
fun toInt(unit: DurationUnit): Int {
println("Hook to int")
return 10086
}
In this example, the toInt method of the Duration class will be replaced by the custom toInt method.
Key Considerations:
- The
@EzHookannotation takes the fully qualified name (FQN) of the target method. It also supports top-level functions. - The name of the hook method can be arbitrary, but the number, types of parameters, and the return type must match the target method.
- Hook methods must be top-level functions.
- If the target platform includes iOS, the
@HiddenFromObjCannotation needs to be added.
Calling the Original Method
EzHook allows you to invoke the original method and modify its parameters within the hook. Here’s how to do it:
- Create a variable with the same name and type as the original parameter to override its value.
- Use
callOrigin<T>()to invoke the original method.
Example:
@EzHook("kotlin.time.Duration.toInt")
fun toInt(unit: DurationUnit): Int {
val unit = DurationUnit.HOURS
return callOrigin<Int>()
}
Inline Hook Functions for Kotlin/JS
In Kotlin/JS, circular dependencies between modules can easily cause runtime crashes. To prevent this, you can inline the hook function directly into the target module. This ensures the hook logic is part of the module, reducing the risk of dependency-related issues.
Here’s how to configure inlining for Kotlin/JS:
@EzHook("kotlin.time.Duration.toInt", true)
fun toInt(unit: DurationUnit): Int {
val unit = DurationUnit.HOURS
return callOrigin<Int>()
}
Limitations
- Only supports Kotlin/Native and Kotlin/JS targets
- Extension functions and constructors are not supported
- Currently compatible with Kotlin version 2.0.21 only
Related Skills
openhue
350.1kControl Philips Hue lights and scenes via the OpenHue CLI.
sag
350.1kElevenLabs text-to-speech with mac-style say UX.
weather
350.1kGet current weather and forecasts via wttr.in or Open-Meteo
casdoor
13.3kAn open-source AI-first Identity and Access Management (IAM) /AI MCP & agent gateway and auth server with web UI supporting OpenClaw, MCP, OAuth, OIDC, SAML, CAS, LDAP, SCIM, WebAuthn, TOTP, MFA, Face ID, Google Workspace, Azure AD
