关闭 JarURLConnection

Closing a JarURLConnection

使用 JarURLConnection 我能够从托管在 Dropbox 上的 JAR 中读取文件(例如 version.txt)以下代码结构:

public static void checkForUpdates() {
    JarURLConnection jarConn = null;
    try {

        System.out.println("Checking for updates..");

        URL updateURL = new URL("jar:https://www.dropbox.com/s/.../foo.jar?dl=1!/version.txt");
        jarConn = (JarURLConnection) updateURL.openConnection();
        JarFile jarFile = jarConn.getJarFile();
        InputStream inputStream = jarFile.getInputStream(jarConn.getJarEntry());
        BufferedReader versionTXT = new BufferedReader(new InputStreamReader(inputStream));

        /* Version comparing left out */

        // If there is an update:
        System.out.println("Update found!");

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (jarConn != null) {
            // This doesn't seem to work
            jarConn.getInputStream().close();
        }
    }
}

第一次调用此方法时,它可以正常工作;您可以看到 "checking for updates" 消息和 "result" 消息之间的延迟。

当我在 Dropbox 上上传新的 foo.jar 并再次 运行 checkForUpdates() 方法时(没有 重新启动 JVM),它将使用'old' jar,检查和结果消息之间没有延迟。当我 重新启动 JVM 时,它将使用 'new' jar 并显示消息之间的延迟。

除了关闭 InputStream(这似乎不起作用)之外,还有其他方法可以关闭 JarURLConnection 吗?

我试过以下方法:

  • 关闭 JarURLConnection 的 OutputStream -> 抛出一个错误,指出连接没有 OutputStream。
  • 关闭 URLConnections Input- & OutputStream(通过在我将其转换为 JarURLConnection 之前创建一个新变量)-> 关闭 InputStream 似乎没有任何作用并关闭OutputStream 抛出同样的错误。
  • 关闭 BufferedReader -> 无效。

如果无法关闭 JarURLConnection,是否可以创建一个 重新连接的新连接?重新启动 JVM 显然做了一些它确实重新连接的事情,是否可以模拟 而不 重新启动 JVM?

提前致谢。

JarURLConnection 使用 jar 文件的缓存。因此,您不会在第二次尝试中看到任何延迟。

因此在访问 Jar 文件之前只需关闭缓存即可:

JarURLConnection con = ...;
con.setUseCaches(false);
JarFile jarFile = jarConn.getJarFile();

这可能会回答您的问题:

URLConnection cache prevents updating JARs with the JarArchiveRepository

The only workaround I found is to disable JarURLConnection caching and it then works as expected:

urlConnection.setDefaultUseCaches(false);

您可以看到 Sun code here:

public void connect() throws IOException {
    if (!connected) {
        /* the factory call will do the security checks */
        jarFile = factory.get(getJarFileURL(), getUseCaches());

        /* we also ask the factory the permission that was required
         * to get the jarFile, and set it as our permission.
         */
        if (getUseCaches()) {
            jarFileURLConnection = factory.getConnection(jarFile);
        }

        if ((entryName != null)) {
            jarEntry = (JarEntry)jarFile.getEntry(entryName);
            if (jarEntry == null) {
                try {
                    if (!getUseCaches()) {
                        jarFile.close();
                    }
                } catch (Exception e) {
                }
                throw new FileNotFoundException("JAR entry " + entryName + " not found in " + jarFile.getName());
            }
        }
        connected = true;
    }
}