@VisibleForTesting
    JarRunHandler getJarRunHandler() {
        return jarRunHandler;
    }
@Test
    void applicationsRunInSeparateThreads(@TempDir Path tempDir) throws Exception {
        final Path uploadDir = Files.createDirectories(tempDir.resolve("uploadDir"));
        // create a copy because the upload handler moves uploaded jars (because it assumes it to be
        // a temporary file)
        final Path jarFile =
                Files.copy(
                        Paths.get(System.getProperty("targetDir")).resolve(JAR_NAME),
                        tempDir.resolve("app.jar"));

        final DispatcherGateway dispatcherGateway = TestingDispatcherGateway.newBuilder().build();

        final ThreadCapturingApplicationRunner threadCapturingApplicationRunner =
                new ThreadCapturingApplicationRunner();

        final WebSubmissionExtension webSubmissionExtension =
                new WebSubmissionExtension(
                        new Configuration(),
                        () -> CompletableFuture.completedFuture(dispatcherGateway),
                        Collections.emptyMap(),
                        new CompletableFuture<>(),
                        uploadDir,
                        Executors.directExecutor(),
                        Time.of(5, TimeUnit.SECONDS),
                        () -> threadCapturingApplicationRunner);

        final String jarId = uploadJar(webSubmissionExtension, jarFile, dispatcherGateway);

        final JarRunHandler jarRunHandler = webSubmissionExtension.getJarRunHandler();

        final JarRunMessageParameters parameters = new JarRunMessageParameters();
        parameters.jarIdPathParameter.resolve(jarId);
        final HandlerRequest<JarRunRequestBody> runRequest =
                HandlerRequest.create(new JarRunRequestBody(), parameters);

        // run several applications in sequence, and verify that each thread is unique
        int numApplications = 20;
        for (int i = 0; i < numApplications; i++) {
            jarRunHandler.handleRequest(runRequest, dispatcherGateway).get();
        }
        assertThat(threadCapturingApplicationRunner.getThreads().size()).isEqualTo(numApplications);
    }