{"id":14969602,"url":"https://github.com/jpenilla/reflection-remapper","last_synced_at":"2025-10-26T09:30:50.478Z","repository":{"id":43217740,"uuid":"422437648","full_name":"jpenilla/reflection-remapper","owner":"jpenilla","description":"Java reflection library with support for obfuscation mappings","archived":false,"fork":false,"pushed_at":"2024-03-15T03:31:34.000Z","size":337,"stargazers_count":93,"open_issues_count":2,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-09-28T12:01:25.899Z","etag":null,"topics":["java","mappings","papermc","reflection","remapping"],"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/jpenilla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"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":"2021-10-29T04:06:23.000Z","updated_at":"2024-09-28T01:57:18.000Z","dependencies_parsed_at":"2023-02-12T14:30:45.416Z","dependency_job_id":"1c1c4fd6-708b-420b-b22d-1d839f94e902","html_url":"https://github.com/jpenilla/reflection-remapper","commit_stats":{"total_commits":55,"total_committers":2,"mean_commits":27.5,"dds":"0.018181818181818188","last_synced_commit":"046b4d205c043bacbfd09c8e1b458ea8e8c634ac"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpenilla%2Freflection-remapper","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpenilla%2Freflection-remapper/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpenilla%2Freflection-remapper/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jpenilla%2Freflection-remapper/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jpenilla","download_url":"https://codeload.github.com/jpenilla/reflection-remapper/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219863300,"owners_count":16555950,"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":["java","mappings","papermc","reflection","remapping"],"created_at":"2024-09-24T13:42:06.293Z","updated_at":"2025-10-26T09:30:50.472Z","avatar_url":"https://github.com/jpenilla.png","language":"Java","readme":"# reflection-remapper\nreflection-remapper is a library to simplify making reflective calls, with specific support for remapped environments.\n\n## Getting reflection-remapper\nReleases are published to [Maven Central](https://central.sonatype.com/artifact/xyz.jpenilla/reflection-remapper).\n\n\u003e \u003cdetails open\u003e\n\u003e \u003csummary\u003eUsing snapshot builds\u003c/summary\u003e\n\u003e\n\u003e Snapshot builds are available on the Sonatype snapshots Maven repository: `https://s01.oss.sonatype.org/content/repositories/snapshots/`\n\u003e\n\u003e Consult your build tool's documentation for details on adding Maven repositories to your project.\n\u003e \u003c/details\u003e\n\n### Gradle Kotlin DSL\n\u003e \u003cdetails open\u003e\n\u003e \u003csummary\u003eClick to show build.gradle.kts\u003c/summary\u003e\n\u003e \n\u003e ```kotlin\n\u003e repositories {\n\u003e   mavenCentral()\n\u003e }\n\u003e \n\u003e dependencies {\n\u003e   implementation(\"xyz.jpenilla:reflection-remapper:0.1.2\")\n\u003e }\n\u003e ```\n\u003e \u003c/details\u003e\n\n### Gradle Groovy DSL\n\u003e \u003cdetails open\u003e\n\u003e \u003csummary\u003eClick to show build.gradle\u003c/summary\u003e\n\u003e \n\u003e ```groovy\n\u003e repositories {\n\u003e   mavenCentral()\n\u003e }\n\u003e \n\u003e dependencies {\n\u003e   implementation 'xyz.jpenilla:reflection-remapper:0.1.2'\n\u003e }\n\u003e ```\n\u003e \u003c/details\u003e\n\n## Using reflection-remapper\n\n*Note: The following is a basic introduction; For further details, consult the reflection-remapper Javadocs.*\n\n### `ReflectionRemapper`\n`ReflectionRemapper` is the interface provided by reflection-remapper for remapping class, method, and field names for reflection lookups.\n\n\u003e \u003cdetails open\u003e\n\u003e \u003csummary\u003eClick to see Java code snippet\u003c/summary\u003e\n\u003e \n\u003e ```java\n\u003e final Path mappingsFile = /* get path to mappings ... */;\n\u003e // ReflectionRemapper provides various static factory methods, in this example we use the one from a Path\n\u003e // Note that the standard ReflectionRemapper implementations store their mappings in memory, which can be multiple megabytes large in some cases.\n\u003e // This means it's best to use the remapper when your program starts and then dispose of any reference to it, so it can be garbage collected.\n\u003e final ReflectionRemapper reflectionRemapper = ReflectionRemapper.forMappings(mappingsFile, \"fromNamespace\", \"toNamespace\");\n\u003e\n\u003e final String runtimeName = reflectionRemapper.remapClassName(\"net.minecraft.server.level.ServerPlayer\");\n\u003e final Class\u003c?\u003e serverPlayerClass = Class.forName(runtimeName); // Exception handling omitted for brevity\n\u003e final String runtimeFieldName = reflectionRemapper.remapFieldName(serverPlayerClass, \"seenCredits\");\n\u003e // ...\n\u003e ```\n\u003e \u003c/details\u003e\n\n### Reflection Proxies\n\nA reflection proxy is a runtime generated implementation of a \"reflection proxy interface\", which uses cached `MethodHandle`s to invoke the targets specified by\nthe interface definition. Reflection proxies can also make use of a `ReflectionRemapper` on creation in order to allow them to work in a remapped (or not) environment.\nThe `ReflectionRemapper` on its own, while powerful, tends to make already verbose reflection code even more verbose. When combined with reflection proxies, we\ncan have relatively clean reflection code while still properly remapping.\n\n\u003e \u003cdetails open\u003e\n\u003e \u003csummary\u003eClick to see Java code snippet\u003c/summary\u003e\n\u003e \n\u003e #### Example target class\n\u003e ```java\n\u003e public final class ServerLevel {\n\u003e   private SleepStatus sleepStatus;\n\u003e\n\u003e   private BlockPos findLightningTargetAround(BlockPos pos) {\n\u003e     // implementation\n\u003e   }\n\u003e }\n\u003e ```\n\u003e\n\u003e #### Example reflection proxy interface\n\u003e ```java\n\u003e @Proxies(ServerLevel.class) // Can use Class or fully qualified class name (for inaccessible classes)\n\u003e private interface ServerLevelProxy {\n\u003e   BlockPos findLightningTargetAround(ServerLevel instance, BlockPos pos);\n\u003e\n\u003e   @FieldSetter(\"sleepStatus\")\n\u003e   void setSleepStatus(ServerLevel instance, SleepStatus value);\n\u003e }\n\u003e ```\n\u003e\n\u003e #### Creating and using reflection proxy instance\n\u003e ```java\n\u003e final ReflectionRemapper reflectionRemapper = /* get ReflectionRemapper ... */;\n\u003e final ClassLoader classLoader = /* get ClassLoader for loading proxy implementations, generally it needs to be able to see any reflection proxy interfaces you want to implement */;\n\u003e final ReflectionProxyFactory reflectionProxyFactory = ReflectionProxyFactory.create(reflectionRemapper, classLoader); // ReflectionProxyFactory holds a ref to it's ReflectionRemapper\n\u003e\n\u003e // Generated proxy instances do not hold a ref to the ReflectionRemapper, and are fine to keep around.\n\u003e final ServerLevelProxy proxyInstance = reflectionProxyFactory.reflectionProxy(ServerLevelProxy.class);\n\u003e\n\u003e // ...\n\u003e \n\u003e final ServerLevel level = /* ... */;\n\u003e final BlockPos blockPos = /* ... */;\n\u003e final BlockPos target = proxyInstance.findLightningTargetAround(level, blockPos);\n\u003e proxyInstance.setSleepStatus(level, new SleepStatus());\n\u003e ```\n\u003e \u003c/details\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpenilla%2Freflection-remapper","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjpenilla%2Freflection-remapper","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjpenilla%2Freflection-remapper/lists"}