Lotus Notes / Domino Sonstiges > Java und .NET mit Notes/Domino
JDBC Treiber einbinden
Axel_Janssen:
@Till_21: mit welchem Server ???
Websphere? Tomcat?
qojote:
Hi,
habs heute nochmal probiert und jetzt funzt es.
Der entscheidende Hinweis( Danke Axel ) war das der Treiber über die UserClasses kommen muß und nicht beim Agent mitgegeben werden kann.
Ich versteh bloß nicht wieso beim Kompilieren findet der alles und beim ausführen nicht mehr. Notes ist da wohl ein bisserl vergesslich :-))
Ralf:
Danke für dein Angebot mit dem Code.
Nur noch ein Tag dann genau 3 Wochen und drei Tage Urlaub.
Ist das nicht geil Leute.
Gruß
Qojote
Axel_Janssen:
--- Zitat von: qojote am 23.06.03 - 22:48:37 ---Der entscheidende Hinweis( Danke Axel ) war das der Treiber über die UserClasses kommen muß und nicht beim Agent mitgegeben werden kann.
--- Ende Zitat ---
... wobei ich dich auch erst auf die Idee gebracht habe, ihn direkt in den Agenten einzubinden... ::) ;D
--- Zitat ---Ich versteh bloß nicht wieso beim Kompilieren findet der alles und beim ausführen nicht mehr. Notes ist da wohl ein bisserl vergesslich :-))
--- Ende Zitat ---
Meine Theorie, gestützt auf Dinge, die ich im Internet gelesen habe:
Die JDBC Treiber Klasse greift auf jeden Fall über Java Native Interface auf irgendwelche c-Klassen in SQLLIB bin zu. ...vielleicht werden die irgendwie relativ eingebunden und wenn db2java.zip im Projektverzeichnis des Agenten eingebunden wird, stimmen die Pfade nicht mehr und es wird eine Runtime-Exception geworfen.
Korrigiert mich, wenn jemand genaueres weiss.
Nach dem Urlaub bitte nicht vergessen:
Code Korrektur
Der jetzige Code kann bewirken, dass das connection Objekt nicht geschlossen wird.
Folgendes Scenario:
--- Code: ---1 Connection con = jdbcDriver.connect(jdbcUrl, props);
2 Statement stmt = con.createStatement();
3 String query = "SELECT NAME FROM STAFF ORDER BY SALARY";
4 ResultSet rs = stmt.executeQuery(query);
5 while (rs.next()) {
6 System.out.println(rs.getString(1));
7 }
8 rs.close();
9 stmt.close();
10 con.close();
11 } catch (Exception e) {
12 e.printStackTrace();
13 }
--- Ende Code ---
In Zeile 1 wird die connection geöffnet. Der code läuft sequentiell ab. Irgendwo zwischen Zeile 2 und Zeile 9 zieht einer das Netzwerkkabel zum Datenbankserver. Der code kann nicht mehr auf die Datenbank zugreifen. Eine Exception wird geworfen und der Programmablauf geht in den catch-Block. Zeile 10 (Schliessen der Connection) wird dann nicht mehr aufgeführt. Nicht geschlossene Connections sind ein grosses Problem.
Deshalb:
--- Code: ---import lotus.domino.*;
import java.util.*;
import java.io.*;
import java.sql.*;
public class JavaAgent extends AgentBase {
private final String jdbcUrl = "jdbc:db2:SAMPLE"; // Syntax siehe IBM DB2 JDBC Treiber Doku
private final String jdbcUser = "db2admin"; // Name von db2-superuser auf meinem Rechner
private final String jdbcPassword = "kennwort"; // 70% aller meiner kennwörter heissen so :-)
private Driver jdbcDriver = null;
public void NotesMain() {
try {
jdbcDriver = new COM.ibm.db2.jdbc.app.DB2Driver();
Properties props = new Properties ();
props.put(jdbcUser, jdbcPassword);
Connection con = jdbcDriver.connect(jdbcUrl, props);
Statement stmt = con.createStatement();
String query = "SELECT NAME FROM STAFF ORDER BY SALARY";
ResultSet rs = stmt.executeQuery(query);
while (rs.next()) {
System.out.println(rs.getString(1));
}
rs.close();
stmt.close();
DriverManager.deregisterDriver(jdbcDriver);
} catch (Exception e) {
e.printStackTrace();
} finally {
con.close();
try {
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
--- Ende Code ---
finally wird immer ausgeführt, egal ob der Programmablauf in den catch-Block verzweigt ist, oder ob er den try-Block bis zu Ende durchlaufen hat. Würde ich auf jedenfall immer so machen. Nicht geschlossene Statement und Resultset-Objekte sind nicht so schlimm, weil weil weil weil (ich glaube die irgendwie dann mitgeschlossen werden).
schönen Urlaub
Ralf_M_Petter:
Hallo Axel!
Wo hast du das her, dass nicht geschlossene Connections ein Problem sind, denn laut Java Api Dokumentation werden Connections bei der Garbagge Collection automatisch geschlossen. Hier ein Auszug aus der Api Beschreibung. Ich mache es zwar auch imer manuell, aber eigentlich mehr aus Gewohnheit als aus wirklicher Pflicht.
close
public void close()
throws SQLException
Releases a Connection's database and JDBC resources immediately instead of waiting for them to be automatically released.
Note: A Connection is automatically closed when it is garbage collected. Certain fatal errors also result in a closed Connection.
Throws:
SQLException - if a database access error occurs
Grüße
Ralf
Axel_Janssen:
Hallo Ralf,
weil ich nicht weiss, wann die automatische garbage-collection losläuft.
Es gilt als gute Programmierpraxis, sich nicht zu stark auf dem Garbage-collector zu verlassen. Dies gilt laut Literatur explizitest für Objekte, die andere Ressourcen binden wie Netzwerk-, Datenbank- oder File-Connections
--- Code: ---Automatic garbage collection should not be perceived as a license for uninhibited creation of objects and forgetting about them. [...]
Certain objects, such as files and net connections, can tie up other resources and should be disposed of properly when they are no longer needed.
--- Ende Code ---
aus Mugal/Rasmussen: A programmers guide to java certification, S. 251f.
Dies nur als Beispiel.
Eine Datenbank-Connection bindet andere Ressourcen ausserhalb des Java Programms. Was wenn eine offene Connection existiert, der Anwender aber das Javaprogramm schliesst. Werden dann diese anderen Ressourcen freigegeben ??? Bin mir hier nicht sicher. Kann jemand was dazu sagen?
Wenn ich mich auf dem Garbage-Collector verlasse, warum dann überhaupt noch con.close()?
Wieso dies nicht einfach dem Garbage Collector überlassen? Wenn keine Referenz mehr auf das con-Objekt existiert (in unserem Beispiel am Ende der Methode NotesMain()) ist dieses Objekt eligible for garbage collection, also bräuchte ich con.close() gar nicht.
Gruss Axel
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln