Warum packt er nicht alle Dateien?

  • Themenstarter Themenstarter Seichelm
  • Beginndatum Beginndatum
S

Seichelm

Gast
Hallo,

bin gerade an einem Programmierbeleg und habe folgendes Problem:

Es handelt sich um ein Programm zum packen von JAR-Archiven.
Dazu werden die Dateien aus einem Ordner ausgelesen und in einer ArrayList gespeichert.

Java:
public void jarEintraege(String JARFile, ArrayList Files, JarOutputStream jos, byte[] buf, String inJARpath) {

        try {
            // Dateien werden eingelesen:
            for (int i = 0; i < Files.size(); i++) {
                final File f = new File((String) Files.get(i));

                // Falls die Datei ein Verzeichnis ist:
                if(f.isDirectory()) {
                    inJARpath = inJARpath + f.getName() + File.separator;
                    File[] files = f.listFiles();
                    ArrayList al = new ArrayList();
                    for(int a = 0; a < files.length; a ++) {
                        al.add(files[a].toString());
                    }

                    jarEintraege(JARFile, al, jos, buf, inJARpath);
                }
                else {
                    final FileInputStream fis = new FileInputStream(f);

                    // Einträge werden angelegt:
                    jos.putNextEntry(new JarEntry(inJARpath + entryName(f)));

                    // JAR-Einträge werden geschrieben:
                    int len;
                    while ((len = fis.read(buf)) >= 0) {
                        jos.write(buf, 0, len);
                    }
                    fis.close();
		}
            }
        }
        catch(IOException e) {}
        finally{
            try{
                jos.close();
            }
            catch(IOException ex) {}
        }

    }

Nun habe ich das Problem, sobald ein Ordner gepackt wird, wird keine weitere Datei gepackt.
Also sind alle Dateien aus dem Ordner in dem Archiv gepackt, jedoch fehlen diejenigen, welche direkt nach dem Ordner stehen.

Kann mir jemand helfen?

Vielen Dank im vorraus!
 
folgende Exception wird ausgelöst:

java.io.IOException: Stream closed
at java.util.zip.ZipOutputStream.ensureOpen(ZipOutputStream.java:70)
at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:142)
at java.util.jar.JarOutputStream.putNextEntry(JarOutputStream.java:92)
at WriteJAR.jarEintraege(WriteJAR.java:155)
at WriteJAR.Write(WriteJAR.java:109)
at CreateJARStrg.archivPacken(CreateJARStrg.java:371)
at CreateJAR.btnArchActionPerformed(CreateJAR.java:565)
at CreateJAR.access$1000(CreateJAR.java:11)
at CreateJAR$11.actionPerformed(CreateJAR.java:362)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6263)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3255)
at java.awt.Component.processEvent(Component.java:6028)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4574)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2475)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
 
Naja - für ein Verzeichnis rufst Du die selbe Methode rekursiv auf. Beim rausspringen (eine Ebene runter im Stack) schließt Du den Strom und willst dann danach weiter drauf schreiben. Das geht natürlich nicht.

Das Close (oben in Zeile 37) ist daran schuld. Konzeptionell gehört es aber ohnehin nicht dort hin. Darum muss sich der Aufrufer kümmern. Die Regel ist ganz einfach: Wer den Strom erzeugt muss ihn schließen. Niemand sonst! Die Methode bekommt einen Strom, um darauf zu schreiben. Nicht um den Strom zu schließen; vielleicht will der Aufrufer ja noch mehr machen.

Ebenius
 
Habe nun einen funktionierenden Code gefunden:

Java:
public void jarEintraege(String JARFile, ArrayList Files, JarOutputStream jos, byte[] buf, String inJARpath) {

        String JARpfad = inJARpath;

        try {
            // Dateien werden eingelesen:
            for (int i = 0; i < Files.size(); i++) {
                final File f = new File((String) Files.get(i));

                // Falls die Datei ein Verzeichnis ist:
                if(f.isDirectory()) {
                    durchläufe = 1;

                    JARpfad = JARpfad + f.getName() + File.separator;
                    File[] files = f.listFiles();
                    ArrayList al = new ArrayList();
                    for(int a = 0; a < files.length; a ++) {
                        al.add(files[a].toString());
                    }
                    
                    jarEintraegeFuerOrdner(JARFile, al, jos, buf, JARpfad);

                    durchläufe = 0;
                }
                else {                    

                    final FileInputStream fis = new FileInputStream(f);

                    // Einträge werden angelegt:
                    jos.putNextEntry(new JarEntry(inJARpath + entryName(f)));

                    // JAR-Einträge werden geschrieben:
                    int len;
                    while ((len = fis.read(buf)) >= 0) {
                        jos.write(buf, 0, len);
                    }
                    fis.close();
		}
            }
        }
        catch(IOException e) { e.printStackTrace(); }
        finally{
            try{
                if(durchläufe == 0) jos.close();
            }
            catch(IOException ex) { ex.printStackTrace(); }
        }

    }

und diese Methode:

Java:
public void jarEintraegeFuerOrdner(String JARFile, ArrayList Files, JarOutputStream jos, byte[] buf, String inJARpath) {
            String JARpfad = inJARpath;

        try {
            // Dateien werden eingelesen:
            for (int i = 0; i < Files.size(); i++) {
                final File f = new File((String) Files.get(i));

                // Falls die Datei ein Verzeichnis ist:
                if(f.isDirectory()) {
                    durchläufe = 1;

                    JARpfad = JARpfad + f.getName() + File.separator;
                    File[] files = f.listFiles();
                    ArrayList al = new ArrayList();
                    for(int a = 0; a < files.length; a ++) {
                        al.add(files[a].toString());
                    }

                    jarEintraege(JARFile, al, jos, buf, JARpfad);

                    durchläufe = 0;
                }
                else {

                    final FileInputStream fis = new FileInputStream(f);

                    // Einträge werden angelegt:
                    jos.putNextEntry(new JarEntry(inJARpath + entryName(f)));

                    // JAR-Einträge werden geschrieben:
                    int len;
                    while ((len = fis.read(buf)) >= 0) {
                        jos.write(buf, 0, len);
                    }
                    fis.close();
		}
            }
        }
        catch(IOException e) { e.printStackTrace(); }
}


Jetzt besteht das Problem, dass zwar das Archiv korrekt gepackt wird, aber nach doppelklick auf die Datei die Anwendung nicht startet.
 
Wird dabei auch eine Manifest datei mit dem Eintrag der Main Klasse erstellt? Habs mir jetzt net durchgelesen... Damit sich eine jar auf Doppelklick öffnet, muss via Manifest Datei festgelegt werden, in welche Klasse er einspringen soll.

Musst das ändern, dass der noch nen Ordner META-INF erstellt indem die MANIFEST.MF liegt, in welcher

Code:
Manifest-Version: 1.0
Main-Class: MeineMainKlasse

steht.
 
Das Manifest ist nicht das Problem.

Es kommt auch kein Fehler, wenn ich das JAR starte.

Es passiert einfach nichts und die Anwendung startet nicht.

Habt ihr eine Idee woran das liegen könnte?
 
Viele Dank für den Tipp, es erscheint tatsächlich eine Exception.

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(Unknown Source)
at JARarchiver.initComponents(JARarchiver.java:163)
at JARarchiver.<init>(JARarchiver.java:20)
at JARarchiver$31.run(JARarchiver.java:1351)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
 
Dann hast Du höchstwahrscheinlich Dein(e) Bild(er) nicht mit ins JAR gepackt, bzw. nicht an die selbe Stelle.

[c]jar -tf meinejardatei.jar[/c] … listet Dir den Inhalt des Archivs auf.

Ebenius
 
Habe das Archiv mit WinRAR geöffnet.

Der Pfad der Bilder in dem von Netbeans erstellten Archiv ist identisch mit dem Pfad des von meinem Programm erstellten Archives.

Merkwürdig ist, dass wenn ich in dem Manifest z.b. zwei Buchstaben einfüge und diese wieder lösche, das Programm startet.
Das Manifest wird quasi nicht verändert, aber das Programm läuft...
 
Der Pfad ist im Programm wie folgt angegeben:

btnOeffnen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Icons/magnifier_zoom_in.png")));

In dem Archiv befindet sich der Ordner unter dem Pfad:

./Icons/
 
OK, liegt wahrscheinlich nur an dem speziellen Fall.
Ansonsten arbeitet das Programm korrekt.

Vielen Dank für die Hilfe!
 
Der Pfad ist im Programm wie folgt angegeben:

btnOeffnen.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Icons/magnifier_zoom_in.png")));

In dem Archiv befindet sich der Ordner unter dem Pfad:

./Icons/

Wo befindet sich die Klasse auf der du getClass() aufrufst?

Der Pfad den du getResource mitgibst, bezieht sich nicht auf das Rootverzeichnis deines jars sondern auf den Pfad der Klasse auf der du getClass() aufrufst.

bspl. bei

foo.Bar.getClass().getResource("blup")

muß blup im Verzeichnis foo sein.

Hat die manifest die "obligatorische Leerzeile" am Ende der Datei?
 

Zurück
Oben