2016-04-09 14 views
1

Mit einem JarURLConnection Closing ich in der Lage bin, eine Datei (zB version.txt) aus einem JAR-auf Dropbox Struktur mit der folgenden Code gehostet zu lesen:ein JarURLConnection

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

Es funktioniert richtig, wenn ich rufe diese Methode zum ersten Mal auf; Sie können eine Verzögerung zwischen der Nachricht "Nach Updates suchen" und der "Ergebnis" -Nachricht sehen.

Wenn ich ein neues foo.jar auf Dropbox hochladen und die checkForUpdates run() Methode wieder (ohne die JVM neu zu starten), wird es das ‚alte‘ Glas verwenden, und es gibt keine Verzögerung zwischen der Überprüfung & Ergebnisnachrichten. Wenn ich mache die JVM neu starten, wird es die 'neue' Jar und Show Verzögerung zwischen den Nachrichten verwenden.

Gibt es eine Möglichkeit, die JarURLConnection zu schließen, außer den InputStream zu schließen (was nicht zu funktionieren scheint)?

Ich habe folgende Dinge ausprobiert:

  • den Output der JarURLConnection Closing -> Löst eine Fehlermeldung, dass die Verbindung nicht einen Output hat.
  • Schließen des URLConnections Input- & Output (durch eine neue Variable zu schaffen, bevor ich es auf eine JarURLConnection cast) -> Schließen der Input scheint nicht, etwas zu tun, und die Output Schließen führt den gleichen Fehler.
  • Schließen der BufferedReader -> Kein Effekt.

Wenn es nicht möglich ist, die JarURLConnection zu schließen, ist es möglich, einen neuen zu erstellen, die nicht wieder? Neustart der JVM scheinbar etwas, das es wieder verbindet, ist es möglich, ohne Neustart der JVM zu simulieren?

Vielen Dank im Voraus.

+0

können Sie einen Versuch - Ressource statt? https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html – chrisl08

+0

Ich habe gerade eine try-Ressource auf meinem InputStream und BufferedReader getestet, aber es gibt keinen Unterschied. – Semx11

Antwort

2

JarURLConnection verwendet einen Cache für JAR-Dateien. Daher sehen Sie im zweiten Versuch keine Verzögerung.

deaktivieren So einfach, den Cache, bevor Sie die JAR-Datei zuzugreifen:

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

Vielen Dank! Ich habe das gerade herausgefunden, und ich habe diese Seite neu geladen, um deine Antwort zu sehen, die gerade gepostet wurde. Ich werde das natürlich als Antwort akzeptieren. – Semx11

1

Diese Frage beantworten könnte:

URLConnection cache prevents updating JARs with the JarArchiveRepository

Die einzige Abhilfe, die ich gefunden ist JarURLConnection zu deaktivieren Caching und dann funktioniert es wie erwartet:

urlConnection.setDefaultUseCaches(false); 

können Sie sehen die 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; 
    } 
} 
+0

Nützliche Antwort, danke! – Semx11