Programmverhalten in IDE anders als bei externen Programmen

Status
Nicht offen für weitere Antworten.

micbur

Bekanntes Mitglied
Hallo,

ich bin auf der Suche nach einem komischen Bug und habe dabei ein merkwürdiges Verhalten beobachtet.
Also mein Bug war Folgendes:
Ich lese mit einem Java-Programm einzeln Dateien ein. Der Inhalt wird nach bestimmten Kriterien gefiltert und der Rest wird in eine neue Datei geschrieben. Nun kommt mein Bug ins Spiel. Dieses Verhalten tritt bei allen Dateien, außer der ersten auf.
Es werden die letzten sieben Zeilen der vorigen Datei an den Anfang der folgenden Datei geschrieben. Ich benutze in meinem Programm eine Queue, als Datenstrucktur eine ArrayList. Diese ArrayList soll maximal 30 Elemente lang werden. Wird ein Element an eine 30-elementige Queue gehangen, wird das erste Element gelöscht.

Kann es sein, dass eine ArrayList initial von der JVM eine Länge von sieben bekommt?

Code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.regex.Pattern;

public class LogLineQueue {
	
	private int queuelength = 30;
	private ArrayList queue = null;
	private ArrayList garbage = null;
	
	public LogLineQueue() {
		this.queue = new ArrayList(this.queuelength); 
		this.garbage = new ArrayList(0);
	}
	
	public LogLineQueue(int length) {
		this.queuelength = length;
		this.queue = new ArrayList(this.queuelength);
		this.garbage = new ArrayList(0);
	}

	public int getQueuelength() {
		return queuelength;
	}

	public void setQueuelength(int queuelength) {
		this.queuelength = queuelength;
	}
	
	/** 
	 * enqueue() schiebt Elemente wieder raus, wenn
	 * Elemente hinzugefügt werden!
	 * Vorne anfügen, hinten rausfallen. FIFO! 
	 * */
	public LogLine[] enqueue(LogLine obj) {
		
		ArrayList output_list = new ArrayList(0);
		LogLine[] out = null;
		
		while (this.queue.size() >= this.queuelength) {
			output_list.add(this.queue.get(0));
			this.queue.remove(0);
		}
		
		// conditions prüfen
		// hier werden die einzelnen Zeilen auf this.queue oder this.garbage verteilt
		// es wird this.queue.add(Object) und this.garbage.add(Object) benutzt

        // Work-A-Round, als Array von der ArrayList zurückbekommen hat nicht funktioniert, wird mit O(n) Aufwand selbst gemacht. 
		out = new LogLine[output_list.size()];
		for (int i = 0; i < output_list.size(); i++) {
			out[i] = (LogLine) output_list.get(i);
		}
		for (int i = 0; i < output_list.size(); i++ ) {
			output_list.remove(0);
		}
		return out;

	}
	
	public boolean contains(LogLine arg) {
		LogLine current = null;
		Iterator i = this.queue.iterator();
		while (i.hasNext()) {
			current = (LogLine) i.next();
			if (current.compareTo(arg) == 0) {
				return true;
			}
		}
		return false;
	}
	
	public LogLine[] getGarbage() {
		
		LogLine[] out = new LogLine[garbage.size()];
		for (int i = 0; i < garbage.size(); i++) {
			out[i] = (LogLine) this.garbage.get(i);
		}
		for (int i = 0; i < this.garbage.size(); i++) {
			this.garbage.remove(0);
		}
		
		this.garbage = null;
		this.garbage = new ArrayList(0);
		
		return out;
	}
	
	public LogLine[] empty() {
		LogLine[] out = new LogLine[this.queue.size()];
		for (int i = 0; i < this.queue.size(); i++) {
			out[i] = (LogLine) this.queue.remove(0);
		}
		for (int i = 0; i < this.queue.size(); i++) {
			this.queue.remove(0);
		}
		this.queue = null;
		this.queue = new ArrayList(0);
		
		return out;
	}
	

}

Aufgerufen wird diese Klasse in einem Thread

Code:
public void run() {

		BufferedReader readfilein  = null;
		BufferedWriter new_logfile = null;
		BufferedWriter garbagefile = null;
		String one_line            = null;

		LogLine[] loglines_arr     = null;
		StringBuffer buffer        = new StringBuffer();
		LogLine current            = null;

		int processed = 0;
		int filtered  = 0;

		try {
			readfilein = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream(this.logfilename))));
			new_logfile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(this.logfilename + ".mod")));

			one_line = readfilein.readLine();

			while(one_line != null) {

				current = new LogLine(one_line);
				// work-a-round für Logzeilen, die kürzer als 14 Spalten sind, z.B. Headerzeilen der Logfiles
				/*
				public class LogLine implements Comparable {
				    private String payload  = null;
				    private String timestamp = null;
				...
			    }
				*/
				if (current.getPayload() == null) {
					current.setTimestamp("");
					current.setPayload(one_line);
				}

				// die erzeugte LogLine zur Queue hinzufügen
				// Rückgabewert der Queue ist der Überhang der Queue. 
				// Regel: Wird das 31te Element an eine 30-stellige Queue übergeben, fällt das erste Element raus. 
				loglines_arr = this.window.enqueue(current);

				// Queue zurück in das neue Log schreiben
				for (int i = 0; i < loglines_arr.length; i++ ) {
					if (loglines_arr[i] != null) {
						processed++;
						buffer.append(loglines_arr[i].getLogline() + System.getProperty("line.separator", "\n\r"));
					}
				}

				// da zuerst ein Buffer gefüllt wird, muss dieser immer zurück in Dateien geschrieben werden. 
				// Der Buffer soll eine bestimmte Mindestgröße erreichen, bevor er geschrieben wird. 
				if (buffer.length() > this.writeBufferSize) {
					new_logfile.write(buffer.toString());
					buffer.delete(0, buffer.length());
					new_logfile.flush();
				}
				new_logfile.flush();

				// erneut eine Zeile einlesen, Scheife nochmal durchlaufen
				one_line = readfilein.readLine();
			}

			new_logfile.write(buffer.toString());
			buffer.delete(0, buffer.length());

			// die letzten LogLines aus der Queue holen & in den Buffer schrieben
			loglines_arr = this.window.empty();
			for (int i = 0; i < loglines_arr.length; i++ ) {
				if (loglines_arr[i] != null) {
					processed++;
					buffer.append(loglines_arr[i].getLogline() + System.getProperty("line.separator", "\n\r"));
				}
			}
			new_logfile.flush();

			new_logfile.write(buffer.toString());
			buffer.delete(0, buffer.length());
			buffer = new StringBuffer("");
			buffer = null;
			new_logfile.flush();
			new_logfile.close();

			this.filtered_counter = filtered;
			this.processed_counter = processed;
			
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		
	}

Vielleicht sieht ja jemand meinen Bug. Ich habe ihn nicht gefunden bisher.

Dann zum Verhalten der IDE. Wenn ich mein bugbehaftetes Programm in der IDE ablaufen lasse, dann gibt es den Fehler nicht. Alle Zeilen sind in den Dateien, wo sie hin sollen. Ich benutze Eclipse 3.1 auf Java 1.5.0 Update 6.


Ciao, micbur
 
Ist mir jetzt zu viel Code zum auf die schnelle durchgehen.
Versuch erstmal mittles Debugger das Problem einzugrenzen.
Zu deiner Frage:
Wenn du keinen Paramter übergibst der das Defaultverhalten ändert wird eine ArrayList mit 10 initialisiert.
 
Hallo,

der Debugger bringt mir leider nichts. Der läuft ja auch in der IDE und da taucht kein Fehler auf ;-)

Schade.

Ciao, micbur
 
Status
Nicht offen für weitere Antworten.

Zurück
Oben