{"id":16375024,"url":"https://github.com/moderocky/cobweb","last_synced_at":"2026-03-31T16:30:18.309Z","repository":{"id":103957162,"uuid":"332270340","full_name":"Moderocky/Cobweb","owner":"Moderocky","description":"Create a spider-web of connected Java programs. A library for easy distributed programming. Export objects for your remote Java programs to access.","archived":false,"fork":false,"pushed_at":"2021-12-16T21:45:24.000Z","size":147,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-01T04:15:16.722Z","etag":null,"topics":["api","java","rmi"],"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":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-23T17:39:12.000Z","updated_at":"2023-09-03T06:59:38.000Z","dependencies_parsed_at":null,"dependency_job_id":"4256254d-6172-40bf-a385-5023a7c73d98","html_url":"https://github.com/Moderocky/Cobweb","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FCobweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FCobweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FCobweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Moderocky%2FCobweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Moderocky","download_url":"https://codeload.github.com/Moderocky/Cobweb/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239954709,"owners_count":19724289,"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":["api","java","rmi"],"created_at":"2024-10-11T03:19:12.794Z","updated_at":"2026-03-31T16:30:18.259Z","avatar_url":"https://github.com/Moderocky.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"Cobweb\n=====\n\n### Opus #2\n\nA library for extremely simple distributed programming.\n\nAccess methods and objects from completely separate Java processes running in an external JVM, even on an entirely\ndifferent physical machine.\n\nCobweb is designed to easily connect parts of a distributed Java program together, in one big spider-web.\n\nThis is built on the work of the Remote Method Interface, a little-known Java 1 API for making remote procedure calls. I\nmust give particular credit to `DOI: 10.1109/40.591654`, the research paper that inspired me to make this.\n\nAs the RMI is such an ignored feature, Cobweb exists to make it more easily accessible and useful, using helper methods,\ngenerics and other, newer features of Java.\n\nFeatures:\n\n* Export objects to be accessed by external JVMs.\n* Call methods directly from another Java process.\n* Automatic retrieval and management of local registries.\n\nSample Intentions:\n\n* Create fully integrated remote backends without needing to touch sockets or transfer protocol.\n* Export APIs locally that can be accessed without dependencies.\n* Export global attachment points that your other programs can link to.\n* Transfer data easily without manual serialisation or connections.\n* Easily link client processes with a centralised backend.\n* Sequester parts of a program to prevent cascade failures.\n* Split up a program to spread the resource cost over multiple machines.\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\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### Examples\n\n#### Simple instance access\n\nCreate a remote interface. (Goes on remote and origin.)\n\n```java\nprivate interface Alice extends Remote {\n\n}\n```\n\nCreate an implementation. (Goes on origin only.)\n\n```java\nprivate static class Bob implements Alice {\n\n}\n```\n\nExport an instance of the implementation from the origin.\n\n```java \nfinal Alice stub = registry.export(\"bob\", new Bob());\n```\n\nImport the instance by proxy on the remote.\n\n```java \nfinal Alice stub = registry.retrieve(\"bob\");\n```\n\n#### Calling remote code\n\nWith the following class structure:\n\n```java\ninterface Alice extends Remote { // Proxy interface\n    \n    int intMethod()\n        throws RemoteException; // Important for passing errors properly\n    \n    Class\u003c?\u003e complexMethod(final String string) // Non-primitive classes may be passed\n        throws RemoteException; // All methods must throw RemoteException\n\n}\n\nclass Bob implements Alice { // Origin instance class\n    \n    @Override\n    public int intMethod() {\n        return 62; // return primitives\n    }\n    \n    @Override\n    public Class\u003c?\u003e complexMethod(final String string) { // pass params\n        assert string != null; // you can throw errors here :)\n        return string.getClass(); // return complex types\n    }\n}\n```\n\nYou can export your instance from the origin as so:\n\n```java \nfinal Registry registry = Registry.acquireLocal();\nassert registry != null;\nassert registry.export(\"bob\", new Bob()) != null;\n```\n\n...and then acquire it remotely with:\n\n```java \nfinal Alice stub = registry.retrieve(\"bob\");\nassert stub.intMethod() == 62;\nClass\u003c?\u003e cls = stub.complexMethod(\"hello\");\nassert cls == String.class;\n```\n\nRemember that in most cases, the parameters are transmitted to origin, and the method code is executed on origin, with\nthe result transmitted back to remote.\n\n### Explanation\n\nWhile it would take a full forty pages to explain distributed computing in Java, and I am not qualified to do so, I do\nprovide a brief insight into how Cobweb and the RMI work.\n\nRemote method invocation relies on a \"registry\" system that is partly separate from Java's ordinary processes. It is\nbuilt from a system of socket servers and receivers, which can be used to transmit data internally or externally.\n\nWhen objects are exported and retrieved by remote JVMs, they are 'marshalled' (serialised) and their structure is\ntransmitted in two parts:\na skeleton class, and a stub class. A `_Skel` and `_Stub` class are generated at runtime as proxy accessors for the\ninstance.\n\nWhen a method is called on the remote, it marshals the parameters and transmits them back to the origin to run the\nactual method, and then returns the result in the same way.\n\nAs an approach, this has some weaknesses. To begin with, large amounts of data may need to be sent for heavily wrapped\nparameters, and a lot of skeleton classes might be recursively generated in order to preserve behaviour. While this\nmeans you can execute a remote method as you would any other, it also means the JVM is doing more work than necessary.\n\nFrom reading the original creator, Ann Wollrath's research, it seems that there was an intention to expand on this and\ncreate a better and more complex system.\n\nFor a better explanation, please refer to `DOI: 10.1109/40.591654`.\n\n### Intentions\n\nTwenty-five years have now passed since the RMI's creation, and there seems to be very little difference between JDK\n15's implementation and the original, from Java 1.1.\n\nI fully intend to take up the torch and see if I can expand on the original work making use of runtime-created method\naccessors, bytecode alterations and possibly even transmitting compiled code from the Graal AOT compiler, in order to\nreduce the need for transference of unnecessary or trivial data.\n\nI may also be able to analyse method behaviour and strip out unnecessary parts of transferred parameters. Using a\ncombination of Java's Unsafe and some internal tricks of the JVM, it would be entirely possible to create whittled-down\nversions of parameter objects that contain only the necessary content, and none of the unused fields.\n\nIt might also be possible to trim out any side effects, or find better, faster methods of serialising the objects.\n\nNow I am sure I cannot match the work of Sun Microsystems on this front, but I believe improvements can be made.\n\nIt is my intention for Cobweb to eventually be able to outperform the RMI on its own, rather than simply being a\nhand-holding wrapper for it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoderocky%2Fcobweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmoderocky%2Fcobweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmoderocky%2Fcobweb/lists"}