【问题标题】:Closing a JarURLConnection关闭一个 JarURLConnection
【发布时间】:2016-04-09 13:44:41
【问题描述】:

使用 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();
        }
    }
}

当我第一次调用这个方法时它可以正常工作;您会看到“检查更新”消息和“结果”消息之间存在延迟。

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

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

我尝试了以下方法:

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

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

提前致谢。

【问题讨论】:

标签: java jar urlconnection


【解决方案1】:

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

所以在访问 Jar 文件之前关闭缓存即可:

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

【讨论】:

  • 非常感谢!我也刚想通了这一点,我重新加载了此页面以查看您刚刚发布的答案。很明显,我会接受这个作为答案。
【解决方案2】:

这可能会回答你的问题:

URLConnection cache prevents updating JARs with the JarArchiveRepository

我发现的唯一解决方法是禁用 JarURLConnection 缓存和 然后它按预期工作:

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;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-29
    • 2016-06-15
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多