{
  "id": "quickstart",
  "title": "RedisGears JVM quick start",
  "url": "https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/deprecated-features/gears-v1/jvm/quickstart/",
  "summary": "A quick start to learn how to use RedisGears with Java.",
  "tags": [
    "docs",
    "operate",
    "stack"
  ],
  "last_updated": "2026-04-22T11:55:45+02:00",
  "page_type": "content",
  "content_hash": "47f386f26b15bc73bd1f39b618acc36f6a2aa1d3c23d1d657d9a6759d990a785",
  "sections": [
    {
      "id": "prerequisites",
      "title": "Prerequisites",
      "role": "overview",
      "text": "For this quick start, you need:\n\n- A Redis Software cluster with the [RedisGears module and JVM plugin installed](https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/deprecated-features/gears-v1/installing-redisgears#install-redisgears) and [enabled on a database](https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/deprecated-features/gears-v1/jvm/install)\n- `redis-cli` with connectivity to a Redis database"
    },
    {
      "id": "tutorial",
      "title": "Tutorial",
      "role": "content",
      "text": ""
    },
    {
      "id": "create-a-maven-project",
      "title": "Create a Maven project",
      "role": "content",
      "text": "1. Create a new [Maven project](https://maven.apache.org/guides/getting-started/index.html#).\n\n1. Add the following sections to the [pom.xml](https://maven.apache.org/guides/introduction/introduction-to-the-pom.html) file:\n\n    [code example]\n\n1. Add example code for either [batch processing](#batch-processing) or [event processing](#event-processing) to your project's `main` function."
    },
    {
      "id": "build-a-jar",
      "title": "Build a JAR",
      "role": "content",
      "text": "Use the Maven command-line tool or an IDE plugin to compile and package your code into a JAR file:\n\n[code example]"
    },
    {
      "id": "upload-the-jar",
      "title": "Upload the JAR",
      "role": "content",
      "text": "Upload your JAR file to a node in the Redis Software cluster. You will need to use the destination filepath when you run your code."
    },
    {
      "id": "run-redisgears-java-code",
      "title": "Run RedisGears Java code",
      "role": "content",
      "text": "Use the `RG.JEXECUTE` command to run your code:\n\n[code example]\n\n\nWhen you use [`GearsBuilder.run()`](https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/deprecated-features/gears-v1/jvm/classes/gearsbuilder/run), `RG.JEXECUTE` runs your code immediately.\n<br></br>\nHowever, if you use [`GearsBuilder.register()`](https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/deprecated-features/gears-v1/jvm/classes/gearsbuilder/register), `RG.JEXECUTE` only outputs an `OK` message if it registers successfully. Your registered code will run whenever certain database events occur."
    },
    {
      "id": "example-code",
      "title": "Example code",
      "role": "example",
      "text": "You can use these code examples with your own Maven project to try out batch processing or event processing with the RedisGears JVM plugin."
    },
    {
      "id": "batch-processing",
      "title": "Batch processing",
      "role": "content",
      "text": "If you use the [`GearsBuilder.run()`](https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/deprecated-features/gears-v1/jvm/classes/gearsbuilder/run) function within your code, then the functions you add to the pipeline will run exactly once when you use `RG.JEXECUTE` with your JAR file.\n\nThe following example calculates the average rating of all restaurant reviews stored in your database.\n\n#### Add data to the database\n\n1. Connect to your database with `redis-cli`:\n\n    [code example]\n\n1. Add a few review hashes to the database with the `HSET` command:\n\n    [code example]\n\n#### Example code\n\n[code example]\n\n#### Example output\n\n[code example]"
    },
    {
      "id": "event-processing",
      "title": "Event processing",
      "role": "content",
      "text": "If you use the [`GearsBuilder.register()`](https://redis.io/docs/latest/operate/oss_and_stack/stack-with-enterprise/deprecated-features/gears-v1/jvm/classes/gearsbuilder/register) function in your code, then the functions you add to the pipeline will run every time a certain database event occurs.\n\nThe following example registers a pipeline of functions to automatically update the maximum age every time you add a new person hash to your database.\n\n#### Example code\n\n[code example]\n\n#### Example event processing\n\nAfter you register your code with the `RG.JEXECUTE` command, add some data to the database and check the value of `age:maximum` to verify that it runs correctly.\n\n1. Connect to your database with `redis-cli`:\n\n    [code example]\n\n1. Add a hash that represents a person with `HSET`:\n\n    [code example]\n\n1. The current value of `age:maximum` should match Alex's age:\n\n    [code example]\n\n1. Add another person with a higher age and then check that `age:maximum` updated automatically:\n\n    [code example]\n\n1. Add a person with a lower age and verify that `age:maximum` did not change:\n\n    [code example]"
    }
  ],
  "examples": [
    {
      "id": "create-a-maven-project-ex0",
      "language": "xml",
      "code": "<repositories>\n        <repository>\n            <id>snapshots-repo</id>\n            <url>https://oss.sonatype.org/content/repositories/snapshots</url>\n        </repository>\n    </repositories>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.redislabs</groupId>\n            <artifactId>gear_runtime</artifactId>\n            <version>0.0.3-SNAPSHOT</version>\n        </dependency>\n    </dependencies>",
      "section_id": "create-a-maven-project"
    },
    {
      "id": "build-a-jar-ex0",
      "language": "sh",
      "code": "$ mvn package",
      "section_id": "build-a-jar"
    },
    {
      "id": "run-redisgears-java-code-ex0",
      "language": "sh",
      "code": "$ redis-cli -x -h {host} -p {port} RG.JEXECUTE {package.MainClass} < {filepath}/{JAR name}.jar",
      "section_id": "run-redisgears-java-code"
    },
    {
      "id": "batch-processing-ex0",
      "language": "sh",
      "code": "$ redis-cli -h <host> -p <port>",
      "section_id": "batch-processing"
    },
    {
      "id": "batch-processing-ex1",
      "language": "sh",
      "code": "127.0.0.1:12000> HSET review:1 user \"Alex L\" message \"My new favorite restaurant!\" rating 5\n    (integer) 3\n    127.0.0.1:12000> HSET review:2 user \"Anonymous user\" message \"Kind of overpriced\" rating 2\n    (integer) 3\n    127.0.0.1:12000> HSET review:3 user \"Francis J\" message \"They have a really unique menu.\" rating 4\n    (integer) 3\n    127.0.0.1:12000> exit",
      "section_id": "batch-processing"
    },
    {
      "id": "batch-processing-ex2",
      "language": "java",
      "code": "import java.io.Serializable;\nimport gears.GearsBuilder;\nimport gears.readers.KeysReader;\nimport gears.records.KeysReaderRecord;\n\npublic class Reviews implements Serializable\n{\n\n\tprivate static final long serialVersionUID = 1L;\n\tint count; // Total number of reviews\n\tint ratingsSum; // Sum of all review ratings\n\t\n    // Reviews constructor\n\tpublic Reviews(int count, int ratingsSum) {\n\t\tthis.count = count;\n\t\tthis.ratingsSum = ratingsSum;\n\t}\n\n    public static void main(String args[]) \n    {  \n        // Create the reader that will pass data to the pipe\n        KeysReader reader = new KeysReader();\n        \n        // Create the data pipe builder\n        GearsBuilder<KeysReaderRecord> gb = GearsBuilder.CreateGearsBuilder(reader);\n        \n\t\tgb.filter(r->{\n\t\t\t// Filter out any keys that are not reviews\n\t\t\treturn r.getKey().startsWith(\"review:\");\n\t\t}).map(r->{\n\t\t\t// Extract the rating field\n\t\t\treturn r.getHashVal().get(\"rating\");\n\t\t})\n\t\t.accumulate(new Reviews(0, 0), (accumulator, record)-> {\n\t\t\t// Count the reviews and add up all of their ratings\n\t\t\taccumulator.count++;\n\t\t\taccumulator.ratingsSum += Integer.parseInt(record);\n\t\t\treturn accumulator;\n\t\t}).map(r->{\n\t\t\t// Calculate the average rating\n\t\t\treturn Double.valueOf(((double) r.ratingsSum) / r.count);\n\t\t});\n             \n        // Run the data through the pipeline immediately\n        gb.run();\n    }\n}",
      "section_id": "batch-processing"
    },
    {
      "id": "batch-processing-ex3",
      "language": "sh",
      "code": "$ redis-cli -x -h {host} -p {port} \\\n    RG.JEXECUTE com.domain.packagename.Reviews < /tmp/rgjvmtest-0.0.1-SNAPSHOT.jar\n1) 1) \"3.6666666666666665\"\n2) (empty array)",
      "section_id": "batch-processing"
    },
    {
      "id": "event-processing-ex0",
      "language": "java",
      "code": "import gears.GearsBuilder;\nimport gears.readers.KeysReader;\nimport gears.records.KeysReaderRecord;\n\npublic class App \n{\n    public static void main(String args[]) \n    {  \n        // Create the reader that will pass data to the pipe\n        KeysReader reader = new KeysReader();\n        \n        // Create the data pipe builder\n        GearsBuilder<KeysReaderRecord> gb = GearsBuilder.CreateGearsBuilder(reader);\n\n        // Only process keys that start with \"person:\"\n        gb.filter(r->{\n        \treturn r.getKey().startsWith(\"person:\");\n       \t});\n\n        // Compare each person's age to the current maximum age\n        gb.foreach(r->{\n        \tString newAgeStr = r.getHashVal().get(\"age\");\n        \tint newAge = Integer.parseInt(newAgeStr);\n        \t\n        \t// Get the current maximum age\n        \tString maxAgeKey = \"age:maximum\";\n        \tString maxAgeStr = (String) GearsBuilder.execute(\"GET\", maxAgeKey);\n        \t\n        \tint maxAge = 0; // Initialize to 0\n        \tif (maxAgeStr != null) {\n                // Convert the maximum age to an integer\n        \t\tmaxAge = Integer.parseInt(maxAgeStr);\n        \t}\n\n        \t// Update the maximum age if a new age is higher\n        \tif (newAge > maxAge) {               \n        \t\tGearsBuilder.execute(\"SET\", maxAgeKey, newAgeStr); \n        \t}\n        });\n        \n        // Store this pipeline of functions and \n        // run them when a new person key is added\n        gb.register(ExecutionMode.SYNC);\n        // Note: ExecutionMode defaults to ASYNC \n        // if you call register() without any arguments\n    }\n}",
      "section_id": "event-processing"
    },
    {
      "id": "event-processing-ex1",
      "language": "sh",
      "code": "$ redis-cli -h <host> -p <port>",
      "section_id": "event-processing"
    },
    {
      "id": "event-processing-ex2",
      "language": "sh",
      "code": "127.0.0.1:12000> HSET person:1 name \"Alex\" age 24\n    (integer) 2",
      "section_id": "event-processing"
    },
    {
      "id": "event-processing-ex3",
      "language": "sh",
      "code": "127.0.0.1:12000> GET age:maximum\n    \"24\"",
      "section_id": "event-processing"
    },
    {
      "id": "event-processing-ex4",
      "language": "sh",
      "code": "127.0.0.1:12000> HSET person:2 name \"Morgan\" age 45\n    (integer) 2\n    127.0.0.1:12000> GET age:maximum\n    \"45\"",
      "section_id": "event-processing"
    },
    {
      "id": "event-processing-ex5",
      "language": "sh",
      "code": "127.0.0.1:12000> HSET person:3 name \"Lee\" age 31\n    (integer) 2\n    127.0.0.1:12000> GET age:maximum\n    \"45\"",
      "section_id": "event-processing"
    }
  ]
}
