private static void update(
            final String targetVersion,
            final boolean forced,
            final Path pathRunning,
            final String userAgent) throws IOException {
        logger.info("Updating to the version {}", targetVersion);

        final String targetUrlString = String.format("https://dl.embulk.org/embulk-%s.jar", targetVersion);

        // In case of Windows, just download without overwriting the running JAR file.
        final String osName = System.getProperty("os.name");
        if (osName != null && osName.contains("Windows")) {
            final Path pathDownloaded = Files.createTempFile("embulk-" + targetVersion + "-", ".jar");
            logger.warn("Overwriting a running JAR file is not permitted on Windows. Just downloading to: {}", pathDownloaded);
            download(targetUrlString, pathDownloaded, userAgent);
            return;
        }

        final Path pathTemporary = Files.createTempFile("embulk-selfupdate", ".jar");
        try {
            download(targetUrlString, pathTemporary, userAgent);

            final FileSystem fileSystemOriginal = pathRunning.getFileSystem();
            final FileSystem fileSystemTemporary = pathTemporary.getFileSystem();
            if (fileSystemOriginal.supportedFileAttributeViews().contains("posix")
                        && fileSystemTemporary.supportedFileAttributeViews().contains("posix")) {
                Files.setPosixFilePermissions(pathTemporary, Files.getPosixFilePermissions(pathRunning));
            }

            if (!forced) {  // Check corruption
                final String downloadedVersion = extractImplementationVersionFromJar(pathTemporary);
                if (!downloadedVersion.equals(targetVersion)) {
                    throw new IOException(String.format("Downloaded version does not match: %s (downloaded) / %s (target)",
                                                        downloadedVersion, targetVersion));
                }
            }
            logger.info("Overwriting {} onto {}", pathTemporary, pathRunning);
            Files.move(pathTemporary, pathRunning, StandardCopyOption.REPLACE_EXISTING);
            logger.info("Overwritten");
        } finally {
            Files.deleteIfExists(pathTemporary);
        }
        logger.info("Updated to the version {}", targetVersion);
    }
Runs the selfupdate subcommand of Embulk.

<p>It uses {@link java.net.HttpURLConnection} so that CLI classes do not need additional dependedcies.

<p>TODO: Support HTTP(S) proxy. The original Ruby version did not support as well, though.
embulk-core/src/main/java/org/embulk/cli/SelfUpdate.java