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

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

commit 92382d45c8c0fd9b0f706222884662eb31c24645
Author: Pochatkin Mikhail <[email protected]>
AuthorDate: Wed Nov 26 14:05:40 2025 +0300

    IGNITE-26536 Extract code deployment class loader to separate module
---
 modules/client/build.gradle                        |  1 +
 .../apache/ignite/client/fakes/FakeCompute.java    |  4 +--
 .../build.gradle}                                  | 37 ++++++++--------------
 .../deployunit/loader/UnitsClassLoader.java}       | 22 ++++++-------
 .../loader/UnitsClassLoaderFactory.java}           |  8 ++---
 .../deployunit/loader/UnitsClassLoaderImpl.java}   |  8 ++---
 .../deployunit/loader/UnitsClasspath.java}         |  4 +--
 .../internal/deployunit/loader/UnitsContext.java}  | 12 +++----
 .../deployunit/loader/UnitsContextManager.java}    | 28 ++++++++--------
 .../loader/JobClassLoaderFactoryTest.java          | 22 ++++++-------
 .../deployunit}/loader/JobClassLoaderTest.java     |  8 ++---
 .../deployunit}/loader/JobContextManagerTest.java  | 26 +++++++--------
 .../deployunit}/util/DummyIgniteDeployment.java    |  2 +-
 .../resources/units/unit1/5.0.0/subdir/test.txt    |  0
 .../src/test/resources/units/unit1/5.0.0/test.txt  |  0
 modules/compute/build.gradle                       |  1 +
 .../compute/ClassLoaderExceptionsMapper.java       |  6 ++--
 .../internal/compute/ComputeComponentImpl.java     | 14 ++++----
 .../ignite/internal/compute/ComputeUtils.java      |  6 ++--
 .../internal/compute/JobExecutionContextImpl.java  |  8 ++---
 .../internal/compute/executor/ComputeExecutor.java |  6 ++--
 .../compute/executor/ComputeExecutorImpl.java      | 10 +++---
 .../internal/compute/ComputeComponentImplTest.java | 12 +++----
 .../compute/executor/ComputeExecutorTest.java      |  4 +--
 modules/runner/build.gradle                        |  1 +
 .../org/apache/ignite/internal/app/IgniteImpl.java |  6 ++--
 settings.gradle                                    |  2 ++
 27 files changed, 127 insertions(+), 131 deletions(-)

diff --git a/modules/client/build.gradle b/modules/client/build.gradle
index 0a1067fac6f..f0c84698d23 100644
--- a/modules/client/build.gradle
+++ b/modules/client/build.gradle
@@ -57,6 +57,7 @@ dependencies {
     testImplementation project(':ignite-cluster-management')
     testImplementation project(':ignite-compute')
     testImplementation project(':ignite-code-deployment')
+    testImplementation project(':ignite-code-deployment-classloader')
     testImplementation project(':ignite-eventlog')
     testImplementation testFixtures(project(':ignite-api'))
     testImplementation testFixtures(project(':ignite-core'))
diff --git 
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCompute.java 
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCompute.java
index 5df6d81b043..fa5060dccb3 100644
--- 
a/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCompute.java
+++ 
b/modules/client/src/test/java/org/apache/ignite/client/fakes/FakeCompute.java
@@ -68,7 +68,7 @@ import org.apache.ignite.internal.compute.SharedComputeUtils;
 import org.apache.ignite.internal.compute.TaskStateImpl;
 import org.apache.ignite.internal.compute.events.ComputeEventMetadata;
 import org.apache.ignite.internal.compute.events.ComputeEventMetadataBuilder;
-import org.apache.ignite.internal.compute.loader.JobClassLoader;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoader;
 import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.network.ClusterNodeImpl;
 import org.apache.ignite.internal.network.InternalClusterNode;
@@ -132,7 +132,7 @@ public class FakeCompute implements IgniteComputeInternal {
         }
 
         if (jobClassName.startsWith("org.apache.ignite")) {
-            JobClassLoader jobClassLoader = new JobClassLoader(List.of(), 
this.getClass().getClassLoader());
+            UnitsClassLoader jobClassLoader = new UnitsClassLoader(List.of(), 
this.getClass().getClassLoader());
             Class<ComputeJob<Object, Object>> jobClass = 
ComputeUtils.jobClass(jobClassLoader, jobClassName);
             ComputeJob<Object, Object> job = 
ComputeUtils.instantiateJob(jobClass);
             CompletableFuture<Object> jobFut = job.executeAsync(
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContext.java
 b/modules/code-deployment-classloader/build.gradle
similarity index 55%
copy from 
modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContext.java
copy to modules/code-deployment-classloader/build.gradle
index a01684bdc0f..16ebb0d6ffc 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContext.java
+++ b/modules/code-deployment-classloader/build.gradle
@@ -15,30 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+apply from: "$rootDir/buildscripts/java-core.gradle"
+apply from: "$rootDir/buildscripts/java-integration-test.gradle"
+apply from: "$rootDir/buildscripts/publishing.gradle"
+apply from: "$rootDir/buildscripts/java-junit5.gradle"
+apply from: "$rootDir/buildscripts/java-test-fixtures.gradle"
 
-import java.util.function.Consumer;
+description = 'ignite-code-deployment-classloader'
 
-/**
- * Job context.
- */
-public class JobContext implements AutoCloseable {
-
-    private final JobClassLoader classLoader;
-
-    private final Consumer<JobContext> onClose;
-
-    public JobContext(JobClassLoader classLoader, Consumer<JobContext> 
onClose) {
-        this.classLoader = classLoader;
-        this.onClose = onClose;
-    }
+dependencies {
+    implementation libs.jetbrains.annotations
 
-    public JobClassLoader classLoader() {
-        return classLoader;
-    }
+    implementation project(':ignite-core')
+    implementation project(':ignite-api')
+    implementation project(':ignite-code-deployment')
 
-    @Override
-    public void close() {
-        onClose.accept(this);
-    }
-}
+    testImplementation project(':ignite-core')
+    testImplementation testFixtures(project(':ignite-core'))
+}
\ No newline at end of file
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoader.java
 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoader.java
similarity index 82%
rename from 
modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoader.java
rename to 
modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoader.java
index 8de3e65e462..46871c2943c 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoader.java
+++ 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoader.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import java.net.URL;
 import java.security.AccessController;
@@ -32,22 +32,22 @@ import org.apache.ignite.lang.IgniteException;
 /**
  * Implementation of {@link ClassLoader} that loads classes from specified 
component directories.
  */
-public class JobClassLoader implements AutoCloseable {
-    private static final IgniteLogger LOG = 
Loggers.forClass(JobClassLoader.class);
+public class UnitsClassLoader implements AutoCloseable {
+    private static final IgniteLogger LOG = 
Loggers.forClass(UnitsClassLoader.class);
 
     private final List<DisposableDeploymentUnit> units;
 
     private final ClassLoader parent;
 
-    private volatile JobClassLoaderImpl impl;
+    private volatile UnitsClassLoaderImpl impl;
 
     /**
-     * Creates new instance of {@link JobClassLoader}.
+     * Creates new instance of {@link UnitsClassLoader}.
      *
      * @param units Units to load classes from.
      * @param parent Parent class loader.
      */
-    public JobClassLoader(List<DisposableDeploymentUnit> units, ClassLoader 
parent) {
+    public UnitsClassLoader(List<DisposableDeploymentUnit> units, ClassLoader 
parent) {
         this.units = units;
         this.parent = parent;
     }
@@ -77,18 +77,18 @@ public class JobClassLoader implements AutoCloseable {
         return impl;
     }
 
-    private JobClassLoaderImpl createClassLoader() {
-        return 
AccessController.doPrivileged((PrivilegedAction<JobClassLoaderImpl>) () -> {
+    private UnitsClassLoaderImpl createClassLoader() {
+        return 
AccessController.doPrivileged((PrivilegedAction<UnitsClassLoaderImpl>) () -> {
             URL[] classpath = units.stream()
                     .map(DisposableDeploymentUnit::path)
-                    .flatMap(JobClasspath::collectClasspath)
+                    .flatMap(UnitsClasspath::collectClasspath)
                     .toArray(URL[]::new);
 
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Created class loader with classpath: {}", 
Arrays.toString(classpath));
             }
 
-            return new JobClassLoaderImpl(units, classpath, parent);
+            return new UnitsClassLoaderImpl(units, classpath, parent);
         });
     }
 
@@ -105,7 +105,7 @@ public class JobClassLoader implements AutoCloseable {
         }
 
         try {
-            JobClassLoaderImpl impl0 = impl;
+            UnitsClassLoaderImpl impl0 = impl;
 
             if (impl0 != null) {
                 impl0.close();
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoaderFactory.java
 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoaderFactory.java
similarity index 81%
rename from 
modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoaderFactory.java
rename to 
modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoaderFactory.java
index bb277dffbff..ecf821dbf11 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoaderFactory.java
+++ 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoaderFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import java.util.List;
 import org.apache.ignite.internal.deployunit.DisposableDeploymentUnit;
@@ -23,14 +23,14 @@ import 
org.apache.ignite.internal.deployunit.DisposableDeploymentUnit;
 /**
  * Creates a class loader for a job.
  */
-public class JobClassLoaderFactory {
+public class UnitsClassLoaderFactory {
     /**
      * Create a class loader for the specified units.
      *
      * @param units The units of the job.
      * @return The class loader.
      */
-    public JobClassLoader createClassLoader(List<DisposableDeploymentUnit> 
units) {
-        return new JobClassLoader(units, getClass().getClassLoader());
+    public UnitsClassLoader createClassLoader(List<DisposableDeploymentUnit> 
units) {
+        return new UnitsClassLoader(units, getClass().getClassLoader());
     }
 }
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoaderImpl.java
 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoaderImpl.java
similarity index 93%
rename from 
modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoaderImpl.java
rename to 
modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoaderImpl.java
index 0bd1db89b09..f3ee2b4f4fd 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClassLoaderImpl.java
+++ 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClassLoaderImpl.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import java.net.URL;
 import java.net.URLClassLoader;
@@ -24,7 +24,7 @@ import java.util.List;
 import java.util.regex.Pattern;
 import org.apache.ignite.internal.deployunit.DisposableDeploymentUnit;
 
-class JobClassLoaderImpl extends URLClassLoader {
+class UnitsClassLoaderImpl extends URLClassLoader {
     /**
      * Pattern to match system packages.
      */
@@ -38,13 +38,13 @@ class JobClassLoaderImpl extends URLClassLoader {
     private final ClassLoader parent;
 
     /**
-     * Creates new instance of {@link JobClassLoader}.
+     * Creates new instance of {@link UnitsClassLoader}.
      *
      * @param urls URLs to load classes from.
      * @param units Units to load classes from.
      * @param parent Parent class loader.
      */
-    JobClassLoaderImpl(List<DisposableDeploymentUnit> units, URL[] urls, 
ClassLoader parent) {
+    public UnitsClassLoaderImpl(List<DisposableDeploymentUnit> units, URL[] 
urls, ClassLoader parent) {
         super("compute-job", urls, parent);
         this.units = units;
         this.parent = parent;
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClasspath.java
 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClasspath.java
similarity index 97%
rename from 
modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClasspath.java
rename to 
modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClasspath.java
index ec909fe33d0..31f283e5606 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobClasspath.java
+++ 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsClasspath.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import java.io.IOException;
 import java.net.MalformedURLException;
@@ -31,7 +31,7 @@ import java.util.stream.Stream;
 import org.apache.ignite.compute.ComputeException;
 import org.apache.ignite.lang.ErrorGroups.Compute;
 
-class JobClasspath {
+class UnitsClasspath {
     static Stream<URL> collectClasspath(Path unitDir) {
         if (Files.notExists(unitDir)) {
             throw new IllegalArgumentException("Unit does not exist: " + 
unitDir);
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContext.java
 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsContext.java
similarity index 75%
rename from 
modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContext.java
rename to 
modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsContext.java
index a01684bdc0f..e96045a9e79 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContext.java
+++ 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsContext.java
@@ -15,25 +15,25 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import java.util.function.Consumer;
 
 /**
  * Job context.
  */
-public class JobContext implements AutoCloseable {
+public class UnitsContext implements AutoCloseable {
 
-    private final JobClassLoader classLoader;
+    private final UnitsClassLoader classLoader;
 
-    private final Consumer<JobContext> onClose;
+    private final Consumer<UnitsContext> onClose;
 
-    public JobContext(JobClassLoader classLoader, Consumer<JobContext> 
onClose) {
+    public UnitsContext(UnitsClassLoader classLoader, Consumer<UnitsContext> 
onClose) {
         this.classLoader = classLoader;
         this.onClose = onClose;
     }
 
-    public JobClassLoader classLoader() {
+    public UnitsClassLoader classLoader() {
         return classLoader;
     }
 
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContextManager.java
 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsContextManager.java
similarity index 89%
rename from 
modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContextManager.java
rename to 
modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsContextManager.java
index 2cd5b32e1df..081a971f910 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/loader/JobContextManager.java
+++ 
b/modules/code-deployment-classloader/src/main/java/org/apache/ignite/internal/deployunit/loader/UnitsContextManager.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static java.util.concurrent.CompletableFuture.failedFuture;
@@ -43,10 +43,10 @@ import org.apache.ignite.lang.ErrorGroups.Compute;
 /**
  * Manages job context.
  */
-public class JobContextManager {
-    private static final IgniteLogger LOG = 
Loggers.forClass(JobContextManager.class);
+public class UnitsContextManager {
+    private static final IgniteLogger LOG = 
Loggers.forClass(UnitsContextManager.class);
 
-    private final RefCountedObjectPool<List<DeploymentUnit>, JobClassLoader> 
classLoaderPool = new RefCountedObjectPool<>();
+    private final RefCountedObjectPool<List<DeploymentUnit>, UnitsClassLoader> 
classLoaderPool = new RefCountedObjectPool<>();
 
     private final IgniteDeployment deployment;
     /**
@@ -57,7 +57,7 @@ public class JobContextManager {
     /**
      * The class loader factory.
      */
-    private final JobClassLoaderFactory classLoaderFactory;
+    private final UnitsClassLoaderFactory classLoaderFactory;
 
     /**
      * Constructor.
@@ -66,10 +66,10 @@ public class JobContextManager {
      * @param deploymentUnitAccessor The deployer service.
      * @param classLoaderFactory The class loader factory.
      */
-    public JobContextManager(
+    public UnitsContextManager(
             IgniteDeployment deployment,
             DeploymentUnitAccessor deploymentUnitAccessor,
-            JobClassLoaderFactory classLoaderFactory
+            UnitsClassLoaderFactory classLoaderFactory
     ) {
         this.deployment = deployment;
         this.deploymentUnitAccessor = deploymentUnitAccessor;
@@ -82,14 +82,14 @@ public class JobContextManager {
      * @param units The deployment units.
      * @return The class loader.
      */
-    public CompletableFuture<JobContext> 
acquireClassLoader(List<DeploymentUnit> units) {
-        CompletableFuture<JobContext> loaderFut = normalizeVersions(units)
+    public CompletableFuture<UnitsContext> 
acquireClassLoader(List<DeploymentUnit> units) {
+        CompletableFuture<UnitsContext> loaderFut = normalizeVersions(units)
                 .thenCompose(normalizedUnits -> 
checkUnitStatuses(normalizedUnits).thenApply(v -> normalizedUnits))
                 .thenCompose(normalizedUnits -> 
onDemandDeploy(normalizedUnits).thenApply(v -> normalizedUnits))
                 .thenApply(normalizedUnits -> 
classLoaderPool.acquire(normalizedUnits, this::createClassLoader))
-                .thenApply(loader -> new JobContext(loader, 
this::releaseClassLoader));
+                .thenApply(loader -> new UnitsContext(loader, 
this::releaseClassLoader));
 
-        CompletableFuture<JobContext> contextFut = loaderFut
+        CompletableFuture<UnitsContext> contextFut = loaderFut
                 .whenComplete((context, error) -> {
                     if (error != null) {
                         LOG.error("Failed to acquire class loader for units: " 
+ units, error);
@@ -102,7 +102,7 @@ public class JobContextManager {
         // completes. We need to close the context in any case. The successful 
path should be handled in the caller. We can't handle it
         // there because we don't have the access to the context if the future 
failed.
         contextFut.exceptionally(e -> {
-            loaderFut.thenAccept(JobContext::close);
+            loaderFut.thenAccept(UnitsContext::close);
             return null;
         });
 
@@ -113,7 +113,7 @@ public class JobContextManager {
      * Creates a class loader for the given deployment units. The units will 
be acquired. The class loader will be closed when it is not
      * used by any other job.
      */
-    private JobClassLoader createClassLoader(List<DeploymentUnit> units) {
+    private UnitsClassLoader createClassLoader(List<DeploymentUnit> units) {
         List<DisposableDeploymentUnit> disposableDeploymentUnits = 
units.stream()
                 .map(deploymentUnitAccessor::acquire)
                 .collect(Collectors.toList());
@@ -124,7 +124,7 @@ public class JobContextManager {
      * Releases a class loader. If the class loader is not used by any other 
job, it will be closed and the deployment units will be
      * released.
      */
-    private void releaseClassLoader(JobContext jobContext) {
+    private void releaseClassLoader(UnitsContext jobContext) {
         List<DeploymentUnit> units = jobContext.classLoader().units().stream()
                 .map(DisposableDeploymentUnit::unit)
                 .collect(Collectors.toList());
diff --git 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobClassLoaderFactoryTest.java
 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobClassLoaderFactoryTest.java
similarity index 91%
rename from 
modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobClassLoaderFactoryTest.java
rename to 
modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobClassLoaderFactoryTest.java
index c44ff99b084..7c8e099db1d 100644
--- 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobClassLoaderFactoryTest.java
+++ 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobClassLoaderFactoryTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import static org.apache.ignite.internal.testframework.IgniteTestUtils.getPath;
 import static 
org.apache.ignite.internal.testframework.matchers.CompletableFutureMatcher.willBe;
@@ -55,9 +55,9 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
 
     private static final String JOB2_UTILITY_CLASS_NAME = 
"org.apache.ignite.internal.compute.Job2Utility";
 
-    private final Path unitsDir = 
getPath(JobClassLoaderFactory.class.getClassLoader().getResource("units"));
+    private final Path unitsDir = 
getPath(UnitsClassLoaderFactory.class.getClassLoader().getResource("units"));
 
-    private final JobClassLoaderFactory jobClassLoaderFactory = new 
JobClassLoaderFactory();
+    private final UnitsClassLoaderFactory jobClassLoaderFactory = new 
UnitsClassLoaderFactory();
 
     @Test
     @DisplayName("Load class with the same name from two different class 
loaders")
@@ -67,8 +67,8 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
         List<DisposableDeploymentUnit> units1 = 
toDisposableDeploymentUnits(new DeploymentUnit("unit1", "1.0.0"));
         List<DisposableDeploymentUnit> units2 = 
toDisposableDeploymentUnits(new DeploymentUnit("unit2", "2.0.0"));
 
-        try (JobClassLoader classLoader1 = 
jobClassLoaderFactory.createClassLoader(units1);
-                JobClassLoader classLoader2 = 
jobClassLoaderFactory.createClassLoader(units2)) {
+        try (UnitsClassLoader classLoader1 = 
jobClassLoaderFactory.createClassLoader(units1);
+                UnitsClassLoader classLoader2 = 
jobClassLoaderFactory.createClassLoader(units2)) {
             // then classes from the first unit are loaded from the first 
class loader
             Class<?> clazz1 = 
classLoader1.classLoader().loadClass(UNIT_JOB_CLASS_NAME);
             ComputeJob<Void, Integer> job1 = (ComputeJob<Void, Integer>) 
clazz1.getDeclaredConstructor().newInstance();
@@ -92,7 +92,7 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
                 new DeploymentUnit("unit1", "2.0.0")
         );
 
-        try (JobClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
+        try (UnitsClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
             Class<?> unitJobClass = 
classLoader.classLoader().loadClass(UNIT_JOB_CLASS_NAME);
             assertNotNull(unitJobClass);
 
@@ -120,7 +120,7 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
         List<DisposableDeploymentUnit> units = toDisposableDeploymentUnits(new 
DeploymentUnit("unit1", "3.0.1"));
 
         // then class from all jars are loaded
-        try (JobClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
+        try (UnitsClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
             Class<?> unitJobClass = 
classLoader.classLoader().loadClass(UNIT_JOB_CLASS_NAME);
             assertNotNull(unitJobClass);
 
@@ -140,7 +140,7 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
         List<DisposableDeploymentUnit> units = toDisposableDeploymentUnits(new 
DeploymentUnit("unit1", "3.0.2"));
 
         // then class from all jars are loaded
-        try (JobClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
+        try (UnitsClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
             Class<?> unitJobClass = 
classLoader.classLoader().loadClass(UNIT_JOB_CLASS_NAME);
             assertNotNull(unitJobClass);
 
@@ -160,7 +160,7 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
         List<DisposableDeploymentUnit> units = toDisposableDeploymentUnits(new 
DeploymentUnit("unit1", "4.0.0"));
 
         // then class loader throws an exception
-        try (JobClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
+        try (UnitsClassLoader classLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
             assertThrows(ClassNotFoundException.class, () -> 
classLoader.classLoader().loadClass(UNIT_JOB_CLASS_NAME));
         }
     }
@@ -176,7 +176,7 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
         List<DisposableDeploymentUnit> units = toDisposableDeploymentUnits(new 
DeploymentUnit("unit1", "5.0.0"));
 
         // then the files are accessible
-        try (JobClassLoader jobClassLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
+        try (UnitsClassLoader jobClassLoader = 
jobClassLoaderFactory.createClassLoader(units)) {
             ClassLoader classLoader = jobClassLoader.classLoader();
             String resource = 
Files.readString(getPath(classLoader.getResource("test.txt")));
             String subDirResource = 
Files.readString(getPath(classLoader.getResource("subdir/test.txt")));
@@ -250,7 +250,7 @@ class JobClassLoaderFactoryTest extends 
BaseIgniteAbstractTest {
             }
         };
 
-        try (JobClassLoader jobClassLoader = 
jobClassLoaderFactory.createClassLoader(slowList)) {
+        try (UnitsClassLoader jobClassLoader = 
jobClassLoaderFactory.createClassLoader(slowList)) {
             List<ClassLoader> classLoaders = new ArrayList<>();
 
             List<Thread> threads = IntStream.range(0, 10)
diff --git 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobClassLoaderTest.java
 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobClassLoaderTest.java
similarity index 93%
rename from 
modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobClassLoaderTest.java
rename to 
modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobClassLoaderTest.java
index f3baa75ffef..2f86aceef0f 100644
--- 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobClassLoaderTest.java
+++ 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobClassLoaderTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.arrayContaining;
@@ -90,7 +90,7 @@ class JobClassLoaderTest extends BaseIgniteAbstractTest {
         DisposableDeploymentUnit unit1 = mock(DisposableDeploymentUnit.class);
         DisposableDeploymentUnit unit2 = mock(DisposableDeploymentUnit.class);
 
-        try (JobClassLoader jobClassLoader = new JobClassLoader(List.of(unit1, 
unit2), parentClassLoader)) {
+        try (UnitsClassLoader jobClassLoader = new 
UnitsClassLoader(List.of(unit1, unit2), parentClassLoader)) {
             jobClassLoader.close();
             verify(unit1, times(1)).release();
             verify(unit2, times(1)).release();
@@ -104,12 +104,12 @@ class JobClassLoaderTest extends BaseIgniteAbstractTest {
         RuntimeException toBeThrown = new RuntimeException("Expected 
exception");
         doThrow(toBeThrown).when(unit1).release();
 
-        JobClassLoader jobClassLoader = new JobClassLoader(List.of(unit1, 
unit2), parentClassLoader);
+        UnitsClassLoader jobClassLoader = new UnitsClassLoader(List.of(unit1, 
unit2), parentClassLoader);
         IgniteException igniteException = assertThrows(IgniteException.class, 
jobClassLoader::close);
         assertThat(igniteException.getSuppressed(), 
arrayContaining(toBeThrown));
     }
 
-    private static class TestJobClassLoaderImpl extends JobClassLoaderImpl {
+    private static class TestJobClassLoaderImpl extends UnitsClassLoaderImpl {
         TestJobClassLoaderImpl(URL[] urls, List<DisposableDeploymentUnit> 
units, ClassLoader parent) {
             super(units, urls, parent);
         }
diff --git 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobContextManagerTest.java
 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobContextManagerTest.java
similarity index 89%
rename from 
modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobContextManagerTest.java
rename to 
modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobContextManagerTest.java
index 5d11721d2f9..4e599264d6f 100644
--- 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/loader/JobContextManagerTest.java
+++ 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/loader/JobContextManagerTest.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.loader;
+package org.apache.ignite.internal.deployunit.loader;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static org.apache.ignite.deployment.version.Version.LATEST;
@@ -42,13 +42,13 @@ import java.util.List;
 import java.util.stream.Collectors;
 import org.apache.ignite.deployment.DeploymentUnit;
 import org.apache.ignite.deployment.version.Version;
-import org.apache.ignite.internal.compute.util.DummyIgniteDeployment;
 import org.apache.ignite.internal.deployunit.DeploymentUnitAccessorImpl;
 import org.apache.ignite.internal.deployunit.DisposableDeploymentUnit;
 import org.apache.ignite.internal.deployunit.FileDeployerService;
 import org.apache.ignite.internal.deployunit.IgniteDeployment;
 import 
org.apache.ignite.internal.deployunit.exception.DeploymentUnitNotFoundException;
 import 
org.apache.ignite.internal.deployunit.exception.DeploymentUnitUnavailableException;
+import org.apache.ignite.internal.deployunit.util.DummyIgniteDeployment;
 import org.apache.ignite.internal.lang.IgniteInternalException;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
 import org.apache.ignite.internal.testframework.WorkDirectory;
@@ -65,7 +65,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
 @ExtendWith(WorkDirectoryExtension.class)
 class JobContextManagerTest extends BaseIgniteAbstractTest {
 
-    private final Path unitsDir = 
getPath(JobClassLoaderFactory.class.getClassLoader().getResource("units"));
+    private final Path unitsDir = 
getPath(UnitsClassLoaderFactory.class.getClassLoader().getResource("units"));
 
     @WorkDirectory
     private Path workDir;
@@ -74,16 +74,16 @@ class JobContextManagerTest extends BaseIgniteAbstractTest {
     private IgniteDeployment deployment = new DummyIgniteDeployment(unitsDir);
 
     @Mock
-    private JobClassLoaderFactory jobClassLoaderFactory;
+    private UnitsClassLoaderFactory jobClassLoaderFactory;
 
-    private JobContextManager classLoaderManager;
+    private UnitsContextManager classLoaderManager;
 
     @BeforeEach
     void setUp() {
         FileDeployerService deployerService = new FileDeployerService("test");
         deployerService.initUnitsFolder(unitsDir, 
workDir.resolve("tempDeployment"));
 
-        classLoaderManager = new JobContextManager(
+        classLoaderManager = new UnitsContextManager(
                 deployment,
                 new DeploymentUnitAccessorImpl(deployerService),
                 jobClassLoaderFactory
@@ -105,11 +105,11 @@ class JobContextManagerTest extends 
BaseIgniteAbstractTest {
                 })
                 .collect(Collectors.toList());
 
-        JobClassLoader toBeReturned = new JobClassLoader(deploymentUnits, 
getClass().getClassLoader());
+        UnitsClassLoader toBeReturned = new UnitsClassLoader(deploymentUnits, 
getClass().getClassLoader());
         doReturn(toBeReturned)
                 
.when(jobClassLoaderFactory).createClassLoader(deploymentUnits);
 
-        JobContext context = 
classLoaderManager.acquireClassLoader(units).join();
+        UnitsContext context = 
classLoaderManager.acquireClassLoader(units).join();
         assertSame(toBeReturned, context.classLoader());
 
         verify(jobClassLoaderFactory, 
times(1)).createClassLoader(deploymentUnits); // verify that class loader was 
created
@@ -131,10 +131,10 @@ class JobContextManagerTest extends 
BaseIgniteAbstractTest {
         Path version2path = unitDir.resolve(version2.version().toString());
         List<DisposableDeploymentUnit> disposableVersion2 = List.of(new 
DisposableDeploymentUnit(version2, version2path, () -> {}));
 
-        try (JobClassLoader toBeReturned1 = new JobClassLoader(
+        try (UnitsClassLoader toBeReturned1 = new UnitsClassLoader(
                 disposableVersion1,
                 getClass().getClassLoader());
-                JobClassLoader toBeReturned2 = new JobClassLoader(
+                UnitsClassLoader toBeReturned2 = new UnitsClassLoader(
                         disposableVersion2,
                         getClass().getClassLoader())
         ) {
@@ -148,16 +148,16 @@ class JobContextManagerTest extends 
BaseIgniteAbstractTest {
             Files.createDirectories(version1path).toFile().deleteOnExit();
 
             List<DeploymentUnit> units = List.of(new DeploymentUnit(unitName, 
LATEST));
-            JobContext context1 = 
classLoaderManager.acquireClassLoader(units).join();
+            UnitsContext context1 = 
classLoaderManager.acquireClassLoader(units).join();
 
             assertSame(toBeReturned1, context1.classLoader());
 
-            JobContext context2 = 
classLoaderManager.acquireClassLoader(units).join();
+            UnitsContext context2 = 
classLoaderManager.acquireClassLoader(units).join();
             assertSame(context1.classLoader(), context2.classLoader());
 
             Files.createDirectories(version2path).toFile().deleteOnExit();
 
-            JobContext context3 = 
classLoaderManager.acquireClassLoader(units).join();
+            UnitsContext context3 = 
classLoaderManager.acquireClassLoader(units).join();
             assertSame(toBeReturned2, context3.classLoader());
         }
     }
diff --git 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/util/DummyIgniteDeployment.java
 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/util/DummyIgniteDeployment.java
similarity index 98%
rename from 
modules/compute/src/test/java/org/apache/ignite/internal/compute/util/DummyIgniteDeployment.java
rename to 
modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/util/DummyIgniteDeployment.java
index be75511e21a..f23b65b6a32 100644
--- 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/util/DummyIgniteDeployment.java
+++ 
b/modules/code-deployment-classloader/src/test/java/org/apache/ignite/internal/deployunit/util/DummyIgniteDeployment.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.compute.util;
+package org.apache.ignite.internal.deployunit.util;
 
 import static java.util.concurrent.CompletableFuture.completedFuture;
 import static java.util.concurrent.CompletableFuture.failedFuture;
diff --git 
a/modules/compute/src/test/resources/units/unit1/5.0.0/subdir/test.txt 
b/modules/code-deployment-classloader/src/test/resources/units/unit1/5.0.0/subdir/test.txt
similarity index 100%
rename from modules/compute/src/test/resources/units/unit1/5.0.0/subdir/test.txt
rename to 
modules/code-deployment-classloader/src/test/resources/units/unit1/5.0.0/subdir/test.txt
diff --git a/modules/compute/src/test/resources/units/unit1/5.0.0/test.txt 
b/modules/code-deployment-classloader/src/test/resources/units/unit1/5.0.0/test.txt
similarity index 100%
rename from modules/compute/src/test/resources/units/unit1/5.0.0/test.txt
rename to 
modules/code-deployment-classloader/src/test/resources/units/unit1/5.0.0/test.txt
diff --git a/modules/compute/build.gradle b/modules/compute/build.gradle
index 3180607d2d8..e6e43e20b91 100644
--- a/modules/compute/build.gradle
+++ b/modules/compute/build.gradle
@@ -29,6 +29,7 @@ dependencies {
     implementation project(':ignite-configuration-root')
     implementation project(':ignite-core')
     implementation project(':ignite-code-deployment')
+    implementation project(':ignite-code-deployment-classloader')
     implementation project(':ignite-cluster-management')
     implementation project(':ignite-placement-driver-api')
     implementation project(':ignite-binary-tuple')
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ClassLoaderExceptionsMapper.java
 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ClassLoaderExceptionsMapper.java
index c2c6ff195d2..1f3f82d725d 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ClassLoaderExceptionsMapper.java
+++ 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ClassLoaderExceptionsMapper.java
@@ -21,9 +21,9 @@ import static 
org.apache.ignite.internal.util.ExceptionUtils.unwrapCompletionThr
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
-import org.apache.ignite.internal.compute.loader.JobContext;
 import 
org.apache.ignite.internal.deployunit.exception.DeploymentUnitNotFoundException;
 import 
org.apache.ignite.internal.deployunit.exception.DeploymentUnitUnavailableException;
+import org.apache.ignite.internal.deployunit.loader.UnitsContext;
 
 class ClassLoaderExceptionsMapper {
     // <class_fqdn>. Deployment unit <deployment_unit_id_and ver> doesn't 
exist.
@@ -34,8 +34,8 @@ class ClassLoaderExceptionsMapper {
     private static final String DEPLOYMENT_UNIT_NOT_AVAILABLE_MSG = "%s. 
Deployment unit %s:%s can't be used: "
             + "[clusterStatus = %s, nodeStatus = %s]";
 
-    static CompletableFuture<JobContext> mapClassLoaderExceptions(
-            CompletableFuture<JobContext> future,
+    static CompletableFuture<UnitsContext> mapClassLoaderExceptions(
+            CompletableFuture<UnitsContext> future,
             String jobClassName
     ) {
         return future.handle((v, e) -> {
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java
 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java
index fae7b4871d8..e393bbc48f9 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java
+++ 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeComponentImpl.java
@@ -39,13 +39,13 @@ import 
org.apache.ignite.internal.compute.configuration.ComputeConfiguration;
 import org.apache.ignite.internal.compute.events.ComputeEventMetadataBuilder;
 import org.apache.ignite.internal.compute.executor.ComputeExecutor;
 import org.apache.ignite.internal.compute.executor.JobExecutionInternal;
-import org.apache.ignite.internal.compute.loader.JobContext;
-import org.apache.ignite.internal.compute.loader.JobContextManager;
 import org.apache.ignite.internal.compute.messaging.ComputeMessaging;
 import org.apache.ignite.internal.compute.messaging.RemoteJobExecution;
 import org.apache.ignite.internal.compute.task.DelegatingTaskExecution;
 import org.apache.ignite.internal.compute.task.JobSubmitter;
 import org.apache.ignite.internal.compute.task.TaskExecutionInternal;
+import org.apache.ignite.internal.deployunit.loader.UnitsContext;
+import org.apache.ignite.internal.deployunit.loader.UnitsContextManager;
 import org.apache.ignite.internal.eventlog.api.EventLog;
 import org.apache.ignite.internal.future.InFlightFutures;
 import org.apache.ignite.internal.lang.IgniteInternalException;
@@ -84,7 +84,7 @@ public class ComputeComponentImpl implements 
ComputeComponent, SystemViewProvide
 
     private final LogicalTopologyService logicalTopologyService;
 
-    private final JobContextManager jobContextManager;
+    private final UnitsContextManager jobContextManager;
 
     private final ComputeExecutor executor;
 
@@ -106,7 +106,7 @@ public class ComputeComponentImpl implements 
ComputeComponent, SystemViewProvide
             MessagingService messagingService,
             TopologyService topologyService,
             LogicalTopologyService logicalTopologyService,
-            JobContextManager jobContextManager,
+            UnitsContextManager jobContextManager,
             ComputeExecutor executor,
             ComputeConfiguration computeConfiguration,
             EventLog eventLog
@@ -133,7 +133,7 @@ public class ComputeComponentImpl implements 
ComputeComponent, SystemViewProvide
         }
 
         try {
-            CompletableFuture<JobContext> classLoaderFut = 
jobContextManager.acquireClassLoader(executionContext.units());
+            CompletableFuture<UnitsContext> classLoaderFut = 
jobContextManager.acquireClassLoader(executionContext.units());
 
             CompletableFuture<CancellableJobExecution<ComputeJobDataHolder>> 
future =
                     mapClassLoaderExceptions(classLoaderFut, 
executionContext.jobClassName())
@@ -337,7 +337,7 @@ public class ComputeComponentImpl implements 
ComputeComponent, SystemViewProvide
         messaging.start(executionContext -> executeLocally(executionContext, 
null));
     }
 
-    private JobExecutionInternal<ComputeJobDataHolder> execJob(JobContext 
context, ExecutionContext executionContext) {
+    private JobExecutionInternal<ComputeJobDataHolder> execJob(UnitsContext 
context, ExecutionContext executionContext) {
         try {
             return executor.executeJob(
                     executionContext.options(),
@@ -353,7 +353,7 @@ public class ComputeComponentImpl implements 
ComputeComponent, SystemViewProvide
     }
 
     private <I, M, T, R> TaskExecutionInternal<I, M, T, R> execTask(
-            JobContext context,
+            UnitsContext context,
             JobSubmitter<M, T> jobSubmitter,
             String taskClassName,
             ComputeEventMetadataBuilder metadataBuilder,
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeUtils.java
 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeUtils.java
index 1431cb4706c..bc2c81ac68f 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeUtils.java
+++ 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/ComputeUtils.java
@@ -42,7 +42,6 @@ import org.apache.ignite.compute.task.MapReduceTask;
 import org.apache.ignite.compute.task.TaskExecutionContext;
 import org.apache.ignite.deployment.DeploymentUnit;
 import org.apache.ignite.deployment.version.Version;
-import org.apache.ignite.internal.compute.loader.JobClassLoader;
 import org.apache.ignite.internal.compute.message.DeploymentUnitMsg;
 import org.apache.ignite.internal.compute.message.ExecuteResponse;
 import org.apache.ignite.internal.compute.message.JobCancelResponse;
@@ -50,6 +49,7 @@ import 
org.apache.ignite.internal.compute.message.JobChangePriorityResponse;
 import org.apache.ignite.internal.compute.message.JobResultResponse;
 import org.apache.ignite.internal.compute.message.JobStateResponse;
 import org.apache.ignite.internal.compute.message.JobStatesResponse;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoader;
 import org.apache.ignite.lang.IgniteCheckedException;
 import org.apache.ignite.lang.IgniteException;
 import org.apache.ignite.marshalling.Marshaller;
@@ -99,7 +99,7 @@ public class ComputeUtils {
      * @param <R> Compute job return type.
      * @return Compute job class.
      */
-    public static <T, R> Class<ComputeJob<T, R>> jobClass(JobClassLoader 
jobClassLoader, String jobClassName) {
+    public static <T, R> Class<ComputeJob<T, R>> jobClass(UnitsClassLoader 
jobClassLoader, String jobClassName) {
         try {
             return (Class<ComputeJob<T, R>>) Class.forName(jobClassName, true, 
jobClassLoader.classLoader());
         } catch (ClassNotFoundException e) {
@@ -147,7 +147,7 @@ public class ComputeUtils {
      * @param taskClassName Map reduce task class name.
      * @return Map reduce task class.
      */
-    public static <I, M, T, R> Class<MapReduceTask<I, M, T, R>> 
taskClass(JobClassLoader taskClassLoader, String taskClassName) {
+    public static <I, M, T, R> Class<MapReduceTask<I, M, T, R>> 
taskClass(UnitsClassLoader taskClassLoader, String taskClassName) {
         try {
             return (Class<MapReduceTask<I, M, T, R>>) 
Class.forName(taskClassName, true, taskClassLoader.classLoader());
         } catch (ClassNotFoundException e) {
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/JobExecutionContextImpl.java
 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/JobExecutionContextImpl.java
index 44935641848..73c18bc0d7a 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/JobExecutionContextImpl.java
+++ 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/JobExecutionContextImpl.java
@@ -24,8 +24,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import org.apache.ignite.Ignite;
 import org.apache.ignite.compute.JobExecutionContext;
 import org.apache.ignite.deployment.DeploymentUnitInfo;
-import org.apache.ignite.internal.compute.loader.JobClassLoader;
 import org.apache.ignite.internal.deployunit.DisposableDeploymentUnit;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoader;
 import org.apache.ignite.internal.util.Lazy;
 import org.apache.ignite.table.partition.Partition;
 import org.jetbrains.annotations.Nullable;
@@ -38,7 +38,7 @@ public class JobExecutionContextImpl implements 
JobExecutionContext {
 
     private final AtomicBoolean isInterrupted;
 
-    private final JobClassLoader classLoader;
+    private final UnitsClassLoader classLoader;
 
     private final @Nullable Partition partition;
 
@@ -52,7 +52,7 @@ public class JobExecutionContextImpl implements 
JobExecutionContext {
      * @param classLoader Job class loader.
      * @param partition Partition associated with this job.
      */
-    public JobExecutionContextImpl(Ignite ignite, AtomicBoolean isInterrupted, 
JobClassLoader classLoader, @Nullable Partition partition) {
+    public JobExecutionContextImpl(Ignite ignite, AtomicBoolean isInterrupted, 
UnitsClassLoader classLoader, @Nullable Partition partition) {
         this.ignite = ignite;
         this.isInterrupted = isInterrupted;
         this.classLoader = classLoader;
@@ -86,7 +86,7 @@ public class JobExecutionContextImpl implements 
JobExecutionContext {
      *
      * @return Job class loader.
      */
-    public JobClassLoader classLoader() {
+    public UnitsClassLoader classLoader() {
         return classLoader;
     }
 
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutor.java
 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutor.java
index c004cfa4a9d..a2583e776ff 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutor.java
+++ 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutor.java
@@ -20,9 +20,9 @@ package org.apache.ignite.internal.compute.executor;
 import org.apache.ignite.internal.compute.ComputeJobDataHolder;
 import org.apache.ignite.internal.compute.ExecutionOptions;
 import org.apache.ignite.internal.compute.events.ComputeEventMetadataBuilder;
-import org.apache.ignite.internal.compute.loader.JobClassLoader;
 import org.apache.ignite.internal.compute.task.JobSubmitter;
 import org.apache.ignite.internal.compute.task.TaskExecutionInternal;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoader;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -32,7 +32,7 @@ public interface ComputeExecutor {
     JobExecutionInternal<ComputeJobDataHolder> executeJob(
             ExecutionOptions options,
             String jobClassName,
-            JobClassLoader classLoader,
+            UnitsClassLoader classLoader,
             ComputeEventMetadataBuilder metadataBuilder,
             @Nullable ComputeJobDataHolder arg
     );
@@ -40,7 +40,7 @@ public interface ComputeExecutor {
     <I, M, T, R> TaskExecutionInternal<I, M, T, R> executeTask(
             JobSubmitter<M, T> jobSubmitter,
             String taskClassName,
-            JobClassLoader classLoader,
+            UnitsClassLoader classLoader,
             ComputeEventMetadataBuilder metadataBuilder,
             @Nullable I arg
     );
diff --git 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutorImpl.java
 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutorImpl.java
index 2ff5e119aec..da589a47294 100644
--- 
a/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutorImpl.java
+++ 
b/modules/compute/src/main/java/org/apache/ignite/internal/compute/executor/ComputeExecutorImpl.java
@@ -44,13 +44,13 @@ import 
org.apache.ignite.internal.compute.configuration.ComputeConfiguration;
 import org.apache.ignite.internal.compute.events.ComputeEventMetadataBuilder;
 import 
org.apache.ignite.internal.compute.executor.platform.PlatformComputeTransport;
 import 
org.apache.ignite.internal.compute.executor.platform.dotnet.DotNetComputeExecutor;
-import org.apache.ignite.internal.compute.loader.JobClassLoader;
 import org.apache.ignite.internal.compute.queue.PriorityQueueExecutor;
 import org.apache.ignite.internal.compute.queue.QueueExecution;
 import org.apache.ignite.internal.compute.state.ComputeStateMachine;
 import org.apache.ignite.internal.compute.task.JobSubmitter;
 import org.apache.ignite.internal.compute.task.TaskExecutionContextImpl;
 import org.apache.ignite.internal.compute.task.TaskExecutionInternal;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoader;
 import org.apache.ignite.internal.eventlog.api.EventLog;
 import org.apache.ignite.internal.hlc.ClockService;
 import org.apache.ignite.internal.logger.IgniteLogger;
@@ -115,7 +115,7 @@ public class ComputeExecutorImpl implements ComputeExecutor 
{
     public JobExecutionInternal<ComputeJobDataHolder> executeJob(
             ExecutionOptions options,
             String jobClassName,
-            JobClassLoader classLoader,
+            UnitsClassLoader classLoader,
             ComputeEventMetadataBuilder metadataBuilder,
             @Nullable ComputeJobDataHolder arg
     ) {
@@ -167,7 +167,7 @@ public class ComputeExecutorImpl implements ComputeExecutor 
{
     private Callable<CompletableFuture<ComputeJobDataHolder>> getJobCallable(
             JobExecutorType executorType,
             String jobClassName,
-            JobClassLoader classLoader,
+            UnitsClassLoader classLoader,
             @Nullable ComputeJobDataHolder arg,
             JobExecutionContext context
     ) {
@@ -193,7 +193,7 @@ public class ComputeExecutorImpl implements ComputeExecutor 
{
 
     private static Callable<CompletableFuture<ComputeJobDataHolder>> 
getJavaJobCallable(
             String jobClassName,
-            JobClassLoader classLoader,
+            UnitsClassLoader classLoader,
             @Nullable ComputeJobDataHolder arg,
             JobExecutionContext context
     ) {
@@ -230,7 +230,7 @@ public class ComputeExecutorImpl implements ComputeExecutor 
{
     public <I, M, T, R> TaskExecutionInternal<I, M, T, R> executeTask(
             JobSubmitter<M, T> jobSubmitter,
             String taskClassName,
-            JobClassLoader classLoader,
+            UnitsClassLoader classLoader,
             ComputeEventMetadataBuilder metadataBuilder,
             @Nullable I arg
     ) {
diff --git 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java
 
b/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java
index cca1eee1c61..5555657f1c5 100644
--- 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java
+++ 
b/modules/compute/src/test/java/org/apache/ignite/internal/compute/ComputeComponentImplTest.java
@@ -77,9 +77,6 @@ import 
org.apache.ignite.internal.compute.configuration.ComputeConfiguration;
 import org.apache.ignite.internal.compute.events.ComputeEventMetadata;
 import org.apache.ignite.internal.compute.executor.ComputeExecutor;
 import org.apache.ignite.internal.compute.executor.ComputeExecutorImpl;
-import org.apache.ignite.internal.compute.loader.JobClassLoader;
-import org.apache.ignite.internal.compute.loader.JobContext;
-import org.apache.ignite.internal.compute.loader.JobContextManager;
 import org.apache.ignite.internal.compute.message.ExecuteRequest;
 import org.apache.ignite.internal.compute.message.ExecuteResponse;
 import org.apache.ignite.internal.compute.message.JobCancelRequest;
@@ -96,6 +93,9 @@ import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguratio
 import org.apache.ignite.internal.deployunit.DeploymentStatus;
 import 
org.apache.ignite.internal.deployunit.exception.DeploymentUnitNotFoundException;
 import 
org.apache.ignite.internal.deployunit.exception.DeploymentUnitUnavailableException;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoader;
+import org.apache.ignite.internal.deployunit.loader.UnitsContext;
+import org.apache.ignite.internal.deployunit.loader.UnitsContextManager;
 import org.apache.ignite.internal.eventlog.api.EventLog;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.TestClockService;
@@ -145,7 +145,7 @@ class ComputeComponentImplTest extends 
BaseIgniteAbstractTest {
     private ComputeConfiguration computeConfiguration;
 
     @Mock
-    private JobContextManager jobContextManager;
+    private UnitsContextManager jobContextManager;
 
     private ComputeComponentImpl computeComponent;
 
@@ -163,8 +163,8 @@ class ComputeComponentImplTest extends 
BaseIgniteAbstractTest {
         lenient().when(ignite.name()).thenReturn(INSTANCE_NAME);
         
lenient().when(topologyService.localMember().name()).thenReturn(INSTANCE_NAME);
 
-        JobClassLoader classLoader = new JobClassLoader(List.of(), 
getClass().getClassLoader());
-        JobContext jobContext = new JobContext(classLoader, ignored -> {});
+        UnitsClassLoader classLoader = new UnitsClassLoader(List.of(), 
getClass().getClassLoader());
+        UnitsContext jobContext = new UnitsContext(classLoader, ignored -> {});
         lenient().when(jobContextManager.acquireClassLoader(anyList()))
                 .thenReturn(completedFuture(jobContext));
 
diff --git 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/executor/ComputeExecutorTest.java
 
b/modules/compute/src/test/java/org/apache/ignite/internal/compute/executor/ComputeExecutorTest.java
index 8e17a9ed0dd..a44f9819fa9 100644
--- 
a/modules/compute/src/test/java/org/apache/ignite/internal/compute/executor/ComputeExecutorTest.java
+++ 
b/modules/compute/src/test/java/org/apache/ignite/internal/compute/executor/ComputeExecutorTest.java
@@ -48,10 +48,10 @@ import org.apache.ignite.internal.compute.ExecutionOptions;
 import org.apache.ignite.internal.compute.SharedComputeUtils;
 import org.apache.ignite.internal.compute.configuration.ComputeConfiguration;
 import org.apache.ignite.internal.compute.events.ComputeEventMetadata;
-import org.apache.ignite.internal.compute.loader.JobClassLoader;
 import org.apache.ignite.internal.compute.state.InMemoryComputeStateMachine;
 import 
org.apache.ignite.internal.configuration.testframework.ConfigurationExtension;
 import 
org.apache.ignite.internal.configuration.testframework.InjectConfiguration;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoader;
 import org.apache.ignite.internal.eventlog.api.EventLog;
 import org.apache.ignite.internal.hlc.HybridClockImpl;
 import org.apache.ignite.internal.hlc.TestClockService;
@@ -78,7 +78,7 @@ class ComputeExecutorTest extends BaseIgniteAbstractTest {
 
     private ComputeExecutor computeExecutor;
 
-    private final JobClassLoader jobClassLoader = new 
JobClassLoader(List.of(), getClass().getClassLoader());
+    private final UnitsClassLoader jobClassLoader = new 
UnitsClassLoader(List.of(), getClass().getClassLoader());
 
     @BeforeEach
     void setUp() {
diff --git a/modules/runner/build.gradle b/modules/runner/build.gradle
index 558b3b6400b..cf642770d41 100644
--- a/modules/runner/build.gradle
+++ b/modules/runner/build.gradle
@@ -81,6 +81,7 @@ dependencies {
     implementation project(':ignite-distribution-zones')
     implementation project(':ignite-placement-driver')
     implementation project(':ignite-code-deployment')
+    implementation project(':ignite-code-deployment-classloader')
     implementation project(':ignite-security-api')
     implementation project(':ignite-security')
     implementation project(':ignite-catalog')
diff --git 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
index 02432b2aa6c..d85ed144ae0 100644
--- 
a/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
+++ 
b/modules/runner/src/main/java/org/apache/ignite/internal/app/IgniteImpl.java
@@ -100,8 +100,6 @@ import 
org.apache.ignite.internal.compute.IgniteComputeInternal;
 import org.apache.ignite.internal.compute.configuration.ComputeConfiguration;
 import 
org.apache.ignite.internal.compute.configuration.ComputeExtensionConfiguration;
 import org.apache.ignite.internal.compute.executor.ComputeExecutorImpl;
-import org.apache.ignite.internal.compute.loader.JobClassLoaderFactory;
-import org.apache.ignite.internal.compute.loader.JobContextManager;
 import org.apache.ignite.internal.compute.state.InMemoryComputeStateMachine;
 import org.apache.ignite.internal.configuration.ComponentWorkingDir;
 import 
org.apache.ignite.internal.configuration.ConfigurationDynamicDefaultsPatcherImpl;
@@ -126,6 +124,8 @@ import 
org.apache.ignite.internal.configuration.validation.ConfigurationValidato
 import org.apache.ignite.internal.deployunit.DeploymentManagerImpl;
 import org.apache.ignite.internal.deployunit.IgniteDeployment;
 import 
org.apache.ignite.internal.deployunit.configuration.DeploymentExtensionConfiguration;
+import org.apache.ignite.internal.deployunit.loader.UnitsClassLoaderFactory;
+import org.apache.ignite.internal.deployunit.loader.UnitsContextManager;
 import org.apache.ignite.internal.deployunit.metastore.DeploymentUnitStoreImpl;
 import org.apache.ignite.internal.disaster.system.ClusterIdService;
 import org.apache.ignite.internal.disaster.system.MetastorageRepairImpl;
@@ -1259,7 +1259,7 @@ public class IgniteImpl implements Ignite {
                 clusterSvc.messagingService(),
                 clusterSvc.topologyService(),
                 logicalTopologyService,
-                new JobContextManager(deploymentManagerImpl, 
deploymentManagerImpl.deploymentUnitAccessor(), new JobClassLoaderFactory()),
+                new UnitsContextManager(deploymentManagerImpl, 
deploymentManagerImpl.deploymentUnitAccessor(), new UnitsClassLoaderFactory()),
                 computeExecutor,
                 computeCfg,
                 eventLog
diff --git a/settings.gradle b/settings.gradle
index 1f17b095aa7..2a017bd8f88 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -77,6 +77,7 @@ include(':ignite-distribution-zones')
 include(':ignite-placement-driver')
 include(':ignite-placement-driver-api')
 include(':ignite-code-deployment')
+include(':ignite-code-deployment-classloader')
 include(':ignite-security-api')
 include(':ignite-security')
 include(':ignite-catalog')
@@ -160,6 +161,7 @@ project(":ignite-distribution-zones").projectDir = 
file('modules/distribution-zo
 project(":ignite-placement-driver").projectDir = 
file('modules/placement-driver')
 project(":ignite-placement-driver-api").projectDir = 
file('modules/placement-driver-api')
 project(":ignite-code-deployment").projectDir = file('modules/code-deployment')
+project(":ignite-code-deployment-classloader").projectDir = 
file('modules/code-deployment-classloader')
 project(":ignite-security").projectDir = file('modules/security')
 project(":ignite-security-api").projectDir = file('modules/security-api')
 project(":ignite-catalog").projectDir = file('modules/catalog')

Reply via email to