This is an automated email from the ASF dual-hosted git repository.

mpochatkin pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new c458d1110a6 IGNITE-27212 - Complete automation for compute deployment 
unit; Minor bug fixes (#7122)
c458d1110a6 is described below

commit c458d1110a60833b05fe24d2851bb9da87468141
Author: Ashish Mishra <[email protected]>
AuthorDate: Thu Feb 26 16:42:38 2026 +0530

    IGNITE-27212 - Complete automation for compute deployment unit; Minor bug 
fixes (#7122)
---
 examples/java/README.md                            |  44 +++
 examples/java/build.gradle                         |  37 +++
 .../ignite/example/client/IgniteClientExample.java |   6 +
 .../client/IgniteClientWithConfigExample.java      |   6 +
 .../code/deployment/CodeDeploymentExample.java     |  24 +-
 .../example/compute/ComputeAsyncExample.java       |  41 +--
 .../example/compute/ComputeBroadcastExample.java   | 151 ++++++---
 .../compute/ComputeCancellationExample.java        |  40 +--
 .../example/compute/ComputeColocatedExample.java   | 148 ++++-----
 .../ignite/example/compute/ComputeExample.java     |  39 +--
 .../example/compute/ComputeJobPriorityExample.java |  40 +--
 .../example/compute/ComputeJobStateExample.java    |  52 +--
 .../example/compute/ComputeMapReduceExample.java   |  37 +--
 .../ComputeWithCustomResultMarshallerExample.java  |  37 ++-
 .../example/compute/ComputeWithResultExample.java  |  43 +--
 .../example/serialization/AutoSerializableArg.java |  14 +-
 .../CustomPojoSerializationExample.java            |  26 +-
 .../serialization/CustomPojoSerializationJob.java  |  10 +-
 .../ignite/example/serialization/JsonArg.java      |  26 +-
 .../ignite/example/serialization/JsonResult.java   |  39 ++-
 .../PojoAutoSerializationExample.java              |   1 +
 .../serialization/SerializationExample.java        |  35 ++
 .../serialization/TupleSerializationExample.java   |   5 +-
 .../streaming/DetectFailedEntriesExample.java      |   7 +-
 .../DistributedComputeWithReceiverExample.java     | 155 +++++----
 .../streaming/MultiTableDataStreamerExample.java   |  57 +++-
 .../streaming/SingleTableDataStreamerExample.java  |   6 +-
 .../ignite/example/table/KeyValueViewExample.java  |   2 +-
 .../example/table/KeyValueViewPojoExample.java     |   2 +-
 .../apache/ignite/example/table/QueryExample.java  |   5 +
 .../ignite/example/table/RecordViewExample.java    |   2 +-
 .../example/table/RecordViewPojoExample.java       |   2 +-
 .../apache/ignite/example/table/TableExample.java  |   2 +-
 .../ignite/example/tx/TransactionsExample.java     |  12 +-
 .../ignite/example/util/DeployComputeUnit.java     | 367 +++++++++++++++++++++
 .../example/code/deployment/resources/script.sh    |   0
 36 files changed, 1137 insertions(+), 383 deletions(-)

diff --git a/examples/java/README.md b/examples/java/README.md
index 3e0eda2a2db..972d47633b9 100644
--- a/examples/java/README.md
+++ b/examples/java/README.md
@@ -118,3 +118,47 @@ with a result return.
     ```shell
     $IGNITE_HOME/bin/ignite3db stop
     ```
+
+## Running Compute and Streaming Examples
+
+Compute and streaming examples require deployment units to be deployed to the 
cluster. There are two ways to run these examples:
+
+### Automated Mode (Recommended)
+
+**From IDE:**
+
+Simply run the example from your IDE. The deployment unit JAR is automatically 
built and deployed if not already present.
+
+**From Command Line:**
+
+Run the example with the following arguments:
+```shell
+java -cp "<classpath>" <ExampleMainClass> runFromIDE=false 
jarPath="/path/to/examples.jar"
+```
+
+Where:
+- `runFromIDE=false` - indicates command-line execution
+- `jarPath` - path to the examples JAR used as the deployment unit
+
+### Manual Mode
+
+If you prefer to deploy the unit manually:
+
+1. Build the examples JAR:
+    ```shell
+    ./gradlew :ignite-examples:jar
+    ```
+
+2. Deploy the JAR as a deployment unit using the CLI:
+    ```shell
+    cluster unit deploy <unitName> \
+        --version 1.0.0 \
+        --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar
+    ```
+
+   Common unit names used by examples:
+   - `computeExampleUnit` - used by compute examples
+   - `streamerReceiverExampleUnit` - used by streaming examples
+
+3. Run the example from the IDE.
+
diff --git a/examples/java/build.gradle b/examples/java/build.gradle
index 8afcd1c0328..db7bbf99373 100644
--- a/examples/java/build.gradle
+++ b/examples/java/build.gradle
@@ -22,6 +22,42 @@ apply from: 
"$rootDir/buildscripts/java-integration-test.gradle"
 
 description = 'ignite-examples'
 
+// Create deployment unit JAR from compiled classes (no file movement needed)
+// This JAR includes all Job classes and resources needed for deployment
+tasks.register('deploymentUnitJar', Jar) {
+    dependsOn classes, processResources
+    group = 'build'
+    archiveBaseName = 'deploymentunit-example'
+    archiveVersion = '1.0.0'
+
+    // Include all compiled Job classes and related deployment code
+    from(sourceSets.main.output.classesDirs) {
+        include 'org/apache/ignite/example/**/*Job.class'
+        include 'org/apache/ignite/example/**/*Job$*.class'
+        include 'org/apache/ignite/example/**/Compute*Example.class'
+        include 'org/apache/ignite/example/**/Compute*Example$*.class'
+        include 'org/apache/ignite/example/**/Distributed*Example.class'
+        include 'org/apache/ignite/example/**/Distributed*Example$*.class'
+        include 'org/apache/ignite/example/streaming/Account.class'
+        include 'org/apache/ignite/example/table/Person.class'
+        // Include all serialization support classes (Args, Results, 
Marshallers)
+        include 
'org/apache/ignite/example/serialization/AutoSerializableArg.class'
+        include 
'org/apache/ignite/example/serialization/AutoSerializableResult.class'
+        include 'org/apache/ignite/example/serialization/JsonArg.class'
+        include 'org/apache/ignite/example/serialization/JsonResult.class'
+        include 
'org/apache/ignite/example/serialization/JsonArgMarshaller.class'
+        include 
'org/apache/ignite/example/serialization/JsonResultMarshaller.class'
+    }
+
+    // Include resources needed by deployment unit from source
+    from(sourceSets.main.resources.srcDirs) {
+        include 'org/apache/ignite/example/code/deployment/resources/**'
+    }
+}
+
+// Make build task depend on deploymentUnitJar
+build.dependsOn deploymentUnitJar
+
 dependencies {
     implementation project(':ignite-runner')
     implementation project(':ignite-client')
@@ -31,6 +67,7 @@ dependencies {
     implementation platform(libs.jackson.bom)
     implementation libs.jackson.core
     implementation libs.jackson.databind
+    implementation libs.awaitility
 
     testImplementation project(':ignite-core')
 
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientExample.java
index 519ab2523a0..c45135303a8 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientExample.java
@@ -26,6 +26,12 @@ import org.apache.ignite.client.IgniteClient;
  */
 
 public class IgniteClientExample {
+    /**
+     * Runs the IgniteClientExample.
+     *
+     * @param args The command line arguments.
+     * @throws Exception if any error occurs.
+     */
     public static void main(String[] args) throws Exception {
         
//--------------------------------------------------------------------------------------
         //
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientWithConfigExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientWithConfigExample.java
index ffa8a560c8b..d884b834126 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientWithConfigExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/client/IgniteClientWithConfigExample.java
@@ -28,6 +28,12 @@ import org.apache.ignite.client.RetryLimitPolicy;
  */
 
 public class IgniteClientWithConfigExample {
+    /**
+     * Runs the IgniteClientWithConfigExample.
+     *
+     * @param args The command line arguments.
+     * @throws Exception if any error occurs.
+     */
     public static void main(String[] args) throws Exception {
 
         
//--------------------------------------------------------------------------------------
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/code/deployment/CodeDeploymentExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/code/deployment/CodeDeploymentExample.java
index 1db20427358..d4ca3ddd96b 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/code/deployment/CodeDeploymentExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/code/deployment/CodeDeploymentExample.java
@@ -17,10 +17,22 @@
 
 package org.apache.ignite.example.code.deployment;
 
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
+
 import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.compute.IgniteCompute;
 import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
+
+/**
+ * This example demonstrates the usage of the {@link IgniteCompute#execute} 
API.
+ *
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
+ */
+
 
 public class CodeDeploymentExample {
 
@@ -31,18 +43,21 @@ public class CodeDeploymentExample {
     private static final String DEPLOYMENT_UNIT_VERSION = "1.0.0";
 
     /**
-     * Main method of the example.
+     * Runs the CodeDeploymentExample.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
-
+    public static void main(String[] args) throws Exception {
+        DeployComputeUnit.processDeploymentUnit(args);
         System.out.println("\nConnecting to server...");
 
         try (IgniteClient client = 
IgniteClient.builder().addresses("127.0.0.1:10800").build()) {
 
             System.out.println("\nConfiguring compute job...");
 
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             JobDescriptor<String, String> job = 
JobDescriptor.builder(MyJob.class)
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION)).resultClass(String.class).build();
 
@@ -53,6 +68,9 @@ public class CodeDeploymentExample {
             String result = client.compute().execute(target, job, "Hello from 
job");
 
             System.out.println("\n=== Result ===\n" + result);
+        } finally {
+            System.out.println("Cleaning up resources...");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
         }
     }
 }
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeAsyncExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeAsyncExample.java
index 2fe0f567567..2acdf8e0694 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeAsyncExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeAsyncExample.java
@@ -18,12 +18,13 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
 import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.compute.ComputeJob;
@@ -32,27 +33,14 @@ import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#executeAsync(JobTarget, JobDescriptor, Object)} API.
+ * This example demonstrates the usage of the {@link 
IgniteCompute#executeAsync} API.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeAsyncExample {
     /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
@@ -60,12 +48,17 @@ public class ComputeAsyncExample {
     /** Deployment unit version. */
     private static final String DEPLOYMENT_UNIT_VERSION = "1.0.0";
 
+
     /**
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) throws ExecutionException, 
InterruptedException {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -86,6 +79,9 @@ public class ComputeAsyncExample {
 
             System.out.println("\nConfiguring compute job...");
 
+
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             JobDescriptor<String, Integer> job = 
JobDescriptor.builder(WordLengthJob.class)
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
                     .build();
@@ -135,13 +131,18 @@ public class ComputeAsyncExample {
             
//--------------------------------------------------------------------------------------
 
             System.out.println("\nTotal number of characters in the words is 
'" + sum + "'.");
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
         }
     }
 
     /**
      * Job that calculates length of the provided word.
      */
-    private static class WordLengthJob implements ComputeJob<String, Integer> {
+    public static class WordLengthJob implements ComputeJob<String, Integer> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Integer> executeAsync(JobExecutionContext 
context, String arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeBroadcastExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeBroadcastExample.java
index 62054f056c8..b4ebf9a28e1 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeBroadcastExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeBroadcastExample.java
@@ -19,6 +19,8 @@ package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static org.apache.ignite.compute.BroadcastJobTarget.table;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.client.IgniteClient;
@@ -28,29 +30,13 @@ import org.apache.ignite.compute.IgniteCompute;
 import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 import org.apache.ignite.table.QualifiedName;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#execute(BroadcastJobTarget, JobDescriptor, Object)} 
API.
+ * This example demonstrates the usage of the {@link 
IgniteCompute#execute(BroadcastJobTarget, JobDescriptor, Object)} API.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>This example is intended to be run on a cluster with more than one node 
to show that the job is broadcast to each node.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
 public class ComputeBroadcastExample {
     /** Deployment unit name. */
@@ -63,8 +49,12 @@ public class ComputeBroadcastExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -77,55 +67,112 @@ public class ComputeBroadcastExample {
                 .addresses("127.0.0.1:10800")
                 .build()
         ) {
-            
//--------------------------------------------------------------------------------------
-            //
-            // Configuring compute job.
-            //
-            
//--------------------------------------------------------------------------------------
 
-            System.out.println("\nConfiguring compute job...");
+            try {
+
+                
//--------------------------------------------------------------------------------------
+                //
+                // Prerequisites for the example:
+                // 1. Create table and schema for the example.
+                // 2. Create a new deployment unit for the compute job.
+                //
+                
//--------------------------------------------------------------------------------------
+
+                setupTablesAndSchema(client);
+                deployIfNotExist(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION, DeployComputeUnit.getJarPath());
+
+                
//--------------------------------------------------------------------------------------
+                //
+                // Configuring compute job.
+                //
+                
//--------------------------------------------------------------------------------------
+
+                System.out.println("\nConfiguring compute job...");
 
-            JobDescriptor<String, Void> job = 
JobDescriptor.builder(HelloMessageJob.class)
-                    .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
-                    .build();
+                JobDescriptor<String, Void> job = 
JobDescriptor.builder(HelloMessageJob.class)
+                        .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
+                        .build();
 
-            BroadcastJobTarget target = table("Person");
+                BroadcastJobTarget target = table("Person");
 
-            
//--------------------------------------------------------------------------------------
-            //
-            // Executing compute job using configured jobTarget.
-            //
-            
//--------------------------------------------------------------------------------------
+                
//--------------------------------------------------------------------------------------
+                //
+                // Executing compute job using configured jobTarget.
+                //
+                
//--------------------------------------------------------------------------------------
 
-            System.out.println("\nExecuting compute job...");
+                System.out.println("\nExecuting compute job...");
 
-            client.compute().execute(target, job, "John");
+                client.compute().execute(target, job, "John");
 
-            System.out.println("\nCompute job executed...");
+                System.out.println("\nCompute job executed...");
 
-            
//--------------------------------------------------------------------------------------
-            //
-            // Executing compute job using a custom by specifying a fully 
qualified table name .
-            //
-            //
+                
//--------------------------------------------------------------------------------------
+                //
+                // Executing compute job using a custom by specifying a fully 
qualified table name .
+                //
+                //
 
-            QualifiedName customSchemaTable = 
QualifiedName.parse("CUSTOM_SCHEMA.MY_QUALIFIED_TABLE");
-            client.compute().execute(table(customSchemaTable),
-                    JobDescriptor.builder(HelloMessageJob.class).build(), null
-            );
+                QualifiedName customSchemaTable = 
QualifiedName.parse("CUSTOM_SCHEMA.MY_QUALIFIED_TABLE");
+                client.compute().execute(table(customSchemaTable),
+                        JobDescriptor.builder(HelloMessageJob.class)
+                                .units(new 
DeploymentUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION))
+                                .build(), null
+                );
 
+                QualifiedName customSchemaTableName = 
QualifiedName.of("PUBLIC", "MY_TABLE");
+                client.compute().execute(table(customSchemaTableName),
+                        JobDescriptor.builder(HelloMessageJob.class)
+                                .units(new 
DeploymentUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION))
+                                .build(), null
+                );
+            } finally {
 
-            QualifiedName customSchemaTableName = QualifiedName.of("PUBLIC", 
"MY_TABLE");
-            client.compute().execute(table(customSchemaTableName),
-                    JobDescriptor.builder(HelloMessageJob.class).build(), null
-            );
+                System.out.println("Cleaning up resources");
+                undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
+                // Drop tables
+                System.out.println("\nDropping the tables...");
+
+                client.sql().executeScript("DROP TABLE IF EXISTS Person");
+                client.sql().executeScript("DROP TABLE IF EXISTS 
PUBLIC.MY_TABLE");
+                client.sql().executeScript("DROP SCHEMA IF EXISTS 
CUSTOM_SCHEMA CASCADE");
+            }
         }
     }
 
+    /**
+     * Sets up the tables and schema required for the broadcast example.
+     *
+     * <p>This setup ensures the example is self-contained and can run
+     * without external dependencies, enabling automated execution.</p>
+     *
+     * @param client The Ignite client to use for executing SQL statements.
+     */
+    private static void setupTablesAndSchema(IgniteClient client) {
+        client.sql().executeScript("DROP SCHEMA IF EXISTS CUSTOM_SCHEMA 
CASCADE");
+        client.sql().executeScript("CREATE SCHEMA CUSTOM_SCHEMA");
+        client.sql().executeScript("CREATE TABLE 
CUSTOM_SCHEMA.MY_QUALIFIED_TABLE ("
+                + "ID INT PRIMARY KEY, MESSAGE VARCHAR(255))");
+
+        client.sql().executeScript("CREATE SCHEMA IF NOT EXISTS PUBLIC");
+        client.sql().executeScript("CREATE TABLE IF NOT EXISTS PUBLIC.MY_TABLE 
("
+                + "ID INT PRIMARY KEY, MESSAGE VARCHAR(255))");
+
+        client.sql().executeScript("CREATE TABLE PERSON ("
+                + "ID INT PRIMARY KEY, FIRST_NAME VARCHAR(100),"
+                + "LAST_NAME VARCHAR(100), AGE INT)");
+
+        client.sql().executeScript("INSERT INTO PERSON VALUES "
+                + "(1, 'John', 'Doe', 36),"
+                + "(2, 'Jane', 'Smith', 35),"
+                + "(3, 'Robert', 'Johnson', 25)");
+    }
+
     /**
      * Job that prints hello message with provided name.
      */
-    private static class HelloMessageJob implements ComputeJob<String, Void> {
+    public static class HelloMessageJob implements ComputeJob<String, Void> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Void> executeAsync(JobExecutionContext 
context, String arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeCancellationExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeCancellationExample.java
index 70f9a7229e2..d9cb7f5af47 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeCancellationExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeCancellationExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
@@ -29,29 +31,15 @@ import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 import org.apache.ignite.lang.CancelHandle;
-import org.apache.ignite.lang.CancellationToken;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#executeAsync(JobTarget, JobDescriptor, Object, 
CancellationToken)} API.
+ * This example demonstrates the usage of the {@link 
IgniteCompute#executeAsync} API with cancellation support.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeCancellationExample {
     /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
@@ -63,8 +51,12 @@ public class ComputeCancellationExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -85,6 +77,9 @@ public class ComputeCancellationExample {
 
             System.out.println("\nConfiguring compute job...");
 
+
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             JobDescriptor<Object, Void> job = 
JobDescriptor.builder(InfiniteJob.class)
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
                     .build();
@@ -124,13 +119,18 @@ public class ComputeCancellationExample {
             } catch (CompletionException ex) {
                 System.out.println("\nThe compute job was cancelled: " + 
ex.getMessage());
             }
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
         }
     }
 
     /**
      * The job to interrupt.
      */
-    private static class InfiniteJob implements ComputeJob<Object, Void> {
+    public static class InfiniteJob implements ComputeJob<Object, Void> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Void> executeAsync(JobExecutionContext 
context, Object arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeColocatedExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeColocatedExample.java
index 714bf1f4c3f..d72254d74fe 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeColocatedExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeColocatedExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ThreadLocalRandom;
@@ -28,29 +30,16 @@ import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 import org.apache.ignite.table.RecordView;
 import org.apache.ignite.table.Tuple;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#execute(JobTarget, JobDescriptor, Object)} API with 
colocated JobTarget.
+ * This example demonstrates the usage of the {@link IgniteCompute#execute} 
API with colocated JobTarget.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeColocatedExample {
     /** Number of accounts to load. */
     private static final int ACCOUNTS_COUNT = 100;
@@ -65,8 +54,12 @@ public class ComputeColocatedExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -79,80 +72,85 @@ public class ComputeColocatedExample {
                 .addresses("127.0.0.1:10800")
                 .build()
         ) {
-            
//--------------------------------------------------------------------------------------
-            //
-            // Creating table.
-            //
-            
//--------------------------------------------------------------------------------------
-
-            client.sql().executeScript(
-                    "CREATE TABLE accounts ("
-                            + "accountNumber INT PRIMARY KEY,"
-                            + "name          VARCHAR)"
-            );
-
-            
//--------------------------------------------------------------------------------------
-            //
-            // Creating a record view for the 'accounts' table.
-            //
-            
//--------------------------------------------------------------------------------------
-
-            RecordView<Tuple> view = 
client.tables().table("accounts").recordView();
-
-            
//--------------------------------------------------------------------------------------
-            //
-            // Creating account records.
-            //
-            
//--------------------------------------------------------------------------------------
-
-            System.out.println("\nCreating account records...");
-
-            for (int i = 0; i < ACCOUNTS_COUNT; i++) {
-                view.insert(null, account(i));
-            }
 
-            
//--------------------------------------------------------------------------------------
-            //
-            // Configuring compute job.
-            //
-            
//--------------------------------------------------------------------------------------
+            try {
+                
//--------------------------------------------------------------------------------------
+                //
+                // Creating table.
+                //
+                
//--------------------------------------------------------------------------------------
+
+                client.sql().executeScript(
+                        "CREATE TABLE accounts ("
+                                + "accountNumber INT PRIMARY KEY,"
+                                + "name          VARCHAR)"
+                );
+
+                
//--------------------------------------------------------------------------------------
+                //
+                // Creating a record view for the 'accounts' table.
+                //
+                
//--------------------------------------------------------------------------------------
+
+                RecordView<Tuple> view = 
client.tables().table("accounts").recordView();
 
-            System.out.println("\nConfiguring compute job...");
+                
//--------------------------------------------------------------------------------------
+                //
+                // Creating account records.
+                //
+                
//--------------------------------------------------------------------------------------
 
-            JobDescriptor<Integer, Void> job = 
JobDescriptor.builder(PrintAccountInfoJob.class)
-                    .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
-                    .build();
+                System.out.println("\nCreating account records...");
 
-            int accountNumber = 
ThreadLocalRandom.current().nextInt(ACCOUNTS_COUNT);
+                for (int i = 0; i < ACCOUNTS_COUNT; i++) {
+                    view.insert(null, account(i));
+                }
 
-            JobTarget jobTarget = JobTarget.colocated("accounts", 
accountKey(accountNumber));
+                
//--------------------------------------------------------------------------------------
+                //
+                // Configuring compute job.
+                //
+                
//--------------------------------------------------------------------------------------
 
-            
//--------------------------------------------------------------------------------------
-            //
-            // Executing compute job for the specific accountNumber.
-            //
-            
//--------------------------------------------------------------------------------------
+                System.out.println("\nConfiguring compute job...");
 
-            System.out.println("\nExecuting compute job for the accountNumber 
'" + accountNumber + "'...");
+                deployIfNotExist(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION, DeployComputeUnit.getJarPath());
 
-            client.compute().execute(jobTarget, job, accountNumber);
+                JobDescriptor<Integer, Void> job = 
JobDescriptor.builder(PrintAccountInfoJob.class)
+                        .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
+                        .build();
 
-            
//--------------------------------------------------------------------------------------
-            //
-            // Dropping the table.
-            //
-            
//--------------------------------------------------------------------------------------
+                int accountNumber = 
ThreadLocalRandom.current().nextInt(ACCOUNTS_COUNT);
 
-            System.out.println("\nDropping the table...");
+                JobTarget jobTarget = JobTarget.colocated("accounts", 
accountKey(accountNumber));
+
+                
//--------------------------------------------------------------------------------------
+                //
+                // Executing compute job for the specific accountNumber.
+                //
+                
//--------------------------------------------------------------------------------------
+
+                System.out.println("\nExecuting compute job for the 
accountNumber '" + accountNumber + "'...");
+
+                client.compute().execute(jobTarget, job, accountNumber);
+            } finally {
+
+                System.out.println("Cleaning up resources");
+                undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
+                /* Drop table */
+                System.out.println("\nDropping the table...");
+
+                client.sql().executeScript("DROP TABLE IF EXISTS accounts");
+            }
 
-            client.sql().executeScript("DROP TABLE accounts");
         }
     }
 
     /**
      * Job that prints account info for the provided accountNumber.
      */
-    private static class PrintAccountInfoJob implements ComputeJob<Integer, 
Void> {
+    public static class PrintAccountInfoJob implements ComputeJob<Integer, 
Void> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Void> executeAsync(JobExecutionContext 
context, Integer arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeExample.java
index 685064471f8..08ea0a3ca41 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.client.IgniteClient;
@@ -27,27 +29,14 @@ import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#execute(JobTarget, JobDescriptor, Object)} API.
+ * This example demonstrates the usage of the {@link IgniteCompute#execute} 
API.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeExample {
     /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
@@ -59,8 +48,12 @@ public class ComputeExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -81,6 +74,9 @@ public class ComputeExample {
 
             System.out.println("\nConfiguring compute job...");
 
+
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             JobDescriptor<String, Void> job = 
JobDescriptor.builder(WordPrintJob.class)
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
                     .build();
@@ -104,13 +100,18 @@ public class ComputeExample {
 
                 client.compute().execute(jobTarget, job, word);
             }
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
         }
     }
 
     /**
      * Job that prints provided word.
      */
-    private static class WordPrintJob implements ComputeJob<String, Void> {
+    public static class WordPrintJob implements ComputeJob<String, Void> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Void> executeAsync(JobExecutionContext 
context, String arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobPriorityExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobPriorityExample.java
index 28adaa57d7a..0e4067d1e68 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobPriorityExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobPriorityExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -30,27 +32,14 @@ import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobExecutionOptions;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#execute(JobTarget, JobDescriptor, Object)} API with 
different job priorities.
+ * This example demonstrates the usage of the {@link IgniteCompute#execute} 
API with different job priorities.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy receiverExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeJobPriorityExample {
     /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
@@ -62,8 +51,12 @@ public class ComputeJobPriorityExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -81,6 +74,9 @@ public class ComputeJobPriorityExample {
 
             System.out.println("\nConfiguring compute job...");
 
+
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             JobDescriptor<Integer, String> lowPriorityJob = 
JobDescriptor.builder(LowPriorityJob.class)
                     
.options(JobExecutionOptions.builder().priority(0).maxRetries(5).build())
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
@@ -122,13 +118,17 @@ public class ComputeJobPriorityExample {
             
//--------------------------------------------------------------------------------------
 
             CompletableFuture.allOf(jobFutures.toArray(new 
CompletableFuture[0])).join();
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
         }
     }
 
     /**
      * High-priority job.
      */
-    private static class HighPriorityJob implements ComputeJob<Integer, 
String> {
+    public static class HighPriorityJob implements ComputeJob<Integer, String> 
{
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<String> executeAsync(JobExecutionContext 
context, Integer arg) {
@@ -151,7 +151,7 @@ public class ComputeJobPriorityExample {
     /**
      * Low-priority job.
      */
-    private static class LowPriorityJob implements ComputeJob<Integer, String> 
{
+    public static class LowPriorityJob implements ComputeJob<Integer, String> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<String> executeAsync(JobExecutionContext 
context, Integer arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobStateExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobStateExample.java
index b28591b7a17..145ddb642f1 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobStateExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeJobStateExample.java
@@ -19,48 +19,49 @@ package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static org.apache.ignite.compute.JobStatus.FAILED;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
 import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.compute.ComputeJob;
 import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecution;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobTarget;
+import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 
 /**
- * This code demonstrates the usage of the {@link JobExecution} interface that 
allows to get job statuses and, for example, handle failures.
+ * This code demonstrates the usage of the {@link JobExecution} interface that 
allows to get job statuses and, for example, handle
+ * failures.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeJobStateExample {
 
+    /** Deployment unit name. */
+    private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
+
+    /** Deployment unit version. */
+    private static final String DEPLOYMENT_UNIT_VERSION = "1.0.0";
+
     /**
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) throws ExecutionException, 
InterruptedException {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
         //
-        
//--------------------------------------------------------------------------------------
+        //--------------------- 
-----------------------------------------------------------------
 
         System.out.println("\nConnecting to server...");
 
@@ -76,8 +77,12 @@ public class ComputeJobStateExample {
 
             System.out.println("\nConfiguring compute job...");
 
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             CompletableFuture<JobExecution<Void>> execution = 
client.compute().submitAsync(JobTarget.anyNode(client.cluster().nodes()),
-                    JobDescriptor.builder(WordPrintJob.class).build(), null
+                    JobDescriptor.builder(WordPrintJob.class)
+                            .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
+                            .build(), null
             );
 
             execution.get().stateAsync().thenApply(state -> {
@@ -86,13 +91,18 @@ public class ComputeJobStateExample {
                 }
                 return null;
             });
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
         }
     }
 
     /**
      * Job that prints provided word.
      */
-    private static class WordPrintJob implements ComputeJob<String, Void> {
+    public static class WordPrintJob implements ComputeJob<String, Void> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Void> executeAsync(JobExecutionContext 
context, String arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeMapReduceExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeMapReduceExample.java
index 8f73727240e..41061b0bce0 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeMapReduceExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeMapReduceExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -34,27 +36,14 @@ import org.apache.ignite.compute.task.MapReduceJob;
 import org.apache.ignite.compute.task.MapReduceTask;
 import org.apache.ignite.compute.task.TaskExecutionContext;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#executeMapReduce(TaskDescriptor, Object)} API.
+ * This example demonstrates the usage of the {@link 
IgniteCompute#executeMapReduce} API.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy receiverExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeMapReduceExample {
     /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
@@ -66,8 +55,12 @@ public class ComputeMapReduceExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -85,6 +78,7 @@ public class ComputeMapReduceExample {
 
             System.out.println("\nConfiguring map reduce task...");
 
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
 
             TaskDescriptor<String, Integer> taskDescriptor = 
TaskDescriptor.builder(PhraseWordLengthCountMapReduceTask.class)
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
@@ -109,6 +103,11 @@ public class ComputeMapReduceExample {
             
//--------------------------------------------------------------------------------------
 
             System.out.println("\nTotal number of characters in the words is 
'" + result + "'.");
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
         }
     }
 
@@ -154,7 +153,7 @@ public class ComputeMapReduceExample {
     /**
      * Job that counts length of the provided word.
      */
-    private static class WordLengthJob implements ComputeJob<String, Integer> {
+    public static class WordLengthJob implements ComputeJob<String, Integer> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Integer> executeAsync(JobExecutionContext 
context, String arg) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithCustomResultMarshallerExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithCustomResultMarshallerExample.java
index 3cbfaaf31d6..3dff5c65739 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithCustomResultMarshallerExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithCustomResultMarshallerExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -29,29 +31,16 @@ import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 import org.apache.ignite.marshalling.ByteArrayMarshaller;
 import org.apache.ignite.marshalling.Marshaller;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#execute(JobTarget, JobDescriptor, Object)} API with a 
custom result marshaller.
+ * This example demonstrates the usage of the {@link IgniteCompute#execute} 
API with a custom result marshaller.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeWithCustomResultMarshallerExample {
     /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
@@ -63,8 +52,12 @@ public class ComputeWithCustomResultMarshallerExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -85,6 +78,9 @@ public class ComputeWithCustomResultMarshallerExample {
 
             System.out.println("\nConfiguring compute job...");
 
+
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             JobDescriptor<String, WordInfoResult> job = 
JobDescriptor.builder(WordInfoJob.class)
                     .resultMarshaller(new WordInfoResultMarshaller())
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
@@ -118,6 +114,11 @@ public class ComputeWithCustomResultMarshallerExample {
 
             for (WordInfoResult result : results)
                 System.out.println("The length of the word '" + result.word + 
"'" + " is " + result.length + ".");
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
         }
     }
 
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithResultExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithResultExample.java
index f9062d3f0a7..ce80449931e 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithResultExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/compute/ComputeWithResultExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.compute;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.client.IgniteClient;
@@ -27,27 +29,14 @@ import org.apache.ignite.compute.JobDescriptor;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 
 /**
- * This example demonstrates the usage of the
- * {@link IgniteCompute#execute(JobTarget, JobDescriptor, Object)} API with a 
result return.
+ * This example demonstrates the usage of the {@link IgniteCompute#execute} 
API with a result return.
  *
- * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
- *
- * <p>The following steps related to code deployment should be additionally 
executed before running the current example:
- * <ol>
- *     <li>
- *         Build "ignite-examples-x.y.z.jar" using the next command:<br>
- *         {@code ./gradlew :ignite-examples:jar}
- *     </li>
- *     <li>
- *         Create a new deployment unit using the CLI tool:<br>
- *         {@code cluster unit deploy computeExampleUnit \
- *          --version 1.0.0 \
- *          --path=$IGNITE_HOME/examples/build/libs/ignite-examples-x.y.z.jar}
- *     </li>
- * </ol>
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
+
 public class ComputeWithResultExample {
     /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = "computeExampleUnit";
@@ -59,8 +48,12 @@ public class ComputeWithResultExample {
      * Main method of the example.
      *
      * @param args The command line arguments.
+     * @throws Exception if any error occurs.
      */
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(args);
+
         
//--------------------------------------------------------------------------------------
         //
         // Creating a client to connect to the cluster.
@@ -81,12 +74,17 @@ public class ComputeWithResultExample {
 
             System.out.println("\nConfiguring compute job...");
 
+
+
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
             JobDescriptor<String, Integer> job = 
JobDescriptor.builder(WordCountJob.class)
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
                     .build();
-
             JobTarget jobTarget = JobTarget.anyNode(client.cluster().nodes());
 
+
+
             
//--------------------------------------------------------------------------------------
             //
             // Executing compute job using configured jobTarget.
@@ -106,13 +104,18 @@ public class ComputeWithResultExample {
             
//--------------------------------------------------------------------------------------
 
             System.out.println("\nTotal number of words in the phrase is '" + 
wordCnt + "'.");
+        } finally {
+
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
+
         }
     }
 
     /**
      * Job that counts words in the provided phrase.
      */
-    private static class WordCountJob implements ComputeJob<String, Integer> {
+    public static class WordCountJob implements ComputeJob<String, Integer> {
         /** {@inheritDoc} */
         @Override
         public CompletableFuture<Integer> executeAsync(JobExecutionContext 
context, String phrase) {
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/AutoSerializableArg.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/AutoSerializableArg.java
index 379d2f0ba7d..0bb41e5a2e8 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/AutoSerializableArg.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/AutoSerializableArg.java
@@ -17,17 +17,29 @@
 
 package org.apache.ignite.example.serialization;
 
+/**
+ * Argument object used in auto-serialization examples.
+ */
 public class AutoSerializableArg {
 
+    /** Word to process. */
     String word;
+
+    /** Whether the word should be converted to upper case. */
     boolean isUpperCase;
 
+    /** Default constructor. */
     public AutoSerializableArg() {
     }
 
+    /**
+     * Creates a new argument object.
+     *
+     * @param word Word value.
+     * @param isUpperCase Flag indicating upper-case conversion.
+     */
     AutoSerializableArg(String word, boolean isUpperCase) {
         this.word = word;
         this.isUpperCase = isUpperCase;
     }
 }
-
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationExample.java
index b8c0e8ec524..ba9fe53be0c 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationExample.java
@@ -19,7 +19,6 @@ package org.apache.ignite.example.serialization;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
-
 import java.io.IOException;
 
 import org.apache.ignite.client.IgniteClient;
@@ -28,14 +27,26 @@ import org.apache.ignite.compute.JobTarget;
 import org.apache.ignite.deployment.DeploymentUnit;
 import org.apache.ignite.marshalling.Marshaller;
 
+/**
+ * Example demonstrating custom POJO serialization using custom marshallers
+ * on both client and server side.
+ */
 public class CustomPojoSerializationExample {
 
+    /**
+     * Name of the deployment unit used in this example.
+     */
     public static final String DEPLOYMENT_UNIT_NAME = 
"customPojoSerializationExampleUnit";
+
+    /**
+     * Version of the deployment unit used in this example.
+     */
     public static final String DEPLOYMENT_UNIT_VERSION = "1.0.0";
 
     /**
-     * Using POJO with custom marshallers: job runs on the server and sets 
input/result marshallers, meanwhile client sets argument/result
-     * marshallers on descriptor.
+     * Runs the POJO job using custom JSON marshallers set on both client and 
server.
+     *
+     * @param client Ignite client instance.
      */
     static void runPojoCustomJsonSerialization(IgniteClient client) {
 
@@ -54,10 +65,12 @@ public class CustomPojoSerializationExample {
         );
 
         System.out.printf("[POJO custom] original=%s, result=%s, length=%d%n",
-                res.originalWord, res.resultWord, res.length);
+                res.getOriginalWord(), res.getResultWord(), res.getLength());
     }
 
-
+    /**
+     * Marshaller for JSON result objects.
+     */
     private static class JsonResultMarshaller implements 
Marshaller<JsonResult, byte[]> {
         private static final ObjectMapper MAPPER = new ObjectMapper();
 
@@ -80,6 +93,3 @@ public class CustomPojoSerializationExample {
         }
     }
 }
-
-
-
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationJob.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationJob.java
index aea480095a1..6805090ff15 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationJob.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/CustomPojoSerializationJob.java
@@ -32,12 +32,12 @@ public class CustomPojoSerializationJob implements 
ComputeJob<JsonArg, JsonResul
             return null;
         }
 
-        String w = arg.word;
-        boolean upper = arg.isUpperCase;
+        String w = arg.getWord();
+        boolean upper = arg.isUpperCase();
         JsonResult r = new JsonResult();
-        r.originalWord = w;
-        r.resultWord = upper ? w.toUpperCase() : w.toLowerCase();
-        r.length = w.length();
+        r.setOriginalWord(w);
+        r.setResultWord(upper ? w.toUpperCase() : w.toLowerCase());
+        r.setLength(w.length());
         return completedFuture(r);
     }
 
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonArg.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonArg.java
index db7331843e8..1aed8eb10e0 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonArg.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonArg.java
@@ -18,14 +18,30 @@
 package org.apache.ignite.example.serialization;
 
 public class JsonArg {
-    String word;
-    boolean isUpperCase;
+    private String word;
+    private boolean isUpperCase;
 
-    public JsonArg() {
-    }
+    public JsonArg() {}
 
-    JsonArg(String word, boolean isUpperCase) {
+    public JsonArg(String word, boolean isUpperCase) {
         this.word = word;
         this.isUpperCase = isUpperCase;
     }
+
+    public String getWord() {
+        return word;
+    }
+
+    public void setWord(String word) {
+        this.word = word;
+    }
+
+    public boolean isUpperCase() {
+        return isUpperCase;
+    }
+
+    public void setUpperCase(boolean upperCase) {
+        isUpperCase = upperCase;
+    }
 }
+
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonResult.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonResult.java
index 16d9e46162c..4beedee2aa2 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonResult.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/JsonResult.java
@@ -16,10 +16,41 @@
  */
 
 package org.apache.ignite.example.serialization;
-
 public class JsonResult {
+    private String originalWord;
+    private String resultWord;
+    private int length;
+
+    public JsonResult() {}
+
+    public JsonResult(String originalWord, String resultWord, int length) {
+        this.originalWord = originalWord;
+        this.resultWord = resultWord;
+        this.length = length;
+    }
+
+    public String getOriginalWord() {
+        return originalWord;
+    }
+
+    public void setOriginalWord(String originalWord) {
+        this.originalWord = originalWord;
+    }
 
-    String originalWord;
-    String resultWord;
-    int length;
+    public String getResultWord() {
+        return resultWord;
+    }
+
+    public void setResultWord(String resultWord) {
+        this.resultWord = resultWord;
+    }
+
+    public int getLength() {
+        return length;
+    }
+
+    public void setLength(int length) {
+        this.length = length;
+    }
 }
+
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/PojoAutoSerializationExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/PojoAutoSerializationExample.java
index 88740e6b06b..7af2982ff23 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/PojoAutoSerializationExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/PojoAutoSerializationExample.java
@@ -36,6 +36,7 @@ public class PojoAutoSerializationExample {
             System.out.println("\n[POJO auto] Running POJO job without custom 
marshallers...");
 
             JobDescriptor<AutoSerializableArg, AutoSerializableResult> job = 
JobDescriptor.builder(PojoAutoSerializationJob.class)
+                    .resultClass(AutoSerializableResult.class)   // REQUIRED
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
                     .build();
 
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/SerializationExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/SerializationExample.java
index 24e67535a10..465f76646ff 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/SerializationExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/SerializationExample.java
@@ -17,19 +17,54 @@
 
 package org.apache.ignite.example.serialization;
 
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
+
 import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.compute.IgniteCompute;
+import org.apache.ignite.example.util.DeployComputeUnit;
+
+/**
+ * This example demonstrates the usage of the {@link 
IgniteCompute#executeAsync} API with various serialization approaches.
+ *
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
+ */
 
 public class SerializationExample {
 
+    private static final String DEPLOYMENT_UNIT_NATIVE = 
"nativeSerializationExampleUnit";
+    private static final String DEPLOYMENT_UNIT_CUSTOM = 
"customPojoSerializationExampleUnit";
+    private static final String DEPLOYMENT_UNIT_AUTO = 
"pojoAutoSerializationExampleUnit";
+    private static final String DEPLOYMENT_UNIT_TUPLE = 
"tupleSerializationExampleUnit";
+    private static final String VERSION = "1.0.0";
+
     public static void main(String[] args) throws Exception {
         try (IgniteClient client = IgniteClient.builder()
                 .addresses("127.0.0.1:10800")
                 .build()) {
 
+            DeployComputeUnit.processDeploymentUnit(args);
+
+            deployIfNotExist(DEPLOYMENT_UNIT_NATIVE, VERSION, 
DeployComputeUnit.getJarPath());
             NativeTypeSerializationExample.runNativeSerialization(client);
+
+            deployIfNotExist(DEPLOYMENT_UNIT_TUPLE, VERSION, 
DeployComputeUnit.getJarPath());
             TupleSerializationExample.runTupleSerialization(client);
+
+            deployIfNotExist(DEPLOYMENT_UNIT_AUTO, VERSION, 
DeployComputeUnit.getJarPath());
             PojoAutoSerializationExample.runPojoAutoSerialization(client);
+
+            deployIfNotExist(DEPLOYMENT_UNIT_CUSTOM, VERSION, 
DeployComputeUnit.getJarPath());
             
CustomPojoSerializationExample.runPojoCustomJsonSerialization(client);
+
+        } finally {
+
+            System.out.println("Cleaning up resources...");
+            undeployUnit(DEPLOYMENT_UNIT_CUSTOM, VERSION);
+            undeployUnit(DEPLOYMENT_UNIT_AUTO, VERSION);
+            undeployUnit(DEPLOYMENT_UNIT_NATIVE, VERSION);
+            undeployUnit(DEPLOYMENT_UNIT_TUPLE, VERSION);
+
         }
     }
 }
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/TupleSerializationExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/TupleSerializationExample.java
index 72639d7274a..72efe0131f1 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/serialization/TupleSerializationExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/serialization/TupleSerializationExample.java
@@ -39,7 +39,10 @@ public class TupleSerializationExample {
 
         Tuple arg = Tuple.create().set("key", "value");
         Tuple res = 
client.compute().execute(JobTarget.anyNode(client.cluster().nodes()), job, arg);
-        System.out.println("[Tuple] Transformed: " + 
res.stringValue("result"));
+
+        System.out.println("Result from job: " + res);
+
+        System.out.println("[Tuple] Transformed: " + res.stringValue("key"));
     }
 }
 
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/DetectFailedEntriesExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/DetectFailedEntriesExample.java
index f340e9704c9..9cfa7cf0057 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/DetectFailedEntriesExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/DetectFailedEntriesExample.java
@@ -35,6 +35,11 @@ public class DetectFailedEntriesExample {
 
     private static final int ACCOUNTS_COUNT = 10;
 
+    /**
+     * Runs the DetectFailedEntriesExample.
+     *
+     * @param arg The command line arguments.
+     */
     public static void main(String[] arg) {
 
         try (IgniteClient client = IgniteClient.builder()
@@ -98,4 +103,4 @@ public class DetectFailedEntriesExample {
             client.sql().execute("DROP TABLE IF EXISTS ACCOUNTS;");
         }
     }
-}
\ No newline at end of file
+}
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/DistributedComputeWithReceiverExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/DistributedComputeWithReceiverExample.java
index 0a349014ca9..b83a18085aa 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/DistributedComputeWithReceiverExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/DistributedComputeWithReceiverExample.java
@@ -18,6 +18,8 @@
 package org.apache.ignite.example.streaming;
 
 import static org.apache.ignite.catalog.definitions.ColumnDefinition.column;
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -30,98 +32,131 @@ import java.util.stream.IntStream;
 import org.apache.ignite.catalog.ColumnType;
 import org.apache.ignite.catalog.definitions.TableDefinition;
 import org.apache.ignite.client.IgniteClient;
+import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 import org.apache.ignite.table.DataStreamerReceiver;
 import org.apache.ignite.table.DataStreamerReceiverContext;
 import org.apache.ignite.table.DataStreamerReceiverDescriptor;
 import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 
-/** This example demonstrates how to use the streaming API to simulate a fraud 
detection process,
- * which typically involves intensive processing of each transaction using ML 
models.
+/**
+ * This example demonstrates how to use the streaming API to simulate a fraud 
detection process, which typically involves intensive
+ * processing of each transaction using ML models.
+ *
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
 
+
 public class DistributedComputeWithReceiverExample {
 
-    public static void main(String[] arg) {
+    private static final String DEPLOYMENT_UNIT_NAME = 
"streamerReceiverExampleUnit";
+
+    /** Deployment unit version. */
+    private static final String DEPLOYMENT_UNIT_VERSION = "1.0.0";
+
+    /**
+     * Runs the DistributedComputeWithReceiverExample.
+     *
+     * @param arg The command line arguments.
+     * @throws Exception if any error occurs.
+     */
+    public static void main(String[] arg) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(arg);
 
         try (IgniteClient client = IgniteClient.builder()
                 .addresses("127.0.0.1:10800")
                 .build()) {
 
-        /* Source data is a list of financial transactions */
-        /* We distribute this processing across the cluster, then gather and 
return results */
-        List<Tuple> sourceData = IntStream.range(1, 10)
-                .mapToObj(i -> Tuple.create()
-                        .set("txId", i)
-                        .set("txData", "{some-json-data}"))
-                .collect(Collectors.toList());
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
+            /* Source data is a list of financial transactions */
+            /* We distribute this processing across the cluster, then gather 
and return results */
+            List<Tuple> sourceData = IntStream.range(1, 10)
+                    .mapToObj(i -> Tuple.create()
+                            .set("txId", i)
+                            .set("txData", "{some-json-data}"))
+                    .collect(Collectors.toList());
 
-        DataStreamerReceiverDescriptor<Tuple, Void, Tuple> desc = 
DataStreamerReceiverDescriptor
-                .builder(FraudDetectorReceiver.class)
-                .build();
+            DataStreamerReceiverDescriptor<Tuple, Void, Tuple> desc = 
DataStreamerReceiverDescriptor
+                    .builder(FraudDetectorReceiver.class)
+                    .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
+                    .build();
 
-        CompletableFuture<Void> streamerFut;
+            CompletableFuture<Void> streamerFut;
 
         /* Streaming requires a target table to partition data.
         /* Use a dummy table for this scenario, because we are not going to 
store any data */
-        TableDefinition txDummyTableDef = TableDefinition.builder("tx_dummy")
-                .columns(column("id", ColumnType.INTEGER))
-                .primaryKey("id")
-                .build();
+            TableDefinition txDummyTableDef = 
TableDefinition.builder("tx_dummy")
+                    .columns(column("id", ColumnType.INTEGER))
+                    .primaryKey("id")
+                    .build();
 
-        Table dummyTable = client.catalog().createTable(txDummyTableDef);
+            Table dummyTable = client.catalog().createTable(txDummyTableDef);
 
-        /* Source data has "txId" field, but target dummy table has "id" 
column, so keyFunc maps "txId" to "id" */
-        Function<Tuple, Tuple> keyFunc = sourceItem -> 
Tuple.create().set("id", sourceItem.value("txId"));
+
+            /* Source data has "txId" field, but target dummy table has "id" 
column, so keyFunc maps "txId" to "id" */
+            Function<Tuple, Tuple> keyFunc = sourceItem -> 
Tuple.create().set("id", sourceItem.value("txId"));
 
         /* Payload function is used to extract the payload (data that goes to 
the receiver) from the source item.
         /* In our case, we want to use the whole source item as the payload */
-        Function<Tuple, Tuple> payloadFunc = Function.identity();
-
-        Flow.Subscriber<Tuple> resultSubscriber = new Flow.Subscriber<>() {
-            @Override
-            public void onSubscribe(Flow.Subscription subscription) {
-                subscription.request(Long.MAX_VALUE);
+            Function<Tuple, Tuple> payloadFunc = Function.identity();
+
+            Flow.Subscriber<Tuple> resultSubscriber = new Flow.Subscriber<>() {
+                @Override
+                public void onSubscribe(Flow.Subscription subscription) {
+                    subscription.request(Long.MAX_VALUE);
+                }
+
+                @Override
+                public void onNext(Tuple item) {
+                    System.out.println("Transaction processed: " + item);
+                }
+
+                @Override
+                public void onError(Throwable throwable) {
+                    System.err.println("Error during streaming: " + 
throwable.getMessage());
+                }
+
+                @Override
+                public void onComplete() {
+                    System.out.println("Streaming completed.");
+                }
+            };
+
+            try (var publisher = new SubmissionPublisher<Tuple>()) {
+                streamerFut = dummyTable.recordView().streamData(
+                        publisher,
+                        desc,
+                        keyFunc,
+                        payloadFunc,
+                        null, /* Optional Receiver arguments*/
+                        resultSubscriber,
+                        null /* DataStreamer options */
+                );
+
+                for (Tuple item : sourceData) {
+                    publisher.submit(item);
+                }
             }
 
-            @Override
-            public void onNext(Tuple item) {
-                System.out.println("Transaction processed: " + item);
-            }
+            streamerFut.join();
 
-            @Override
-            public void onError(Throwable throwable) {
-                System.err.println("Error during streaming: " + 
throwable.getMessage());
-            }
+            System.out.println("Cleaning up resources");
 
-            @Override
-            public void onComplete() {
-                System.out.println("Streaming completed.");
-            }
-        };
-
-        try (var publisher = new SubmissionPublisher<Tuple>()) {
-            streamerFut = dummyTable.recordView().streamData(
-                    publisher,
-                    desc,
-                    keyFunc,
-                    payloadFunc,
-                    null, /* Optional Receiver arguments*/
-                    resultSubscriber,
-                    null /* DataStreamer options */
-            );
-
-            for (Tuple item : sourceData) {
-                publisher.submit(item);
-            }
+            /* Drop table */
+            System.out.println("\nDropping the table...");
+            client.sql().executeScript("DROP TABLE IF EXISTS tx_dummy");
+        } finally {
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
         }
-
-        streamerFut.join();
     }
-}
-
 
-    private static class FraudDetectorReceiver implements 
DataStreamerReceiver<Tuple, Void, Tuple> {
+    /**
+     * Receiver that processes transactions and detects potential fraud.
+     */
+    public static class FraudDetectorReceiver implements 
DataStreamerReceiver<Tuple, Void, Tuple> {
         @Override
         public CompletableFuture<List<Tuple>> receive(List<Tuple> page, 
DataStreamerReceiverContext ctx, Void arg) {
             List<Tuple> results = new ArrayList<>(page.size());
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/MultiTableDataStreamerExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/MultiTableDataStreamerExample.java
index 474e3c1cf52..7d774889cc8 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/MultiTableDataStreamerExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/MultiTableDataStreamerExample.java
@@ -17,6 +17,9 @@
 
 package org.apache.ignite.example.streaming;
 
+import static 
org.apache.ignite.example.util.DeployComputeUnit.deployIfNotExist;
+import static org.apache.ignite.example.util.DeployComputeUnit.undeployUnit;
+
 import java.util.List;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.SubmissionPublisher;
@@ -25,29 +28,67 @@ import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.deployment.DeploymentUnit;
+import org.apache.ignite.example.util.DeployComputeUnit;
 import org.apache.ignite.table.DataStreamerReceiverDescriptor;
 import org.apache.ignite.table.RecordView;
 import org.apache.ignite.table.Tuple;
 
 /**
- * This example demonstrates how to use the streaming API to how to implement 
a receiver that processes data containing customer and address information,
- * and updates two separate tables on the server.
+ * This example demonstrates how to use the streaming API to implement a 
receiver that processes data containing customer and address
+ * information, and updates two separate tables on the server.
+ *
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
  */
 
+
 public class MultiTableDataStreamerExample {
 
-    /** Deployment unit name. */
     private static final String DEPLOYMENT_UNIT_NAME = 
"streamerReceiverExampleUnit";
 
     /** Deployment unit version. */
     private static final String DEPLOYMENT_UNIT_VERSION = "1.0.0";
 
-    public static void main(String[] arg) {
+    /**
+     * Runs the MultiTableDataStreamerExample.
+     *
+     * @param arg The command line arguments.
+     * @throws Exception if any error occurs.
+     */
+    public static void main(String[] arg) throws Exception {
+
+        DeployComputeUnit.processDeploymentUnit(arg);
 
         try (IgniteClient client = IgniteClient.builder()
                 .addresses("127.0.0.1:10800")
                 .build()) {
 
+            deployIfNotExist(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION, 
DeployComputeUnit.getJarPath());
+
+            /* Create tables using client SQL API */
+            client.sql().executeScript(
+                    "CREATE TABLE IF NOT EXISTS Customers ("
+                            + "id INT PRIMARY KEY,"
+                            + "name VARCHAR(255),"
+                            + "addressId INT"
+                            + ")"
+            );
+
+            client.sql().executeScript(
+                    "CREATE TABLE IF NOT EXISTS Addresses ("
+                            + "id INT PRIMARY KEY,"
+                            + "street VARCHAR(255),"
+                            + "city VARCHAR(255)"
+                            + ")"
+            );
+
+            client.sql().executeScript("INSERT INTO Addresses (id, street, 
city) VALUES (1, '123 Elm Street', 'Springfield')");
+            client.sql().executeScript("INSERT INTO Addresses (id, street, 
city) VALUES (2, '456 Oak Avenue', 'Shelbyville')");
+            client.sql().executeScript("INSERT INTO Addresses (id, street, 
city) VALUES (3, '789 Pine Road', 'Capitol City')");
+
+            client.sql().executeScript("INSERT INTO Customers (id, name, 
addressId) VALUES (1, 'John Doe', 1)");
+            client.sql().executeScript("INSERT INTO Customers (id, name, 
addressId) VALUES (2, 'Jane Smith', 2)");
+            client.sql().executeScript("INSERT INTO Customers (id, name, 
addressId) VALUES (3, 'Robert Johnson', 3)");
+
             DataStreamerReceiverDescriptor<Tuple, Void, Tuple> desc = 
DataStreamerReceiverDescriptor
                     .builder(TwoTableReceiver.class)
                     .units(new DeploymentUnit(DEPLOYMENT_UNIT_NAME, 
DEPLOYMENT_UNIT_VERSION))
@@ -91,6 +132,14 @@ public class MultiTableDataStreamerExample {
             }
 
             streamerFut.join();
+
+            // Drop tables
+            System.out.println("\nDropping the tables...");
+            client.sql().executeScript("DROP TABLE IF EXISTS Customers");
+            client.sql().executeScript("DROP TABLE IF EXISTS Addresses");
+        } finally {
+            System.out.println("Cleaning up resources");
+            undeployUnit(DEPLOYMENT_UNIT_NAME, DEPLOYMENT_UNIT_VERSION);
         }
     }
 }
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/SingleTableDataStreamerExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/SingleTableDataStreamerExample.java
index ec21305435f..819386016f8 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/streaming/SingleTableDataStreamerExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/streaming/SingleTableDataStreamerExample.java
@@ -36,7 +36,11 @@ public class SingleTableDataStreamerExample {
 
     private static final int ACCOUNTS_COUNT = 10;
 
-    /* Assuming table Accounts exists */
+    /**
+     * Runs the SingleTableDataStreamerExample.
+     *
+     * @param arg The command line arguments.
+     */
     public static void main(String[] arg) {
 
         try (IgniteClient client = IgniteClient.builder()
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java
index c6c7743fe66..75caedf41a6 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewExample.java
@@ -25,7 +25,7 @@ import org.apache.ignite.table.KeyValueView;
 import org.apache.ignite.table.Tuple;
 
 /**
- * This example demonstrates the usage of the {@link KeyValueView} API.
+ * This example demonstrates the usage of the { @link KeyValueView} API.
  *
  * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
  */
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewPojoExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewPojoExample.java
index ec470876e3f..d3f842902a3 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewPojoExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/table/KeyValueViewPojoExample.java
@@ -24,7 +24,7 @@ import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.table.KeyValueView;
 
 /**
- * This example demonstrates the usage of the {@link KeyValueView} API with 
user-defined POJOs.
+ * This example demonstrates the usage of the { @link KeyValueView} API with 
user-defined POJOs.
  *
  * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
  */
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/table/QueryExample.java 
b/examples/java/src/main/java/org/apache/ignite/example/table/QueryExample.java
index 8b0ba488c92..cc33c675c90 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/table/QueryExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/table/QueryExample.java
@@ -63,6 +63,8 @@ public class QueryExample {
 
     /**
      * Demonstrates querying with an implicit transaction.
+     *
+     * @param table  Table instance to query.
      */
     public static void performQueryWithoutTransaction(Table table) {
         System.out.println("[ Example 1 ] Performing query without 
transaction");
@@ -85,6 +87,9 @@ public class QueryExample {
 
     /**
      * Demonstrates querying with an explicit transaction.
+     *
+     * @param client Ignite client used to start the transaction.
+     * @param table  Table instance to query.
      */
     public static void performQueryWithTransaction(IgniteClient client, Table 
table) {
         System.out.println("[ Example 2 ] Performing query with transaction");
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewExample.java
index af1d275e7ec..4c14b22d2d8 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewExample.java
@@ -25,7 +25,7 @@ import org.apache.ignite.table.RecordView;
 import org.apache.ignite.table.Tuple;
 
 /**
- * This example demonstrates the usage of the {@link RecordView} API.
+ * This example demonstrates the usage of the { @link RecordView} API.
  *
  * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
  */
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewPojoExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewPojoExample.java
index 5d5a1d95ccf..8e8a3f9f4d2 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewPojoExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/table/RecordViewPojoExample.java
@@ -24,7 +24,7 @@ import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.table.RecordView;
 
 /**
- * This example demonstrates the usage of the {@link RecordView} API with 
user-defined POJOs.
+ * This example demonstrates the usage of the { @link RecordView} API with 
user-defined POJOs.
  *
  * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
  */
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/table/TableExample.java 
b/examples/java/src/main/java/org/apache/ignite/example/table/TableExample.java
index 6fe326eedd3..e3c9e74c36d 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/table/TableExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/table/TableExample.java
@@ -26,7 +26,7 @@ import org.apache.ignite.table.Table;
 import org.apache.ignite.table.Tuple;
 
 /**
- * This example demonstrates the usage of the {@link KeyValueView} API.
+ * This example demonstrates the usage of the { @link KeyValueView} API.
  *
  * <p>Find instructions on how to run the example in the README.md file 
located in the "examples" directory root.
  */
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/tx/TransactionsExample.java
 
b/examples/java/src/main/java/org/apache/ignite/example/tx/TransactionsExample.java
index 7bc26440ed7..e940902bbba 100644
--- 
a/examples/java/src/main/java/org/apache/ignite/example/tx/TransactionsExample.java
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/tx/TransactionsExample.java
@@ -25,9 +25,19 @@ import java.util.concurrent.CompletableFuture;
 import org.apache.ignite.client.IgniteClient;
 import org.apache.ignite.table.KeyValueView;
 
-/* This example demonstrates the usage of the Ignite Transactions API */
+/**
+ * This example demonstrates the usage of the Ignite Transactions API.
+ *
+ * <p>See {@code README.md} in the {@code examples} directory for execution 
instructions.</p>
+ */
 public class TransactionsExample {
 
+    /**
+     * Runs the TransactionsExample.
+     *
+     * @param args The command line arguments.
+     * @throws Exception if any error occurs.
+     */
     public static void main(String[] args) throws Exception {
 
         /* Create 'accounts' table via JDBC */
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/util/DeployComputeUnit.java
 
b/examples/java/src/main/java/org/apache/ignite/example/util/DeployComputeUnit.java
new file mode 100644
index 00000000000..25601f913cf
--- /dev/null
+++ 
b/examples/java/src/main/java/org/apache/ignite/example/util/DeployComputeUnit.java
@@ -0,0 +1,367 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.example.util;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static java.util.concurrent.TimeUnit.SECONDS;
+import static org.awaitility.Awaitility.await;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.IOException;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+/**
+ * Utility class for deploying Ignite compute units.
+ * <p>
+ * Note: The deployment unit JAR is now built at compile time via the 
deploymentUnitJar Gradle task,
+ * not at runtime. This eliminates the need for runtime JAR building.
+ * </p>
+ */
+public class DeployComputeUnit {
+
+    // Root path of the project.
+    private static final Path PROJECT_ROOT = Paths.get("").toAbsolutePath();
+
+    // Pre-built JAR from deploymentUnitJar task (built at compile time).
+    private static final Path DEFAULT_JAR_PATH =
+            
PROJECT_ROOT.resolve("examples/java/build/libs/deploymentunit-example-1.0.0.jar");
+
+    private static String jarPathAsString = "";
+    private static Path jarPath = DEFAULT_JAR_PATH;
+    private static boolean runFromIDE = true;
+
+    /**
+     * Returns the JAR path as a string.
+     *
+     * @return JAR path as string.
+     */
+    public static String getJarPathAsString() {
+        return jarPathAsString;
+    }
+
+    /**
+     * Returns the path to the deployment unit JAR.
+     *
+     * @return Path to the JAR file.
+     */
+    public static Path getJarPath() {
+        return jarPath;
+    }
+
+    /**
+     * Returns whether the example is running from an IDE.
+     *
+     * @return True if running from IDE.
+     */
+    public static boolean isRunFromIDE() {
+        return runFromIDE;
+    }
+
+    /**
+     * Class containing deployment arguments parsed from command line.
+     */
+    public static final class DeploymentArgs {
+        private final boolean runFromIDE;
+        private final String jarPath;
+
+        /**
+         * Creates deployment arguments.
+         *
+         * @param runFromIDE Whether the example runs from an IDE.
+         * @param jarPath Path to external JAR when run outside IDE (may be 
null).
+         */
+        public DeploymentArgs(boolean runFromIDE, String jarPath) {
+            this.runFromIDE = runFromIDE;
+            this.jarPath = jarPath;
+        }
+
+        /**
+         * Returns whether the example runs from an IDE.
+         *
+         * @return True if running from IDE.
+         */
+        public boolean runFromIDE() {
+            return runFromIDE;
+        }
+
+        /**
+         * Returns the path to external JAR when run outside IDE.
+         *
+         * @return JAR path or null.
+         */
+        public String jarPath() {
+            return jarPath;
+        }
+    }
+
+    private static final String BASE_URL = "http://localhost:10300";;
+    private static final HttpClient HTTP = HttpClient.newHttpClient();
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+    private static final int DEPLOYMENT_TIMEOUT_SECONDS = 30;
+
+
+    /**
+     * Checks if a deployment unit already exists on the cluster with DEPLOYED 
status.
+     *
+     * @param unitId Deployment unit ID.
+     * @param version Deployment version.
+     * @return True if deployment exists with DEPLOYED status.
+     * @throws Exception If request fails.
+     */
+    private static boolean isDeployed(String unitId, String version) throws 
Exception {
+        HttpRequest req = HttpRequest.newBuilder()
+                .uri(new URI(BASE_URL + 
"/management/v1/deployment/cluster/units/" + unitId))
+                .GET()
+                .build();
+
+        HttpResponse<String> resp = HTTP.send(req, 
HttpResponse.BodyHandlers.ofString());
+
+        if (resp.statusCode() == 404) {
+            // Unit doesn't exist yet
+            return false;
+        }
+
+        if (resp.statusCode() != 200) {
+            throw new RuntimeException("Failed to check deployment status. 
HTTP " + resp.statusCode() + ": " + resp.body());
+        }
+
+        // Parse JSON response - the API returns a Collection<UnitStatus>
+        JsonNode root = OBJECT_MAPPER.readTree(resp.body());
+
+        // Handle empty response (unit exists but no matching status)
+        if (root.isArray() && root.isEmpty()) {
+            return false;
+        }
+
+        // The response is an array of UnitStatus objects
+        if (!root.isArray()) {
+            throw new RuntimeException("Unexpected response format. Expected 
array, got: " + root);
+        }
+
+        // Check if any node has this version deployed
+        for (JsonNode unitStatus : root) {
+            JsonNode versionToStatus = unitStatus.path("versionToStatus");
+
+            if (versionToStatus.isArray()) {
+                for (JsonNode versionStatus : versionToStatus) {
+                    String versionValue = 
versionStatus.path("version").asText();
+                    String statusValue = versionStatus.path("status").asText();
+
+                    if (version.equals(versionValue) && 
"DEPLOYED".equals(statusValue)) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Checks if a deployment unit exists (in any state).
+     *
+     * @param unitId Deployment unit ID.
+     * @param version Deployment version.
+     * @return True if deployment exists.
+     * @throws Exception If request fails.
+     */
+    private static boolean deploymentExists(String unitId, String version) 
throws Exception {
+        HttpRequest req = HttpRequest.newBuilder()
+                .uri(new URI(BASE_URL + 
"/management/v1/deployment/cluster/units/" + unitId))
+                .GET()
+                .build();
+
+        HttpResponse<String> resp = HTTP.send(req, 
HttpResponse.BodyHandlers.ofString());
+        return resp.statusCode() == 200 && 
resp.body().contains("\"version\":\"" + version + "\"");
+    }
+
+    /**
+     * Deploys a unit to the Ignite cluster and waits for it to reach DEPLOYED 
status.
+     *
+     * @param unitId Deployment unit ID.
+     * @param version Deployment version.
+     * @param jar Path to the JAR file to upload.
+     * @throws Exception If deployment fails.
+     */
+    private static void deployUnit(String unitId, String version, Path jar) 
throws Exception {
+        String boundary = "igniteBoundary";
+
+        byte[] jarBytes = Files.readAllBytes(jar);
+
+        String start =
+                "--" + boundary + "\r\n" +
+                        "Content-Disposition: form-data; name=\"unitContent\"; 
filename=\"" + jar.getFileName() + "\"\r\n" +
+                        "Content-Type: application/java-archive\r\n\r\n";
+
+        String end = "\r\n--" + boundary + "--\r\n";
+
+        byte[] startBytes = start.getBytes();
+        byte[] endBytes = end.getBytes();
+
+        byte[] full = new byte[startBytes.length + jarBytes.length + 
endBytes.length];
+
+        System.arraycopy(startBytes, 0, full, 0, startBytes.length);
+        System.arraycopy(jarBytes, 0, full, startBytes.length, 
jarBytes.length);
+        System.arraycopy(endBytes, 0, full, startBytes.length + 
jarBytes.length, endBytes.length);
+
+        HttpRequest req = HttpRequest.newBuilder()
+                .uri(new URI(BASE_URL + "/management/v1/deployment/units/" + 
unitId + "/" + version + "?deployMode=ALL"))
+                .header("Content-Type", "multipart/form-data; boundary=" + 
boundary)
+                .POST(HttpRequest.BodyPublishers.ofByteArray(full))
+                .build();
+
+        HttpResponse<String> resp = HTTP.send(req, 
HttpResponse.BodyHandlers.ofString());
+
+        if (resp.statusCode() != 200 && resp.statusCode() != 409) {
+            throw new RuntimeException("Deployment failed: " + 
resp.statusCode() + "\n" + resp.body());
+        }
+
+        // Wait for deployment to reach DEPLOYED status using polling
+        await()
+                .atMost(DEPLOYMENT_TIMEOUT_SECONDS, SECONDS)
+                .pollInterval(200, MILLISECONDS)
+                .until(() -> isDeployed(unitId, version));
+    }
+
+    /**
+     * Undeploys the given deployment unit from the cluster and waits for it 
to be removed.
+     *
+     * @param unitId Deployment unit ID.
+     * @param version Deployment version.
+     * @throws Exception If undeployment fails.
+     */
+    public static void undeployUnit(String unitId, String version) throws 
Exception {
+        HttpRequest req = HttpRequest.newBuilder()
+                .uri(new URI(BASE_URL + "/management/v1/deployment/units/" + 
unitId + "/" + version))
+                .DELETE()
+                .build();
+
+        HttpResponse<String> resp = HTTP.send(req, 
HttpResponse.BodyHandlers.ofString());
+
+        if (resp.statusCode() != 200 && resp.statusCode() != 404) {
+            throw new RuntimeException("Undeploy failed: " + resp.statusCode() 
+ "\n" + resp.body());
+        }
+
+        // Wait for deployment to be removed using polling
+        await()
+                .atMost(DEPLOYMENT_TIMEOUT_SECONDS, SECONDS)
+                .pollInterval(200, MILLISECONDS)
+                .until(() -> !deploymentExists(unitId, version));
+
+        System.out.println("Unit successfully undeployed.");
+    }
+
+    /**
+     * Processes command-line arguments for:
+     * <ul>
+     *   <li><b>runFromIDE</b> – whether the example runs from source</li>
+     *   <li><b>jarPath</b> – path to external JAR when run outside IDE</li>
+     * </ul>
+     *
+     * @param args Command-line arguments (may be null).
+     * @return DeploymentArgs record with runFromIDE and jarPath fields.
+     */
+    public static DeploymentArgs processArguments(String[] args) {
+        boolean runFromIDE = true;
+        String jarPath = null;
+
+        if (args == null) {
+            return new DeploymentArgs(runFromIDE, jarPath);
+        }
+
+        for (String arg : args) {
+
+            if (arg.contains("runFromIDE")) {
+                String[] splitArgArr = arg.split("=");
+                if (splitArgArr.length == 2) {
+                    runFromIDE = Boolean.parseBoolean(splitArgArr[1]);
+                } else {
+                    throw new RuntimeException(" 'runFromIDE' argument not 
specified in the required format ");
+                }
+            }
+
+            if (arg.contains("jarPath")) {
+                String[] splitArgArr = arg.split("=");
+                if (splitArgArr.length == 2) {
+                    jarPath = splitArgArr[1];
+                } else {
+                    throw new RuntimeException(" 'jarPath' argument not 
specified in the required format ");
+                }
+            }
+        }
+
+        return new DeploymentArgs(runFromIDE, jarPath);
+    }
+
+    /**
+     * Checks if a deployment unit exists with DEPLOYED status. If it does not 
exist or is not deployed,
+     * deploys the unit and waits for it to reach DEPLOYED status.
+     *
+     * <p>The method uses polling to check the deployment status periodically 
until it reaches DEPLOYED state.
+     * If the unit is already deployed, it skips the deployment process.</p>
+     *
+     * @param deploymentUnitName The name of the deployment unit to check and 
deploy.
+     * @param deploymentUnitVersion The version of the deployment unit to 
check and deploy.
+     * @param jarPath The file path to the JAR file that will be used for 
deployment, if necessary.
+     * @throws Exception If an error occurs during the deployment process, 
such as a failure to deploy the unit.
+     */
+    public static void deployIfNotExist(String deploymentUnitName, String 
deploymentUnitVersion, Path jarPath) throws Exception {
+        if (isDeployed(deploymentUnitName, deploymentUnitVersion)) {
+            System.out.println("Deployment unit already deployed. Skip 
deploy.");
+        } else {
+            System.out.println("Deployment unit not found or not in DEPLOYED 
state. Deploying...");
+            deployUnit(deploymentUnitName, deploymentUnitVersion, jarPath);
+            System.out.println("Deployment completed: " + deploymentUnitName + 
" version " + deploymentUnitVersion + " is DEPLOYED.");
+        }
+    }
+
+    /**
+     * Processes the deployment unit by parsing command-line arguments and 
verifying the JAR exists.
+     *
+     * @param args Arguments passed to the deployment process.
+     * @throws IOException if JAR file is not found.
+     */
+    public static void processDeploymentUnit(String[] args) throws IOException 
{
+        DeploymentArgs deploymentArgs = processArguments(args);
+
+        runFromIDE = deploymentArgs.runFromIDE();
+        String newJarPathStr = deploymentArgs.jarPath();
+
+        // Use isBlank() instead of trim().isEmpty() to avoid creating a new 
String
+        if (newJarPathStr != null && !newJarPathStr.isBlank()) {
+            jarPathAsString = newJarPathStr;
+            jarPath = Path.of(newJarPathStr);
+        }
+
+        // JAR is pre-built at compile time via deploymentUnitJar task
+        // No runtime JAR building needed - just verify it exists
+        if (!Files.exists(jarPath)) {
+            throw new IllegalStateException(
+                "Deployment unit JAR not found at: " + jarPath + "\n"
+                + "Please build the project first: ./gradlew 
:ignite-examples:build"
+            );
+        }
+    }
+}
diff --git 
a/examples/java/src/main/java/org/apache/ignite/example/code/deployment/resources/script.sh
 
b/examples/java/src/main/resources/org/apache/ignite/example/code/deployment/resources/script.sh
similarity index 100%
rename from 
examples/java/src/main/java/org/apache/ignite/example/code/deployment/resources/script.sh
rename to 
examples/java/src/main/resources/org/apache/ignite/example/code/deployment/resources/script.sh

Reply via email to