{"id":16375002,"url":"https://github.com/moderocky/librarian","last_synced_at":"2025-08-25T12:02:57.776Z","repository":{"id":103957271,"uuid":"375405174","full_name":"Moderocky/Librarian","owner":"Moderocky","description":"An internal dependency/library manager designed to provide access to services and libraries.","archived":false,"fork":false,"pushed_at":"2021-06-10T11:04:03.000Z","size":16,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-26T04:27:04.929Z","etag":null,"topics":["bytecode-compiler","dependency","java","library","reflection"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Moderocky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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-06-09T15:33:11.000Z","updated_at":"2023-05-29T07:37:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"7322033d-54ad-44be-80b2-83a31aab4122","html_url":"https://github.com/Moderocky/Librarian","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Moderocky/Librarian","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FLibrarian","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FLibrarian/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FLibrarian/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FLibrarian/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Moderocky","download_url":"https://codeload.github.com/Moderocky/Librarian/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FLibrarian/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270690057,"owners_count":24628795,"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","status":"online","status_checked_at":"2025-08-16T02:00:11.002Z","response_time":91,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["bytecode-compiler","dependency","java","library","reflection"],"created_at":"2024-10-11T03:19:04.967Z","updated_at":"2025-08-16T09:08:25.167Z","avatar_url":"https://github.com/Moderocky.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Librarian\n=====\n\n### Opus #6\n\nAn innovative system for managing and accessing services or resources without requiring them as dependencies, or from external Java applications.\n\nLibrarian is designed for easily distributing and accessing implementations of standard library interfaces (similar to Java's Service Provider Interface) but with the added bonus of also allowing easy \"blind\" access to resources of which the type is not known at compile-time.\n\nThis could, for example, allow extensible systems (such as game-servers) to utilise alternative implementations of particular features provided by third-party modules, plugins or other modifications without needing to know anything about them.\n\nLibrarian differs from other simple interface providers in that it offers a new option: to use a resource about which *nothing* is known.\n\nThis is helpful in cases where resources are somewhat standardised in form but do not use any sort of widely-recognised template or interface. An example scenario is detailed below.\n\n\u003e **Example:**\n\u003e A 'vehicles' mod for a game would like to add functionality for users to buy and sell cars, but has no access to any 'economy' module.\n\u003e\n\u003e The game may have an 'economy' module installed as well, but as it is a third-party module, we have no way of knowing anything about it. Perhaps there are multiple different third-party 'economy' modules available, and the user could have installed any of them.\n\u003e \n\u003e While we don't know the exact structure, we can assume 'economy' will provide certain things:\n\u003e a `getBalance(Player)` method and a `setBalance(Player)` method.\n\u003e \n\nIn the above example, we can use Librarian to query those resources.\n```java \ninterface Economy {\n    double getBalance(Player player);\n    void setBalance(Player player, double balance);\n}\n\nfinal Economy economy = library.lookFor(Economy.class);\neconomy.setBalance(player, 66);\nassert economy.getBalance(player) == 66;\n```\n\n**Note:** we are using an interface that *we* have provided, and Librarian is populating it for us.\n\nLibrarian binds our interface methods to the methods from the resources using a relatively efficient proxy system.\n`Method call -\u003e Proxy -\u003e Original method`\n\nThis allows Librarian to provide a very simple and easy-to-use way to call the methods, rather than having the user do reflection, casting or some sort of stringified method lookup.\n\nAs the methods in the proxy are resolved, prepared and cached ahead of time, using the proxy is relatively efficient.\n\n### Maven Information\n\n```xml\n\n\u003crepository\u003e\n    \u003cid\u003epan-repo\u003c/id\u003e\n    \u003cname\u003ePandaemonium Repository\u003c/name\u003e\n    \u003curl\u003ehttps://gitlab.com/api/v4/projects/18568066/packages/maven\u003c/url\u003e\n\u003c/repository\u003e\n``` \n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003emx.kenzie\u003c/groupId\u003e\n    \u003cartifactId\u003elibrarian\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n    \u003cscope\u003ecompile\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n### Remote Libraries\n\nLibrarian has basic support for acquiring libraries from and distributing to other JVMs and Java applications on external machines. This makes use of [Cobweb](https://github.com/Moderocky/Cobweb) to do so (and is required as a dependency to use this feature.)\n\nRemote libraries are significantly more limited (by marshalling constraints, etc.) but can still be used to great effect in many situations.\n\nThe Resource object itself must be a Remote object able to be marshalled, so that it can be distributed/accessed via RMI.\n\nThe dependency information for Cobweb is below.\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003emx.kenzie\u003c/groupId\u003e\n    \u003cartifactId\u003ecobweb\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.1\u003c/version\u003e\n    \u003cscope\u003ecompile\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n### Compiled Library Endpoints\n\nIn some scenarios, the added overhead of using reflection proxies may be too great, especially for libraries which require a lot of repeat calls and would benefit from Hotspot's native JIT optimisations.\n\nLibrarian contains the `CompiledEndpointLibrary` implementation, an extension of the simple library, which aims to solve this issue.\n\nAs the name suggests, this advanced library generates and compiles an endpoint implementation at runtime to Java bytecode, which means the library methods require no reflection to run and gain all the standard JIT optimisations.\n\n#### Benefits\n - Significantly faster than proxy endpoints.\n - Able to undergo JIT optimisation.\n - No reflection or proxies required for use.\n - Able to re-use existing endpoints in some scenarios.\n\n#### Caveats\n - Unable to use local or private interfaces/methods.\n - Requires creation of a new class for each unique endpoint.\n - Classes and loader are kept in memory if user stores references.\n\n\nThe dependencies for the necessary ASM version are below.\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.ow2.asm\u003c/groupId\u003e\n    \u003cartifactId\u003easm\u003c/artifactId\u003e\n    \u003cversion\u003e9.1\u003c/version\u003e\n    \u003cscope\u003ecompile\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.ow2.asm\u003c/groupId\u003e\n    \u003cartifactId\u003easm-commons\u003c/artifactId\u003e\n    \u003cversion\u003e9.1\u003c/version\u003e\n    \u003cscope\u003ecompile\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n### Examples\n\nRegistering and requesting a simple resource by known class.\n\n```java \nfinal Library\u003cObject\u003e library = new SimpleLibrary();\nclass Alice { // An example class\n    public int a() { return 1; }\n    public int b() { return 2; }\n}\nassert library.register(new Alice());\nfinal Alice alice = library.getResource(Alice.class); // Any supertype of Alice.class would be acceptable here.\nassert alice != null;\nassert alice.a() == 1;\nassert alice.b() == 2;\n```\n\nRegistering a resource, and requesting it using `lookFor` query.\n\n```java \nfinal Library\u003cObject\u003e library = new SimpleLibrary();\nclass Alice { // An example class\n    public int a() { return 1; }\n    public int b() { return 2; }\n}\nassert library.register(new Alice());\ninterface Bob { // This is the template we try to match\n    int a();\n    int b();\n}\nfinal Bob bob = library.lookFor(Bob.class); // Populate our template with methods from the resources\nassert bob != null;\nassert bob.a() == 1; // These are called on our \"alice\" object we registered\nassert bob.b() == 2;\n```\n\nRegistering two resources, and accessing them both using a single `lookFor` query.\n\n```java \nfinal Library\u003cObject\u003e library = new SimpleLibrary();\nclass Alice {\n    public int a() { return 1; }\n    public int b() { return 2; }\n}\nclass Jeremy {\n    public int c() { return 5; }\n    public int d() { return 6; }\n}\nassert library.register(new Alice());\nassert library.register(new Jeremy());\ninterface Bob {\n    int a();\n    int b();\n    int c();\n    int d();\n}\nfinal Bob bob = library.lookFor(Bob.class);\nassert bob != null;\nassert bob.a() == 1; // Populated from Alice\nassert bob.b() == 2; // Populated from Alice\nassert bob.c() == 5; // Populated from Jeremy\nassert bob.d() == 6; // Populated from Jeremy\n```\n\n(Remote Library)\nExporting a remote object, then accessing it using a `lookFor` query.\n\n```java \nfinal Library\u003cRemote\u003e library = new RemoteLibrary();\ninterface Jeremy extends Remote { // We need an interface for the RMI to stub\n    int a() throws RemoteException;\n    int b() throws RemoteException;\n}\nclass Bob implements Jeremy {\n    public int a() throws RemoteException { return 1; };\n    public int b() throws RemoteException { return 2; };\n}\nassert library.register(new Bob()); // This actually exports the Jeremy interface\ninterface Alice {\n    int a();\n    int b();\n}\nfinal Alice alice = library.lookFor(Alice.class); // We lookup the Jeremy interface\nassert alice != null;\nassert alice.a() == 1;\nassert alice.b() == 2;\n```\n\n(Compiled Library)\nCreating and re-using a compiled endpoint.\n```java \nfinal Library\u003cObject\u003e library = new CompiledEndpointLibrary();\nassert library.register(new Alice());\nfinal Bob bob = library.lookFor(Bob.class); // Endpoint is compiled here\nassert bob != null;\nassert bob.a() == 1;\nassert bob.b() == 2;\nfinal Bob two = library.lookFor(Bob.class);\nassert bob.getClass() == two.getClass(); // Will re-use the compiled class\n\npublic interface Bob {\n        int a();\n        \n        int b();\n        \n        int c(); // Will throw error if used - no implementation\n        \n        int d(); // Will throw error if used - no implementation\n    }\n    \npublic static class Alice {\n    public int a() {\n        return 1;\n    }\n    \n    public int b() {\n        return 2;\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoderocky%2Flibrarian","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoderocky%2Flibrarian","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoderocky%2Flibrarian/lists"}