{"id":15038344,"url":"https://github.com/linkedin/dexmaker","last_synced_at":"2025-12-16T16:58:26.968Z","repository":{"id":24714353,"uuid":"28126132","full_name":"linkedin/dexmaker","owner":"linkedin","description":"A utility for doing compile or runtime code generation targeting Android's Dalvik VM","archived":false,"fork":false,"pushed_at":"2025-03-01T20:27:57.000Z","size":5707,"stargazers_count":1903,"open_issues_count":29,"forks_count":254,"subscribers_count":99,"default_branch":"main","last_synced_at":"2025-04-10T12:40:23.150Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/linkedin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2014-12-17T07:22:19.000Z","updated_at":"2025-04-10T07:51:08.000Z","dependencies_parsed_at":"2022-07-14T21:30:35.660Z","dependency_job_id":"57f68fd7-9e15-42b6-ac7c-0a92f583ab8f","html_url":"https://github.com/linkedin/dexmaker","commit_stats":{"total_commits":259,"total_committers":48,"mean_commits":5.395833333333333,"dds":0.7837837837837838,"last_synced_commit":"51aea602f6d972235808e8323d345244f2e6ecc4"},"previous_names":["crittercism/dexmaker"],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkedin%2Fdexmaker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkedin%2Fdexmaker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkedin%2Fdexmaker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/linkedin%2Fdexmaker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/linkedin","download_url":"https://codeload.github.com/linkedin/dexmaker/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251561241,"owners_count":21609361,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T20:38:05.297Z","updated_at":"2025-12-16T16:58:26.962Z","avatar_url":"https://github.com/linkedin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dexmaker\n[![Build Status](https://img.shields.io/github/workflow/status/linkedin/dexmaker/Merge%20checks)](https://img.shields.io/github/workflow/status/linkedin/dexmaker/Merge%20checks)\n\nA Java-language API for doing compile time or runtime code generation targeting the Dalvik VM. Unlike\n[cglib](http://cglib.sourceforge.net/) or [ASM](http://asm.ow2.org/), this library creates Dalvik `.dex`\nfiles instead of Java `.class` files.\n\nIt has a small, close-to-the-metal API. This API mirrors the\n[Dalvik bytecode specification](http://source.android.com/devices/tech/dalvik/dalvik-bytecode.html) giving you tight\ncontrol over the bytecode emitted. Code is generated instruction-by-instruction; you bring your own abstract\nsyntax tree if you need one. And since it uses Dalvik's `dx` tool as a backend, you get efficient register\nallocation and regular/wide instruction selection for free.\n\n## What does it do?\n\n### Mockito Mocks\nDexmaker lets you use the [Mockito](https://github.com/mockito/mockito) mocking library in your\nAndroid projects by generating Dalvik bytecode class proxies. Just add an\n`androidTestImplementation` dependency on `dexmaker-mockito` and you can use Mockito in your Android Instrumentation tests.\n\nThe version of Mockito that Dexmaker targets can be found in `dexmaker-mockito`'s [build.gradle](https://github.com/linkedin/dexmaker/blob/main/dexmaker-mockito/build.gradle) file. The general rule is that the major and minor version of Dexmaker will match the underlying major and minor version of Mockito.\n\n### Mocking Final Classes \u0026 Methods\nStarting in Android \"P\", it is possible to mock final classes and methods using the `dexmaker-mockito-inline` library. If you execute your tests on a device or emulator running Android P or above, you can add an `androidTestImplementation` dependency on `dexmaker-mockito-inline` (instead of `dexmaker-mockito`; don't add both) and you can use the normal Mockito APIs to mock final classes and methods in your Android Instrumentation tests.\n\n**NOTE:** This functionality requires OS APIs which were introduced in Android P and cannot work on older versions of Android.\n\n### Class Proxies\nDexmaker includes a stock code generator for [class proxies](https://github.com/crittercism/dexmaker/blob/main/dexmaker/src/main/java/com/android/dx/stock/ProxyBuilder.java).\nIf you just want to do AOP or class mocking, you don't need to mess around with bytecodes.\n\n### Runtime Code Generation\nThis example generates a class and a method. It then loads that class into the current process and invokes its method.\n\n``` java\npublic final class HelloWorldMaker {\n    public static void main(String[] args) throws Exception {\n        DexMaker dexMaker = new DexMaker();\n\n        // Generate a HelloWorld class.\n        TypeId\u003c?\u003e helloWorld = TypeId.get(\"LHelloWorld;\");\n        dexMaker.declare(helloWorld, \"HelloWorld.generated\", Modifier.PUBLIC, TypeId.OBJECT);\n        generateHelloMethod(dexMaker, helloWorld);\n\n        // Create the dex file and load it.\n        File outputDir = new File(\".\");\n        ClassLoader loader = dexMaker.generateAndLoad(HelloWorldMaker.class.getClassLoader(),\n                outputDir, outputDir);\n        Class\u003c?\u003e helloWorldClass = loader.loadClass(\"HelloWorld\");\n\n        // Execute our newly-generated code in-process.\n        helloWorldClass.getMethod(\"hello\").invoke(null);\n    }\n\n    /**\n     * Generates Dalvik bytecode equivalent to the following method.\n     *    public static void hello() {\n     *        int a = 0xabcd;\n     *        int b = 0xaaaa;\n     *        int c = a - b;\n     *        String s = Integer.toHexString(c);\n     *        System.out.println(s);\n     *        return;\n     *    }\n     */\n    private static void generateHelloMethod(DexMaker dexMaker, TypeId\u003c?\u003e declaringType) {\n        // Lookup some types we'll need along the way.\n        TypeId\u003cSystem\u003e systemType = TypeId.get(System.class);\n        TypeId\u003cPrintStream\u003e printStreamType = TypeId.get(PrintStream.class);\n\n        // Identify the 'hello()' method on declaringType.\n        MethodId hello = declaringType.getMethod(TypeId.VOID, \"hello\");\n\n        // Declare that method on the dexMaker. Use the returned Code instance\n        // as a builder that we can append instructions to.\n        Code code = dexMaker.declare(hello, Modifier.STATIC | Modifier.PUBLIC);\n\n        // Declare all the locals we'll need up front. The API requires this.\n        Local\u003cInteger\u003e a = code.newLocal(TypeId.INT);\n        Local\u003cInteger\u003e b = code.newLocal(TypeId.INT);\n        Local\u003cInteger\u003e c = code.newLocal(TypeId.INT);\n        Local\u003cString\u003e s = code.newLocal(TypeId.STRING);\n        Local\u003cPrintStream\u003e localSystemOut = code.newLocal(printStreamType);\n\n        // int a = 0xabcd;\n        code.loadConstant(a, 0xabcd);\n\n        // int b = 0xaaaa;\n        code.loadConstant(b, 0xaaaa);\n\n        // int c = a - b;\n        code.op(BinaryOp.SUBTRACT, c, a, b);\n\n        // String s = Integer.toHexString(c);\n        MethodId\u003cInteger, String\u003e toHexString\n                = TypeId.get(Integer.class).getMethod(TypeId.STRING, \"toHexString\", TypeId.INT);\n        code.invokeStatic(toHexString, s, c);\n\n        // System.out.println(s);\n        FieldId\u003cSystem, PrintStream\u003e systemOutField = systemType.getField(printStreamType, \"out\");\n        code.sget(systemOutField, localSystemOut);\n        MethodId\u003cPrintStream, Void\u003e printlnMethod = printStreamType.getMethod(\n                TypeId.VOID, \"println\", TypeId.STRING);\n        code.invokeVirtual(printlnMethod, null, localSystemOut, s);\n\n        // return;\n        code.returnVoid();\n    }\n}\n```\n\n## Download\n\nFor Mockito support, download the latest .jar via Maven:\n```xml\n    \u003cdependency\u003e\n      \u003cgroupId\u003ecom.linkedin.dexmaker\u003c/groupId\u003e\n      \u003cartifactId\u003edexmaker-mockito\u003c/artifactId\u003e\n      \u003cversion\u003e2.28.6\u003c/version\u003e\n      \u003ctype\u003epom\u003c/type\u003e\n    \u003c/dependency\u003e\n```\n\nor Gradle:\n```\n    androidTestImplementation 'com.linkedin.dexmaker:dexmaker-mockito:2.28.6'\n```\n\n_Note: The dependency on Mockito will be transitively included, so there's no need to specify both Mockito AND dexmaker-mockito_\n\n## Snapshots\n\nYou can use snapshot builds to test the latest unreleased changes. A new snapshot is published\nafter every merge to the main branch by the [Deploy Snapshot Github Action workflow](.github/workflows/deploy-snapshot.yml).\n\nJust add the Sonatype snapshot repository to your Gradle scripts:\n```gradle\nrepositories {\n    maven {\n        url \"https://oss.sonatype.org/content/repositories/snapshots/\"\n    }\n}\n```\n\nYou can find the latest snapshot version to use in the [gradle.properties](gradle.properties) file.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinkedin%2Fdexmaker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flinkedin%2Fdexmaker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flinkedin%2Fdexmaker/lists"}