<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>freakcommander.de &#187; Computer</title>
	<atom:link href="http://www.freakcommander.de/category/computer/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.freakcommander.de</link>
	<description>Kann alles. Weiß alles. Macht alles.</description>
	<lastBuildDate>Thu, 29 Jul 2010 09:04:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Performancevergleich: Enzelne SQL-Statements vs. MySQL LOAD DATA INFILE vs. Prepared Statements</title>
		<link>http://www.freakcommander.de/2915/computer/java/performancevergleich-mysql-load-data-infile-vs-einzelne-sql-statements/</link>
		<comments>http://www.freakcommander.de/2915/computer/java/performancevergleich-mysql-load-data-infile-vs-einzelne-sql-statements/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 13:50:31 +0000</pubDate>
		<dc:creator>crille</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Datenmenge]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PreparedStatements]]></category>

		<guid isPermaLink="false">http://www.freakcommander.de/?p=2915</guid>
		<description><![CDATA[Performance: Einzelne SQL-Statements Was macht das Programm? Aus einer gro&#223;en XML-Datei werden per SAXParser Datens&#228;tze eingelesen. Insgesamt gibt es 1.109.270 &#8220;Datens&#228;tze&#8221; in der XML-Datei. Aus jedem Datensatz werden 2 SQL-Queries erzeugt: Ein REPLACE-Statement zum Einf&#252;gen/Aktualsieren von Stammdaten und ein INSERT-Statement zum Einf&#252;gen von Bewegungsdaten Es werden also kontinuierlich SQL-Statements abgesetzt. Laufzeit des Programms 41 Minuten [...]]]></description>
			<content:encoded><![CDATA[<h2>Performance: Einzelne SQL-Statements</h2>
<p>Was macht das Programm?</p>
<ol>
<li>Aus einer gro&#223;en XML-Datei werden per <a href="http://de.wikipedia.org/wiki/Simple_API_for_XML">SAXParser</a> Datens&#228;tze eingelesen. Insgesamt gibt es <strong>1.109.270 &#8220;Datens&#228;tze&#8221;</strong> in der XML-Datei.</li>
<li>Aus jedem Datensatz werden 2 SQL-Queries erzeugt: Ein REPLACE-Statement zum Einf&#252;gen/Aktualsieren von Stammdaten und ein INSERT-Statement zum Einf&#252;gen von Bewegungsdaten</li>
</ol>
<p>Es werden also kontinuierlich SQL-Statements abgesetzt.</p>
<h3>Laufzeit des Programms</h3>
<p><span style="color: #ff0000;"><strong>41 Minuten und 36 Sekunden</strong></span></p>
<h2>Performance: Generierung der CSV-Datei &amp; LOAD DATA INFILE</h2>
<p>Was macht das Programm?</p>
<ol>
<li>(identisch mit vorherigem Programm:) Aus einer gro&#223;en XML-Datei werden per <a href="http://de.wikipedia.org/wiki/Simple_API_for_XML">SAXParser</a> Datens&#228;tze eingelesen. Insgesamt gibt es <strong>1.109.270 &#8220;Datens&#228;tze&#8221;</strong> in der XML-Datei.</li>
<li>Aus jedem Datensatz werden 2 CSV-Dateien um einen Datensatz erweitert. Die erste Datei enth&#228;lt die Daten f&#252;r die Stammdaten-Tabelle, die zweite Datei enth&#228;lt die Bewegungsdaten.</li>
<li>Zwei LOAD DATA INFILE Befehle zum Einlesen der CSV-Dateien.</li>
</ol>
<p>Das Programm erzeugt also zuerst 2 Dateien und greift erst zum Schluss auf die Datenbank zu.</p>
<h3>Laufzeit des Programms</h3>
<p><span style="color: #ff0000;"><strong>30 Minuten und 9 Sekunden</strong></span></p>
<h2><span style="color: #ff0000;"><span style="color: #000000;">Performance: Nur </span></span>LOAD DATA INFILE</h2>
<p>Wenn wir annehmen, dass die 2 CSV-Dateien schon vorhanden sind und nur noch die LOAD DATA INFILE-Befehle ausgef&#252;hrt werden m&#252;ssen, so sind die immerhin 2.218.540 Datens&#228;tze innerhalb von</p>
<p><span style="color: #ff0000;"><strong>2 Minuten und 23 Sekunden</strong></span></p>
<p>importiert.</p>
<h2>Performance: Prepared Statements</h2>
<p><a href="http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html">Prepared Statements</a> sollten nicht nur aus sicherheitsrelevanten &#220;berlegungen eingesetzt werden, sondern bringen &#8211; richtig implementiert &#8211; auch einen Performance-Vorteil. Dieser Vorteil l&#228;sst sich so erkl&#228;ren, dass 1x das SQL-Statement mit &#8220;?&#8221; als Platzhalter an das DBMS &#252;bertragen wird und danach werden f&#252;r jeden Datensatz nur noch die Parameter &#252;bertragen, die in die entsprechenden Platzhalter durch das DBMS eingef&#252;gt werden. Es fallen also weniger zu &#252;bertragene Daten an, aber vor allem k&#246;nnen die Daten so &#252;bertragen und verarbeitet werden, dass sie nicht mehr durch das DB-System interpretiert bzw. konvertiert werden m&#252;ssen. Das Ergebnis kann sich sehen lassen:</p>
<p>Das Programm ist identisch mit dem Programm, welches kontinuierlich, einzelne SQL-Statements absetzt. Allerdings ist es so programmiert, dass es die Performance-Vorteile der Prepared Statements nutzt.</p>
<h3>Laufzeit des Programms</h3>
<p><span style="color: #ff0000;"><strong>28 Minuten und 30 Sekunden</strong></span></p>
<h2>Fazit</h2>
<p>Bei so gro&#223;en Datenmengen, die sequentiell eingelesen werden, kommt es auf die richtige Wahl der Methode an:</p>
<p><span style="color: #339966;"><strong>Vorteile Prepared Statements:</strong></span></p>
<ul>
<li>sind einfach zu implementieren</li>
<li>sind  im Performance-Vergleich noch ein St&#252;ck weit schneller als CSV-Dateien zu erstellen und per LOAD DATA INFILE einzulesen</li>
</ul>
<p><span style="color: #ff0000;"><strong>Nachteile Prepared Statements:</strong></span></p>
<ul>
<li>die Datenbank wird &#252;ber die gesamte Zeit stark belastet</li>
</ul>
<p><span style="color: #339966;"><strong>Vorteile Generierung von CSV &amp; LOAD DATA INFILE:</strong></span></p>
<ul>
<li>die Datenbank wird nur f&#252;r kurze Zeit beansprucht</li>
<li>die CSV-Datei kann nach dem Generieren gespeichert bleiben und zu Diagnosezwecke bzw. wiederholten Datenimport verwendet werden</li>
</ul>
<p><span style="color: #ff0000;"><strong>Nachteile <strong>Generierung von CSV &amp;</strong> LOAD DATA INFILE:</strong></span></p>
<ul>
<li>kompliziertere Implementierung</li>
<li>zus&#228;tzlicher Festplattenverbrauch durch CSV-Dateien</li>
<li>geringf&#252;gig langsamer als Prepared Statements</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.freakcommander.de/2915/computer/java/performancevergleich-mysql-load-data-infile-vs-einzelne-sql-statements/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Java: Erstellen gro&#223;er CSV-Dateien zum Datenbank-Import</title>
		<link>http://www.freakcommander.de/2905/computer/java/java-erstellen-grosser-csv-dateien-zum-datenbank-import/</link>
		<comments>http://www.freakcommander.de/2905/computer/java/java-erstellen-grosser-csv-dateien-zum-datenbank-import/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 17:05:49 +0000</pubDate>
		<dc:creator>crille</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[CSV]]></category>
		<category><![CDATA[Datenmenge]]></category>
		<category><![CDATA[Geschwindigkeit]]></category>
		<category><![CDATA[Klasse]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://www.freakcommander.de/?p=2905</guid>
		<description><![CDATA[Anstatt Millionen von INSERT oder UPDATE-Befehlen an die Datenbank zu schicken, um eine Tabelle zu aktualisieren, bietet es sich bei gro&#223;en Datenmengen an, eine CSV-Datei zu erstellen, welche dann &#252;ber LOAD DATA INFILE mit extrem hoher Geschwindigkeit eingelesen wird. Erstellen von CSV-Dateien mit Java In Java bietet sich zum Erstellen von CSV-Dateien die Klasse Super [...]]]></description>
			<content:encoded><![CDATA[<p>Anstatt Millionen von INSERT oder UPDATE-Befehlen an die Datenbank zu schicken, um eine Tabelle zu aktualisieren, bietet es sich bei gro&#223;en Datenmengen an, eine CSV-Datei zu erstellen, welche dann &#252;ber <a href="http://dev.mysql.com/doc/refman/5.1/de/load-data.html">LOAD DATA INFILE</a> mit extrem hoher Geschwindigkeit eingelesen wird.</p>
<h2>Erstellen von CSV-Dateien mit Java</h2>
<p>In Java bietet sich zum Erstellen von <a href="http://de.wikipedia.org/wiki/CSV_%28Dateiformat%29">CSV-Dateien</a> die Klasse <a href="http://supercsv.sourceforge.net/">Super CSV</a> an. Um eine Datei zu erzeugen, ben&#246;tigt man als erstes einen CSVMapWriter:</p>
<pre class="brush: java">CsvMapWriter writer = new CsvMapWriter(new OutputStreamWriter(new FileOutputStream(&quot;C:\meineDatei.csv&quot;, true),&quot;UTF-8&quot;), CsvPreference.EXCEL_PREFERENCE);</pre>
<p>Anstatt mit einem OutputStreamWriter zu arbeiten, kann man auch einen FileWriter verwenden. Da man bei letzterem aber kein Encoding (&#8220;UTF-8&#8243;) angeben kann und in der Datenbank die Zeichen UTF-8-kodiert sind, m&#252;ssen wir den Stream verwenden.<br />
Interessant ist der zweite Parameter des FileOutputStream, der angibt, dass die Daten, die eingef&#252;gt werden, angeh&#228;ngt werden und nicht vorher gel&#246;scht werden.<br />
Die Einstellung CsvPreference.EXCEL_PREFERENCE legt fest, welche Trennzeichen in der CSV-Datei verwendet werden &#8211; wenn man andere Trennzeichen verwenden m&#246;chte, muss der sp&#228;ter behandelte LOAD DATA INFILE-Befehl angepasst werden.</p>
<p>Als n&#228;chstes werden die Textfelder f&#252;r die CSV-Datei definiert:</p>
<pre class="brush: java">final String[] header = new String[] { &quot;id&quot;, &quot;name&quot;, &quot;adressfeld&quot; };</pre>
<p>Unsere Datens&#228;tze bestehen also aus 3 Feldern.</p>
<p>Um die CSV-Datei mit Daten zu f&#252;llen sind folgende Zeilen notwendig:</p>
<pre class="brush: java">final HashMap&lt;String, ? super Object&gt; data = new HashMap&lt;String, Object&gt;();
data.put(header[0], this.id);
data.put(header[1], this.name);
this.adressfeld = this.adressfeld.replace(&quot;\\&quot;, &quot;\\\\&quot;);
data.put(header[2], this.adressfeld);</pre>
<p>Die Daten werden in einer HashMap gespeichert und per data.put eingef&#252;gt. Was mich etwas &#252;berraschte war, dass man das Backslash maskieren muss, ansonsten geht es in der Verarbeitung verloren. Eigenartig, weil man diese Funktionalit&#228;t sicherlich problemlos in Super CSV h&#228;tte integrieren k&#246;nnen.</p>
<p>Abschlie&#223;end werden die Daten dem CSVMapWriter &#252;bergeben und dieser wieder geschlossen:</p>
<pre class="brush: java">writer.write(data, header);
writer.close();</pre>
<h3>Und mehrere Datens&#228;tze?</h3>
<p>Obiges Beispiel ist f&#252;r einen einzelnen Datensatz, der in einer CSV-Datei gespeichert wird. Wenn man mehrere Datens&#228;tze einf&#252;gen m&#246;chte, m&#252;ssen s&#228;mtliche Schritte (Anlegen eines CSVMapWriter, Daten vorbereiten, Daten einf&#252;gen) f&#252;r jeden Datensatz wiederholt werden.</p>
<p>Den CSVMapWriter 1x anzulegen und am Ende per .close zu schlie&#223;en, funktioniert nicht &#8211; meine Versuche mit der Super CSV-Klasse haben gezeigt, dass dann Datens&#228;tze verloren gehen bzw. abgeschnitten werden.</p>
<h2>Einlesen der CSV mit LOAD DATA INFILE</h2>
<p>Um die so erstellte Datei mit <a href="http://dev.mysql.com/doc/refman/5.1/de/load-data.html">LOAD DATA INFILE</a> in die Datenbank zu importieren, muss folgender Befehl eingetragen werden:</p>
<pre class="brush: sql">LOAD DATA [LOCAL] INFILE &#039;C:\\meineDatei.csv&#039;
[REPLACE]
INTO TABLE meine_tabelle
FIELDS TERMINATED BY &#039;,&#039;
OPTIONALLY ENCLOSED BY &#039;\&quot;&#039;
LINES TERMINATED BY &#039;\n&#039;
(id, name, adressfeld);</pre>
<p>Vorab: Der Befehl wird so nicht funktionieren, da die Bestandteile innerhalb der eckigen Klammern optional sind:</p>
<ul>
<li>LOCAL wird dann angegeben, wenn die CSV-Datei vom Clientprogramm auf dem Clienthost gelesen und an den MySQL-Server geschickt wird. Fehlt LOCAL, liegt die Datei auf dem MySQL-Server</li>
<li>REPLACE nutzt man, wenn die eingelesene Datei nicht nur neue Datens&#228;tze importiert, sondern auch bereits vorhandene &#252;berschreibt &#8211; also UPDATES durchf&#252;hrt</li>
</ul>
<p>Alle/Weitere Optionen zu dem LOAD DATA INFILE-Befehl gibt es im <a href="http://dev.mysql.com/doc/refman/5.1/de/load-data.html">MySQL-Handbuch</a>.</p>
<h2>Performancevergleich</h2>
<p><a href="http://www.freakcommander.de/2915/computer/java/performancevergleich-mysql-load-data-infile-vs-einzelne-sql-statements/">Ein Performancevergleich ist hier</a> zu finden.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freakcommander.de/2905/computer/java/java-erstellen-grosser-csv-dateien-zum-datenbank-import/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Java: Falscher ResultSet.getter verursacht Memory Leak</title>
		<link>http://www.freakcommander.de/2892/computer/java/java-falscher-resultset-getter-verursacht-memory-leak/</link>
		<comments>http://www.freakcommander.de/2892/computer/java/java-falscher-resultset-getter-verursacht-memory-leak/#comments</comments>
		<pubDate>Thu, 22 Jul 2010 22:43:48 +0000</pubDate>
		<dc:creator>crille</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Klasse]]></category>
		<category><![CDATA[Memory Leak]]></category>
		<category><![CDATA[notebook]]></category>
		<category><![CDATA[Speicherleck]]></category>

		<guid isPermaLink="false">http://www.freakcommander.de/?p=2892</guid>
		<description><![CDATA[Ich bin ein G&#228;nsebl&#252;mchen im Sonnenschein und durch meine Bl&#252;te flie&#223;t die Sonne in mich rein Ich bin ein G&#228;nsebl&#252;mchen und mir wird ganz warm ich k&#246;nnt die ganze Welt und dann mich selbst umarmen. Ich bin ein G&#228;nsebl&#252;mchen ohne Aggression Wut, &#196;rger &#8211; was bringt das schon? Durchatmen, Freakcommander! Momentan gehst du durch die [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Ich bin ein G&#228;nsebl&#252;mchen im Sonnenschein<br />
und durch meine Bl&#252;te flie&#223;t die Sonne in mich rein<br />
Ich bin ein G&#228;nsebl&#252;mchen und mir wird ganz warm<br />
ich k&#246;nnt die ganze Welt und dann mich selbst umarmen.<br />
Ich bin ein G&#228;nsebl&#252;mchen ohne Aggression<br />
Wut, &#196;rger &#8211; was bringt das schon?</p></blockquote>
<p><a href="http://www.freakcommander.de/wp-content/uploads/2010/07/java.png"><img class="alignright size-full wp-image-2893" title="Java" src="http://www.freakcommander.de/wp-content/uploads/2010/07/java.png" alt="Java" width="100" height="189" /></a>Durchatmen, Freakcommander! <a href="http://www.freakcommander.de/2888/computer/java/liefert-mich-ein-sofort/">Momentan</a> gehst du durch die harte Schule einer dir immer noch relativ unbekannten Sprache. Da f&#228;llt man mal hin und muss wieder aufstehen, ansonsten wird das nichts.</p>
<h2>Die Vorgeschichte</h2>
<p>Aber man muss zugegeben, dass der heutige Fehler nicht ganz so leicht zu finden war:</p>
<ul>
<li>Ich habe die <em>Klasse Host</em> umgeschrieben. Vorher hat sie einfach per Methode <em>.toDB()</em> ihre Attribute in die Datenbank geschrieben. Nach dem Umschreiben soll sich die Klasse nur dann in die Datenbank schreiben, wenn sie entweder noch nicht in der DB ist oder ein Attribut sich ver&#228;ndert hat und die DB somit aktualisiert werden muss.<br />
<strong>Grund f&#252;r das Umschreiben</strong>: Innerhalb eines Programmaufrufs werden hintereinander Millionen Instanzen erzeugt und geguckt, ob sie sich ver&#228;ndert haben. Wenn das der Fall ist, muss der Eintrag auch in der DB aktualisiert werden. Da aber UPDATE oder INSERT-Befehle teurer sind und nur ein sehr kleiner Teil der Millionen Eintr&#228;ge sich auch wirklich ver&#228;ndern, macht eine &#220;berpr&#252;fung, ob ein UPDATE oder INSERT erfolgen muss, definitiv Sinn.</li>
<li>Wie bin ich vorgegangen?
<ol>
<li>Eine Methode <em>.getFromDB</em>, die die &#8220;alten&#8221; Daten aus der DB liest</li>
<li>Eine Methode <em>.equals</em>, die eine Instanz des Objekts mit einer anderen Instanz vergleicht und TRUE zur&#252;ck gibt, wenn die Attribute gleich sind</li>
<li>Die alte Methode <em>.toDB()</em> dementsprechend angepasst. Einziges Manko war, dass ich in dieser Methode eine Instanz des eigenen Objektes anlegen musste &#8211; diese angelegte Instanz des eigenen Objekts bekommt mittels <em>.getFromDB</em>() die alten Daten verabreicht und wird dann mit <em>.equals</em> verglichen.</li>
</ol>
</li>
<li>Das Anpassen des Quellcodes war schnell erledigt. Das gro&#223;e Problem war nun allerdings, dass die Anwendung jetzt ein Speicherleck hatte. Der benutzte Speicher wuchs und wuchs und endete schlie&#223;lich in einer Exception.</li>
<li>Anstatt mich direkt mit dem Code zu besch&#228;ftigen und durch auskommentieren und System.out.println-Meldungen dem Problem auf die Schliche zu kommen, besch&#228;ftigte ich mich mit der Literaturrecherche zu Memory Leaks, Speicherlecks, Garbage Collector und <a href="http://www.eclipse.org/mat/">Eclipse Memory Analyzern</a> oder <a href="https://visualvm.dev.java.net/">VisualVM</a>, einem Tool, das eine Realtime Heap-Usage Analyse verspricht.</li>
<li>Beim <a href="http://www.eclipse.org/mat/">Eclipse Memory Analyzer</a> funktionierte das Generieren der .hprof-Datei nicht, die man braucht, um den Analyzer einzusetzen.</li>
<li>Und die <a href="https://visualvm.dev.java.net/">VisualVM</a> ist sicherlich ein tolles Tool, aber mein uralt Notebook, welches zu wenig RAM und CPU-Leistung hat, arbeitet so langsam mit der VisualVM, dass beim Start schon der Java-Prozess mit meiner Anwendung, die den Memory Leak hat, verschwunden war. So konnte ich leider keinen Memory-Monitorer einschalten oder den Heap dumpen.. No chance.</li>
<li>Und nach stundenlanger Recherche und antesten etlicher Tools, um einem Speicherleck in Java zu begegnen, bekam ich schon wieder dieses Gef&#252;hl: Wie kann es sein, dass eine Programmiersprache, die millionenfach eingesetzt wird, kein einfach zu installierendes Tool hat, welches automatisch die Daten sammelt, um einem dann vorzuschlagen, welche Klassen oder Methoden man sich nochmal genauer anschauen sollte, um das Speicherleck zu schlie&#223;en. Wenn in Foren ein Programmierer Probleme mit einem Tool hat, wird ihm einfach ein anderes Tool empfohlen, welches &#228;hnlich ist und bei ihm laufen sollte. Na ja, ich hatte keinen Bock mehr mich durch irgendwelche Seiten und Tools zu klicken.</li>
<li>Das Problem war an irgendeiner Stelle in meinem Code, also finde ich einfach die Stelle und behebe das Problem.</li>
<li>Nachdem ich sichergestellt hatte, dass s&#228;mtliche Statements, PreparedStatements, ResultSets und Connections nach getaner Arbeit auch wieder geschlossen wurden und das Problem nach wie vor auftrat, k&#252;mmerte ich mich um die Instanz, die innerhalb der <em>.toDB()-</em>Methode erzeugt wird. Vielleicht werden ganz viele Instanzen erzeugt, die der Garbage Collector aus irgendwelchen Gr&#252;nden nicht l&#246;schen kann. Aber auch daran lag es nicht.</li>
<li>Schlie&#223;lich ging ich dazu &#252;ber ganze Funktionen und Programmteile auszukommentieren. Folgender Programmcode verursachte das Speicherleck</li>
</ul>
<h2>Der Fehler</h2>
<p>In der Methode <em>.getFromDB</em>(), die einfach nur per DB-Query Daten einliest, gab es folgende 3 Zeilen Code, die Grund f&#252;r das Memory Leak waren:</p>
<pre class="brush: java">this.setM_swap(rs.getInt(16));
this.setD_total(rs.getInt(17));
this.setD_free(rs.getInt(18));</pre>
<p>Aus dem ResultSet der DB-Abfrage werden per Setter-Methoden die Attribute gesetzt. Das Problem? Da die Java-Datentypen und die DB-Felder f&#252;r m_swap, d_total und d_free mit Integer bzw. int nicht ausreichend lang waren, habe ich sie nachtr&#228;glich auf long bzw. Bigint (DB) ge&#228;ndert. Dabei habe ich auch die setter wie <em>setM_swap()</em> so ge&#228;ndert, dass sie als Parameter long erwarten.  Normalerweise schreit ja gleich das IDE los, wenn ein Typ nicht passt, aber Java findet (und in diesem Fall v&#246;llig zu Recht), dass Methoden, die long als Parameter erwarten, auch mit int gef&#252;ttert werden k&#246;nnen und hat deswegen nicht gemeckert.</p>
<p>Das Memory Leak kann ich mir nur so erkl&#228;ren, dass mit rs.getInt auf eine Spalte zugegriffen wurde, welche in der Datenbank als BigInteger definiert ist.</p>
<p>Richtigerweise h&#228;tte man mit <em>rs.getLong()</em> arbeiten m&#252;ssen, dann gibt es auch keine Probleme mit dem Speicher. ;)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freakcommander.de/2892/computer/java/java-falscher-resultset-getter-verursacht-memory-leak/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Liefert mich ein! Sofort!</title>
		<link>http://www.freakcommander.de/2888/computer/java/liefert-mich-ein-sofort/</link>
		<comments>http://www.freakcommander.de/2888/computer/java/liefert-mich-ein-sofort/#comments</comments>
		<pubDate>Wed, 21 Jul 2010 16:50:20 +0000</pubDate>
		<dc:creator>crille</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[Projekt]]></category>
		<category><![CDATA[Uni]]></category>

		<guid isPermaLink="false">http://www.freakcommander.de/?p=2888</guid>
		<description><![CDATA[Das Leben ist hart, grausam und gemein! Und heute ist es noch ein bi&#223;chen fieser als sonst. Ich wage mich gerade in die Tiefen von Java vor. Zwar hatte ich in der Uni etliche Kurse zur Java-Programmierung, aber man ist erst in einer Programmiersprache richtig drin, wenn man etwas gr&#246;&#223;eres damit erstellen muss. Das Problem [...]]]></description>
			<content:encoded><![CDATA[<p>Das Leben ist hart, grausam und gemein! Und heute ist es noch ein bi&#223;chen fieser als sonst.</p>
<p>Ich wage mich gerade in die Tiefen von Java vor. Zwar hatte ich in der Uni etliche Kurse zur Java-Programmierung, aber man ist erst in einer Programmiersprache richtig drin, wenn man etwas gr&#246;&#223;eres damit erstellen muss. Das Problem ist nur, dass man immer wieder an seine sprachlichen Grenzen st&#246;&#223;t, viel nachschlagen muss und sich auch mit der Komplilierung &amp; Ausf&#252;hrung von Java nicht wirklich auskennt. Theoretisch ist alles klar, aber das Praktische ist meist etwas komplizierter als gedacht.</p>
<p>Nachdem ich die letzten Tage etliche Zeilen Java-Code geschrieben hatte, wollte ich mich heute ran setzen und das Ganze von meinem lokalen Eclipse auf den Server bringen. Ich machte mir ein wenig Sorgen, ob ich die DB-Verbindung auf einer Linux-Maschine zum Laufen kriegen w&#252;rde, zudem nutzte ich ein paar externe Java-Bibliotheken (jar), deren Pfade ja schlie&#223;lich auch angepasst werden mussten.</p>
<ul>
<li>Mein erster Ansatz einfach die Export-Funktion von Eclipse zu nutzen und das Ding in eine jar-Datei zu exportieren, funktionierte nicht. Die referenzierten Bibliotheken waren nicht bekannt.</li>
<li>Der Versuch die Angaben der .classpath-Datei im Editor auf die Serverpfade anzupassen und dann in Eclipse zu kompilieren, schlug auch fehl, da Eclipse die referenzierten Bibliotheken nicht mehr finden konnte.</li>
<li>Auch die Idee beim CL-Aufruf den classpath mit zu &#252;bergeben, brachte kein Erfolg</li>
<li>Ich landete dann auf der <a href="http://www.torsten-horn.de/techdocs/java-eclipse.htm#Export-als-jar">Seite von Thorsten Stein</a>, der mit <a href="http://ant.apache.org/">Apache Ant</a> arbeitet, um eine Jar mit zus&#228;tzlichen Libraries zu bauen.</li>
<li>Mir kam das zu kompliziert vor. Ich wollte doch nur etwas umsetzen, was Millionen Java-Entwickler Tag f&#252;r Tag machen: Ein Projekt kompilieren, welches zus&#228;tzliche Libraries verwendet. Das kann doch nicht so kompliziert sein!!!</li>
<li>Aber anscheinend ist es das: Ich landete schlie&#223;lich bei <a href="http://fjep.sourceforge.net/">FatJar</a> einem Plugin f&#252;r Eclipse, welches sich daf&#252;r r&#252;hmt, ein Jar erstellen zu k&#246;nnen, welches weitere Jars enth&#228;lt. Genau das, was ich wollte. Aber auch hier geschah nicht das, was ich wollte.</li>
<li>Langsam verzweifelte ich. Rufe ich vielleicht einfach nur mein Programm falsch auf? <em>java -jar meineAnwendung.jar</em> &#8211; Das muss doch richtig sein!</li>
<li>Die Stunden vergingen und ich machte absolut gar keine Fortschritte und offensichtlich gab es im Internet auch kaum jemanden, der &#228;hnliche Probleme hatte. Es gab zwar viele Suchergebnisse, aber da waren die Probleme meist anders gelagert&#8230;</li>
<li>Ich entschloss mich, das <a href="http://www.torsten-horn.de/techdocs/java-eclipse.htm#Export-als-jar">Tutorial von Thorsten Stein</a> abzuarbeiten. Toll: Ant installieren. Toll: Ant braucht JDK. Toll: JDK installieren!</li>
<li>Ich erhielt schlie&#223;lich die jar mit den externen Libs und lud es auf den Server. Ich f&#252;hrte es aus. Wieder nichts.</li>
<li>Ich war mit meinem Latein am Ende. Seit 7 Stunden sa&#223; ich an diesem Problem und bekam es nicht gel&#246;st.</li>
<li>Komisch, dass der Logger, den ich in meiner Anwendung verwende, eine leere Datei erzeugt. Moment! K&#246;nnte es sein, dass das Programm doch ausgef&#252;hrt wird und nichts macht, weil es nichts gibt, was es machen muss?<br />
Ja, denn das Ergebnis dieser Abfrage ist auf dem Server leer:<br />
<code lang=java>ResultSet rs = stmt.executeQuery("SELECT idprojects FROM projects WHERE download_url IS NOT NULL AND short_name IS NOT NULL AND (status != 1 OR status != 6)");<br />
while (rs.next()){<br />
	Project pro = new Project(rs.getInt(1));<br />
	pro.update();<br />
}</code></li>
</ul>
<p>Ich hatte also den ganzen Tag damit zugebracht, einen Fehler zu finden, den es gar nicht gibt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.freakcommander.de/2888/computer/java/liefert-mich-ein-sofort/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linux</title>
		<link>http://www.freakcommander.de/2819/computer/linux/</link>
		<comments>http://www.freakcommander.de/2819/computer/linux/#comments</comments>
		<pubDate>Wed, 30 Jun 2010 15:34:17 +0000</pubDate>
		<dc:creator>crille</dc:creator>
				<category><![CDATA[Computer]]></category>
		<category><![CDATA[Anleitung]]></category>
		<category><![CDATA[Konsolenbefehlen]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Student]]></category>
		<category><![CDATA[Virtualbox]]></category>
		<category><![CDATA[wlan]]></category>

		<guid isPermaLink="false">http://www.freakcommander.de/?p=2819</guid>
		<description><![CDATA[Ich bin ja bekennender Windows Nutzer. Eigentlich untypisch f&#252;r einen Informatik-Studenten, die ja sehr oft zu der Ultra-Linux-User-Fraktion z&#228;hlen. Meine Abneigung gegen&#252;ber Linux ist vor allem aus meiner Faulheit (never change a running system) und meiner Ansicht gewachsen, dass ein Betriebssystem einfach nur zu funktionieren hat. Nein, ich will mich nicht stundenlang mit irgendwelchen Treibern, [...]]]></description>
			<content:encoded><![CDATA[<p>Ich bin ja bekennender Windows Nutzer. Eigentlich untypisch f&#252;r einen Informatik-Studenten, die ja sehr oft zu der Ultra-Linux-User-Fraktion z&#228;hlen.</p>
<p>Meine Abneigung gegen&#252;ber Linux ist vor allem aus meiner Faulheit (never change a running system) und meiner Ansicht gewachsen, dass ein Betriebssystem einfach nur zu funktionieren hat. Nein, ich will mich nicht stundenlang mit irgendwelchen Treibern, Wrappern oder sonstwas rum&#228;rgern. Plug &amp; Play funktioniert bei Windows nach anf&#228;nglichen Problemen (Plug &amp; Pray) sehr gut, bei Linux stellt mich die Installation eines WLAN USB-Sticks vor ungeahnte Probleme &#8211; da gibt es zig verschiedene Anleitungen f&#252;r unterschiedlichste Revisions des Sticks und keine funktioniert. Das Schlimmste ist aber, dass man kaum etwas aus diesen Anleitungen lernt, weil es oft nur Auflistungen von Konsolenbefehlen sind. Was die machen?!?</p>
<p>Im Forum habe ich diesen Kommentar zu Linux gelesen und dem schlie&#223;e ich mich ganz an:</p>
<blockquote><p>Lachhaft! Das System ist allenfalls zum Einsatz in geschlossen psychiatrischen Anstalten zu gebrauchen: Die Insassen k&#246;nnen mit einfachsten Aufgaben wochenlang besch&#228;ftigt werden und das System bietet eine prima Gelegenheit zur gefahrlosen Kanalisierung von Aggressionen. Au&#223;erdem wird durch den Erfahrungsaustausch der Insassen deren soziale und kommunikative Kompetenz gest&#228;rkt.</p></blockquote>
<p>Wie ich nun meinen WLAN USB-Stick unter Linux zum Laufen gebracht habe? Ich habe Virtualbox installiert und emuliere per Netzwerkbr&#252;cke vom WLAN USB Stick eine Ethernet-Karte, die Linux ohne Probleme nutzen kann&#8230; Super, oder?!?</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px; overflow: hidden;">http://www.youtube.com/watch?v=SBgZNINN6MU</div>
]]></content:encoded>
			<wfw:commentRss>http://www.freakcommander.de/2819/computer/linux/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
