{"id":37029857,"url":"https://github.com/oak/jsonrpc4j","last_synced_at":"2026-01-14T03:36:44.563Z","repository":{"id":57734337,"uuid":"446615847","full_name":"oak/jsonrpc4j","owner":"oak","description":"JSON-RPC for Java","archived":false,"fork":true,"pushed_at":"2022-01-21T20:56:47.000Z","size":1418,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2023-12-20T09:07:51.627Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"briandilley/jsonrpc4j","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oak.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}},"created_at":"2022-01-10T23:36:51.000Z","updated_at":"2022-01-11T09:45:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/oak/jsonrpc4j","commit_stats":null,"previous_names":[],"tags_count":19,"template":null,"template_full_name":null,"purl":"pkg:github/oak/jsonrpc4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oak%2Fjsonrpc4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oak%2Fjsonrpc4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oak%2Fjsonrpc4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oak%2Fjsonrpc4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oak","download_url":"https://codeload.github.com/oak/jsonrpc4j/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oak%2Fjsonrpc4j/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"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":[],"created_at":"2026-01-14T03:36:43.924Z","updated_at":"2026-01-14T03:36:44.546Z","avatar_url":"https://github.com/oak.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSON-RPC for Java\n\nThis project aims to provide the facility to easily implement\nJSON-RPC for the java programming language.  jsonrpc4j uses the\n[Jackson][Jackson page] library to convert java\nobjects to and from json objects (and other things related to\nJSON-RPC).\n\n[![Javadoc](https://img.shields.io/badge/javadoc-OK-blue.svg)](http://briandilley.github.io/jsonrpc4j/javadoc/1.5.0/)\n[![Download](https://img.shields.io/maven-central/v/com.github.briandilley.jsonrpc4j/jsonrpc4j.svg) ](https://repo1.maven.org/maven2/com/github/briandilley/jsonrpc4j/jsonrpc4j/1.5.3/)\n[![Travis CI](https://travis-ci.org/gaborbernat/jsonrpc4j.svg?branch=master)](https://travis-ci.org/gaborbernat/jsonrpc4j)\n[![GitHub commits](https://img.shields.io/github/commits-since/briandilley/jsonrpc4j/1.5.3.svg)](https://github.com/briandilley/jsonrpc4j/compare/1.5.3...master)\n\n## Features Include:\n  * Streaming server (`InputStream` \\ `OutputStream`)\n  * HTTP Server (`HttpServletRequest` \\ `HttpServletResponse`)\n  * Portlet Server (`ResourceRequest` \\ `ResourceResponse`)\n  * Socket Server (`StreamServer`)\n  * Integration with the Spring Framework (`RemoteExporter`)\n  * Streaming client\n  * HTTP client\n  * Dynamic client proxies\n  * Annotations support\n  * Custom error resolving\n  * Composite services\n\n## Maven\nThis project is built with [Maven][Maven page]. Be\nsure to check the pom.xml for the dependencies if you're not using\nmaven.  If you're already using spring you should have most (if not all)\nof the dependencies already - outside of maybe the\n[Jackson Library][Jackson page].  Jsonrpc4j is available\nfrom the maven central repo. Add the following to your pom.xml if you're\nusing maven:\n\n\nIn `\u003cdependencies\u003e`:\n\n```xml\n\t\u003c!-- jsonrpc4j --\u003e\n\t\u003cdependency\u003e\n\t\t\u003cgroupId\u003ecom.github.briandilley.jsonrpc4j\u003c/groupId\u003e\n\t\t\u003cartifactId\u003ejsonrpc4j\u003c/artifactId\u003e\n\t\t\u003cversion\u003e1.6\u003c/version\u003e\n\t\u003c/dependency\u003e\n```\n\nor with gradle:\n\n```groovy\n    implementation('com.github.briandilley.jsonrpc4j:jsonrpc4j:1.6')\n```\n\nIf you want to just download the projects output JAR and it's dependencies you can\ndo it over at the [Maven repository][Maven repository].\n\n## JSON-RPC specification\nThe official source for the [JSON-RPC 2.0 specification][JSON RPC Spec].\nThe guys over at [json-rpc google group][Google Group]\nseem to be fairly active, so you can ask clarifying questions there.\n\n## Streaming server and client\nJsonrpc4j comes with a streaming server and client to support applications of all types\n(not just HTTP).  The `JsonRpcClient` and `JsonRpcServer` have simple methods\nthat take `InputStream`s and `OutputStream`s.  Also in the library is a `JsonRpcHttpClient`\nwhich extends the `JsonRpcClient` to add HTTP support.\n\n## Spring Framework\njsonrpc4j provides a `RemoteExporter` to expose java services as JSON-RPC over HTTP without\nrequiring any additional work on the part of the programmer.  The following example explains\nhow to use the `JsonServiceExporter` within the Spring Framework.\n\nCreate your service interface:\n\n```java\npackage com.mycompany;\npublic interface UserService {\n    User createUser(String userName, String firstName, String password);\n    User createUser(String userName, String password);\n    User findUserByUserName(String userName);\n    int getUserCount();\n}\n```\n\nImplement it:\n\n```java\npackage com.mycompany;\npublic class UserServiceImpl\n    implements UserService {\n\n    public User createUser(String userName, String firstName, String password) {\n        User user = new User();\n        user.setUserName(userName);\n        user.setFirstName(firstName);\n        user.setPassword(password);\n        database.saveUser(user);\n        return user;\n    }\n\n    public User createUser(String userName, String password) {\n        return this.createUser(userName, null, password);\n    }\n\n    public User findUserByUserName(String userName) {\n        return database.findUserByUserName(userName);\n    }\n\n    public int getUserCount() {\n        return database.getUserCount();\n    }\n\n}\n```\n\nConfigure your service in spring as you would any other RemoteExporter:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cbeans xmlns=\"http://www.springframework.org/schema/beans\"\n\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\txsi:schemaLocation=\"http://www.springframework.org/schema/beans\n\t\thttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd\"\u003e\n\n    \u003cbean class=\"org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping\"/\u003e\n\n    \u003cbean id=\"userService\" class=\"com.mycompany.UserServiceImpl\"\u003e\n    \u003c/bean\u003e\n\n    \u003cbean name=\"/UserService.json\" class=\"com.googlecode.jsonrpc4j.spring.JsonServiceExporter\"\u003e\n        \u003cproperty name=\"service\" ref=\"userService\"/\u003e\n        \u003cproperty name=\"serviceInterface\" value=\"com.mycompany.UserService\"/\u003e\n    \u003c/bean\u003e\n\n\u003c/beans\u003e\n```\n\nYour service is now available at the URL /UserService.json.  Type conversion of\nJSON-\u003eJava and Java-\u003eJSON will happen for you automatically.  This service can\nbe accessed by any JSON-RPC capable client, including the `JsonProxyFactoryBean`,\n`JsonRpcClient` and `JsonRpcHttpClient` provided by this project:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cbeans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\"\u003e\n\n    \u003cbean  class=\"com.googlecode.jsonrpc4j.spring.JsonProxyFactoryBean\"\u003e\n        \u003cproperty name=\"serviceUrl\" value=\"http://example.com/UserService.json\"/\u003e\n        \u003cproperty name=\"serviceInterface\" value=\"com.mycompany.UserService\"/\u003e\n    \u003c/bean\u003e\n\n\u003cbeans\u003e\n```\n\nIn the case that your JSON-RPC requires named based parameters rather than indexed\nparameters an annotation can be added to your service interface (this also works on\nthe service implementation for the ServiceExporter):\n\n```java\npackage com.mycompany;\npublic interface UserService {\n    User createUser(@JsonRpcParam(value=\"theUserName\") String userName, @JsonRpcParam(value=\"thePassword\") String password);\n}\n```\n\nBy default all error message responses contain the the message as returned by\nException.getmessage() with a code of 0.  This is not always desirable.\njsonrpc4j supports annotated based customization of these error messages and\ncodes, for example:\n\n```java\npackage com.mycompany;\npublic interface UserService {\n    @JsonRpcErrors({\n        @JsonRpcError(exception=UserExistsException.class,\n            code=-5678, message=\"User already exists\", data=\"The Data\"),\n        @JsonRpcError(exception=Throwable.class,code=-187)\n    })\n    User createUser(@JsonRpcParam(value=\"theUserName\") String userName, @JsonRpcParam(value=\"thePassword\") String password);\n}\n```\n\nThe previous example will return the error code `-5678` with the message\n`User already exists` if the service throws a UserExistsException.  In the\ncase of any other exception the code `-187` is returned with the value\nof `getMessage()` as returned by the exception itself.\n\n### Auto Discovery With Annotations\n\nSpring can also be configured to auto-discover services and clients with annotations.\n\nTo configure auto-discovery of annotated services first annotate the service interface:\n\n```java\n@JsonRpcService(\"/path/to/MyService\")\ninterface MyService {\n... service methods ...\n}\n```\n\nNext annotate the implementation of the service interface;\n\n```java\n@AutoJsonRpcServiceImpl\nclass MyServiceImpl {\n... service methods' implementations ...\n}\n```\n\nand use the following configuration to allow spring to find the implementation that you would like to expose:\n\n```xml\n\u003cbeans xmlns=\"http://www.springframework.org/schema/beans\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\"\u003e\n\n  \u003cbean class=\"com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter\"/\u003e\n\n  \u003cbean class=\"com.mycompany.MyServiceImpl\" /\u003e\n\n\u003c/beans\u003e\n```\n\nConfiguring a client is just as easy:\n\n```xml\n\u003cbeans xmlns=\"http://www.springframework.org/schema/beans\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd\"\u003e\n\n  \u003cbean class=\"com.googlecode.jsonrpc4j.spring.AutoJsonRpcClientProxyCreator\"\u003e\n    \u003cproperty name=\"baseUrl\" value=\"http://hostname/api/\" /\u003e\n    \u003cproperty name=\"scanPackage\" value=\"com.mycompany.services\" /\u003e\n  \u003c/bean\u003e\n\n\u003c/beans\u003e\n```\n\nWhere the `baseUrl` is added to the front of the path value provided by the\n`JsonRpcService` annotation and `scanPackage` tells spring which packages\nto scan for services.\n\n## Without the Spring Framework\njsonrpc4j can be used without the spring framework as well.  In fact, the client\nand server both work in an Android environment.\n\n### Client\nHere's an example of how to use the client to communicate with the JSON-RPC service described above:\n\n```java\nJsonRpcHttpClient client = new JsonRpcHttpClient(\n    new URL(\"http://example.com/UserService.json\"));\n\nUser user = client.invoke(\"createUser\", new Object[] { \"bob\", \"the builder\" }, User.class);\n```\n\nOr, the ProxyUtil class can be used in conjunction with the interface to create a dynamic proxy:\n\n```java\nJsonRpcHttpClient client = new JsonRpcHttpClient(\n    new URL(\"http://example.com/UserService.json\"));\n\nUserService userService = ProxyUtil.createClientProxy(\n    getClass().getClassLoader(),\n    UserService.class,\n    client);\n\nUser user = userService.createUser(\"bob\", \"the builder\");\n```\n\n### server\nThe server can be used without spring as well:\n\n```java\n// create it\nJsonRpcServer server = new JsonRpcServer(userService, UserService.class);\n```\n\nAfter having created the server it's simply a matter of calling one of the\n`handle(...)` methods available.  For example, here's a servlet using the\nvery same `UserService`:\n\n```java\nclass UserServiceServlet\n    extends HttpServlet {\n\n    private UserService userService;\n    private JsonRpcServer jsonRpcServer;\n\n    protected void doPost(HttpServletRequest req, HttpServletResponse resp) {\n        jsonRpcServer.handle(req, resp);\n    }\n\n    public void init(ServletConfig config) {\n        //this.userService = ...\n        this.jsonRpcServer = new JsonRpcServer(this.userService, UserService.class);\n    }\n\n}\n```\n\n### Composite Services\nMultiple services can be combined into a single server using one of the\n`ProxyUtil::createCompositeService(...)` methods.  For example:\n\n```java\nUserverService userService = ...;\nContentService contentService = ...;\nBlackJackService blackJackService = ...;\n\nObject compositeService = ProxyUtil.createCompositeServiceProxy(\n    this.getClass().getClassLoader(),\n    new Object[] { userService, contentService, blackJackService},\n    new Class\u003c?\u003e[] { UserService.class, ContentService.class, BlackJackService.class},\n    true);\n\n// now compositeService can be used as any of the above service, ie:\nUser user = ((UserverService)compositService).createUser(...);\nContent content =  ((ContentService)compositService).getContent(...);\nHand hand = ((BlackJackService)compositService).dealHand(...);\n\n```\n\nThis can be used in conjunction with the `JsonRpcServer` to expose the service\nmethods from all services at a single location:\n\n```java\nJsonRpcServer jsonRpcServer = new JsonRpcServer(compositeService);\n```\n\nA spring service exporter exists for creating composite services as well\nnamed `CompositeJsonServiceExporter`.\n\n### Streaming (Socket) Server\nA streaming server that uses `Socket`s is available in the form of the\n`StreamServer` class.  It's use is very straightforward:\n\n```java\n// create the jsonRpcServer\nJsonRpcServer jsonRpcServer = new JsonRpcServer(...);\n\n// create the stream server\nint maxThreads = 50;\nint port = 1420;\nInetAddress bindAddress = InetAddress.getByName(\"...\");\nStreamServer streamServer = new StreamServer(\n    jsonRpcServer, maxThreads, port, bindAddress);\n\n// start it, this method doesn't block\nstreamServer.start();\n```\n\nand when you're ready to shut the server down:\n\n```java\n// stop it, this method blocks until\n// shutdown is complete\nstreamServer.stop();\n```\n\nOf course, this is all possible in the Spring Framework as well:\n\n```xml\n    \u003cbean id=\"streamingCompositeService\" class=\"com.googlecode.jsonrpc4j.spring.CompositeJsonStreamServiceExporter\"\u003e\n        \u003c!-- can be an IP, hostname or omitted to listen on all available devices --\u003e\n        \u003cproperty name=\"hostName\" value=\"localhost\"/\u003e\n        \u003cproperty name=\"port\" value=\"6420\"/\u003e\n        \u003cproperty name=\"services\"\u003e\n        \t\u003clist\u003e\n\t        \t\u003cref bean=\"userService\" \t/\u003e\n\t        \t\u003cref bean=\"contentService\" \t/\u003e\n\t        \t\u003cref bean=\"blackJackService\" \t/\u003e\n        \t\u003c/list\u003e\n        \u003c/property\u003e\n    \u003c/bean\u003e\n```\n\t}\n\n\n### `JsonRpcServer` settings explained\nThe following settings apply to both the `JsonRpcServer` and `JsonServiceExporter`:\n\n  * `allowLessParams` - Boolean specifying whether or not the server should allow for methods to be invoked by clients supplying less than the required number of parameters to the method.\n  * `allowExtraParams` - Boolean specifying whether or not the server should allow for methods to be invoked by clients supplying more than the required number of parameters to the method.\n  * `rethrowExceptions` - Boolean specifying whether or not the server should re-throw exceptions after sending them back to the client.\n  * `backwardsComaptible` - Boolean specifying whether or not the server should allow for jsonrpc 1.0 calls.  This only includes the omission of the jsonrpc property of the request object, it will not enable class hinting.\n  * `errorResolver` - An implementation of the `ErrorResolver` interface that resolves exception thrown by services into meaningful responses to be sent to clients.  Multiple `ErrorResolver`s can be configured using the `MultipleErrorResolver` implementation of this interface.\n  * `batchExecutorService` - A configured `ExecutorService` to use for parallel JSON-RPC batch processing. By default batch requests are handled sequentially.\n\n### Server Method resolution\nMethods are resolved in the following way, each step immediately short circuits the\nprocess when the available methods is 1 or less.\n\n  1. If a method has the @JsonRpcMethod annotation, then if the annotation value has the same name as the request method, it is considered.  If the annotation has `required` set to `true`, then the Java method name is not considered.\n  2. Otherwise, all methods with the same name as the request method are considered.\n  3. If `allowLessParams` is disabled methods with more parameters than the request are removed\n  4. If `allowExtraParams` is disabled then methods with less parameters than the request are removed\n  5. If either of the two parameters above are enabled then methods with the lowest difference in parameter count from the request are kept\n  6. Parameters types are compared to the request parameters and the method(s) with the highest number of matching parameters is kept\n  7. If there are multiple methods remaining then the first of them are used\n\njsonrpc4j's method resolution allows for overloaded methods _sometimes_.  Primitives are\neasily resolved from json to java.  But resolution between other objects are not possible.\n\n\nFor example, the following overloaded methods will work just fine:\n\njson request:\n\n```json\n{\"jsonrpc\":\"2.0\", \"id\":\"10\", \"method\":\"aMethod\", \"params\":[\"Test\"]}\n```\n\njava methods:\n\n```java\npublic void aMethod(String param1);\npublic void aMethod(String param1, String param2);\npublic void aMethod(String param1, String param2, int param3);\n```\n\nBut the following will not:\n\njson request:\n\n```json\n{\"jsonrpc\":\"2.0\", \"id\":\"10\", \"method\":\"addFriend\", \"params\":[{\"username\":\"example\", \"firstName\":\"John\"}]}\n```\n\njava methods:\n\n```java\npublic void addFriend(UserObject userObject);\npublic void addFriend(UserObjectEx userObjectEx);\n```\n\nThe reason being that there is no efficient way for the server to\ndetermine the difference in the json between the `UserObject`\nand `UserObjectEx` Plain Old Java Objects.\n\n#### Custom method names\n\nIn some instances, you may need to expose a JsonRpc method that is not a valid Java method name.\nIn this case, use the annotation @JsonRpcMethod on the service method.  You may also use this annotation\nto disambiguate overloaded methods by setting the `required` property on the annotation to `true`.\n\n```java\n@JsonRpcService(\"/jsonrpc\")\npublic interface LibraryService {\n    @JsonRpcMethod(\"VideoLibrary.GetTVShows\")\n    List\u003cTVShow\u003e fetchTVShows(@JsonRpcParam(value=\"properties\") final List\u003cString\u003e properties);\n}\n```\n\n```json\n{\"jsonrpc\":\"2.0\", \"method\": \"VideoLibrary.GetTVShows\", \"params\": { \"properties\": [\"title\"] }, \"id\":1}\n```\n#### Fixed parameters\n\nYou may need to pass some fixed parameters to a JsonRpc method. In this case, use the annotation @JsonRpcFixedParam on the service method.  You may also use @JsonRpcFixedParams to pass a collection of fixed parameters.\n\n```java\n@JsonRpcService(\"/jsonrpc\")\npublic interface LibraryService {\n    @JsonRpcMethod(\"VideoLibrary.GetTVShows\")\n    @JsonRpcFixedParam(name = \"status\", value = \"published\")\n    List\u003cTVShow\u003e fetchTVShows(@JsonRpcParam(value=\"properties\") final List\u003cString\u003e properties);\n}\n```\n\n```json\n{\n    \"jsonrpc\":\"2.0\", \n    \"method\": \"VideoLibrary.GetTVShows\", \n    \"params\": { \n        \"status\": \"published\", \n        \"properties\": [\"title\"] \n    }, \n    \"id\":1\n}\n```\n\n```java\n@JsonRpcService(\"/jsonrpc\")\npublic interface LibraryService {\n    @JsonRpcMethod(\"VideoLibrary.GetTVShows\")\n    @JsonRpcFixedParams(fixedParams = { \n        @JsonRpcFixedParam(name = \"status\", value = \"published\"), \n        @JsonRpcFixedParam(name = \"order_by\", value = \"recent\") })\n    List\u003cTVShow\u003e fetchTVShows(@JsonRpcParam(value=\"properties\") final List\u003cString\u003e properties);\n}\n```\n\n```json\n{\n    \"jsonrpc\":\"2.0\", \n    \"method\": \"VideoLibrary.GetTVShows\", \n    \"params\": { \n        \"status\": \"published\", \n        \"order_by\": \"recent\", \n        \"properties\": [\"title\"] \n    }, \n    \"id\":1\n}\n```\n\n[Google Group]: http://groups.google.com/group/json-rpc\n[Jackson page]: https://github.com/FasterXML/jackson\n[JSON RPC Spec]: http://www.jsonrpc.org/specification\n[Maven page]: http://maven.apache.org\n[Maven repository]: http://mvnrepository.com/artifact/com.github.briandilley.jsonrpc4j/jsonrpc4j\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foak%2Fjsonrpc4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foak%2Fjsonrpc4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foak%2Fjsonrpc4j/lists"}