Autor Thema: JDBC Treiber einbinden  (Gelesen 14776 mal)

Offline qojote

  • Aktives Mitglied
  • ***
  • Beiträge: 229
  • I love YaBB 1G - SP1!
JDBC Treiber einbinden
« am: 19.06.03 - 01:35:26 »
Hi,

kann mir jemand sagen wie einen Jdbc Treiber einbinde ?

Hintergrund ich möchte mit einem Agent Daten as einer DB2 lesen /schreiben.
Soweit ich weiß ist es so das Java Agents immer auf dem NotesServer ausgeführt werden.
Was für mich bedeutet das der Treiber nur auf dem Server eingbunden sein muß oder ??
Reicht es wenn ich den Treiber ( ist eine Jar Datei ) einfach in den Classpath des Servers schreibe ?
Oder muß ich dem Notesserver noch was mit geben so ähnlich wie am client mit den UserClasses ??

Hat sowas schon mal einer von euch versucht ??

Danke

Qojote

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #1 am: 19.06.03 - 09:10:28 »
Hi,

Hi. Das schöne an diesem "Java für Anfänger" ist, dass man die fellow Fragensteller noch mit Handschlag begrüssen kann:


Zitat
kann mir jemand sagen wie einen Jdbc Treiber einbinde ?
ja.
[gehe davon aus, dass du LoNo5 benutzt. LoNo6 dürfte ähnlich und   gerade nicht auf diesen computer :-[]


Erstmal Frage:
Du vewendest db2java.zip, oder?
Für DB2 befindet sich der Treiber in db2java.zip. Es gibt davon 2 Versionen. Eine für Java11 (für LoNo5 funktioniert wahrscheinlich nur diese) und eine andere für >=java12. Bei mir steht die java11-Version unter SQLLIB/java11 und die java2 Version unter java (ich habe Standardmässig Java2 Unterstützung in meinem DB2.

Es gibt unterschiedliche Wege einen JDBC-Treiber in Notes einzubinden einzubinden.
Ein JDBC-Treiber ist nichts anderes als eine einfache Java-Klasse, bzw ein Verbund der selben (jar oder zip File).
Weg 1 ist für die Entwicklung der flexiblere, Weg 2 vielleicht für Produktivsysteme der Bessere.
Weg 1:
{später habe ich festgestellt, das mit JDBC-Treibern Weg 1 nicht funktioniert. Will man sonstige Zusatz-Libraries einbinden, kann man das aber machen. Bei dem JDBC-Treiber von DB2 (und möglicherweise anderen) existiert unter Java1.18 ein Spezialproblem mit irgendwelchen Zugriffen auf über Java Native Interface angesprochene dlls (verfestigte Arbeitshypothese)
s. unten.
}

Du machst einen Java-Agenten. Also unten Typ: Java.
Nun hast du rechts unten ein Fenster. Über den ganz linken Button "Edit Project" kannst du 3rd party jars/zips einbinden. Es öffnet sich ein neues Fenster.  
In meinen Fall navigiere ich bei Base Directory zu D:\SQLLIB\java11.
Auf der linken Seite erscheint db2java.zip. Dann klicke ich auf Add/Replace Files und klicke dann auf OK.
Jetzt sind die Klassen da.
Nix mehr ClassNotFoundException.
 
Weg 2:
Du kannst in der Notes.ini des Servers eine Zeile JavaUserClasses einfügen, wo du die jars/zips eintragen kannst, die auf diesen NotesServer zusätzlich benutzt werden sollen. Ich meine mich zu erinnern, dass dies Performance-mässig besser ist als für jeden Agenten einzeln zips zu importieren. Der Classloader der Notes-VM läd diese Zusatz-Klassen nämlich beim Starten in den Speicher.

Wenn du weitere Fragen hast, stelle sie.

Das von mir propagierte umsonst-Buch "Handbuch der Java Programmierung" (http://www.javabuch.de) hat mit Nummer 42 ein eigenes Kapitel, das sicher ziemlich gut ist. Ich benutze für JDBC auch oft das entsprechende Kapitel im Sun Tutorial. http://java.sun.com/docs/ . Hier Link zu The Java Tutorial.

Gruss Axel

P.S.
Das ist alles ein bischen retro.
Aus 2 Gründen:
1. In J2EE Servern wie Tomcat oder Websphere arbeitet man this days mit sogenannten Connection Pools. In Notes-Agenten musst du jedes mal eine neue Connection zu der Datenbank erzeugen. Bei J2EE werden diese Connections nach Gebrauch in den Pool getan und können wiederverwendet werden. Das ist effizienter.

2. Man geht immer mehr davon ab JDBC wirklich zu koden. Das hat tiefere Gründe als dem Programmierer Tipperei zu ersparen. Es gibt nun verschiedene, sehr ernstzunehmende Frameworks, Spezifikationen oder verwandtes, die für den Programmierer transparente Persistenz-Services (anderes Wort für Integration mit RDBMS) anbieten und somit den Programmierer vor Arbeit und menschlichen Fehlern bewahren.
Man spricht hier von Object/Relational Mapping.
Es geht darum dass Objekt-Modelle eines Business-Problems und deren persistenten Repräsentation in RDBMS etwas sehr unterschiedliches sind (Object-Relational impedance missmatch). Objekt-Modelle modellieren den jeweiligen Business Process, indem dieser in miteinander kommunizierende Objekte dargestellt wird, während sich Datenbank Schemas nach technisch-mathematischen Konzepten ausrichten (normalisieren -> Redundanz vermeiden).  
Beliebt sind derzeit Hibernate und Castor (open Source). Auch Entity Enterprise Java Beans bieten Object Relational Mapping an. Daneben existieren noch Producte wie Cocobase oder Toplink. JDO ist eine neue Spezifikation, für die es bereits >20.
 Hersteller-Implementierungen gibt. JDO ist derzeit ein sehr hippes Thema in Java-Land.
Wobei viele dieser Produkte, Frameworks und Sonstiges über die Persistenzierung in RDBMS hinausgehen sondern auch automatisierte Persistenz in Files, nicht RDBMS-DB2 wie LoNO oder xml anbieten.
  :-X
« Letzte Änderung: 22.06.03 - 11:10:41 von Axel_Janssen »
... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline qojote

  • Aktives Mitglied
  • ***
  • Beiträge: 229
  • I love YaBB 1G - SP1!
Re:JDBC Treiber einbinden
« Antwort #2 am: 19.06.03 - 12:04:03 »
Hi erst mal vielen Dank für deine Antwort.
Werd das gleich mal probieren.

Ich hab hier zwei Bücher über Notes und java 1. von Patton 2. von Ibm Press ( von Muhns ist super entäuschend mehr als die hälfte des Buches ist die Notes Klassen beschreibung die auch in der Hilfe steht.).
Es steht zwar in allen drin wie man über JDBC eine connection aufbaut und ein Sql abschiesst aber das wichtige wie man die Treiber einbindet und so das steht nirgends.
Schade das da niemand mal ein vernünftiges Buch schreiben kann oder kennst du eins ??
Ich fahr am Mittwoch drei Wochen in Urlaub. Ich nehm mein Notebook mit und hoffe das ich da ein bisschen mehr Zeit hab was zu machen ( wenn Frau und Kinder mich lassen :-)))
Schade ist das ich da auf deine Hilfe verzichten muß weil da kommen bestimmt richtig viele Fragen auf.
Gruß
qojote

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #3 am: 19.06.03 - 14:29:46 »
Schade das da niemand mal ein vernünftiges Buch schreiben kann oder kennst du eins ??

quojote,

ich glaube das Thema Lotus und Java ist einfach zu - um es mal OO-mässig auszudrücken - fine-grained, als dass es ausreichend Käufer finden würde, die vom Autor den nötigen Einsatz pekuniär rechtfertigen würde. ;D
Ich war schockiert, als ich erfahren habe, wie wenig von mir als Nobelpreis-würdig gehaltene Autoren durch das Schreiben von Büchern eigentlich verdienen (6 Euro die Stunde oder z.T. wesentlich weniger. und ok die machen sich mit dem Buch einen Namen, wenn es gut ist).

Ich persönlich kaufe Java Bücher nach Amazon-, JavaMagazin- und Javaranch Ratings sowie aus irrationalen groopy-Gehabe (alles von Simon Brown, Kyle Brown und Rick Hightower).  

Deshalb nimmst du am besten unterschiedliche Objekte, um das Problem zu lösen:
- jdbc ist Teil von core-Java und in umsonst zugänglichen, hervorragenden Ressourcen (javabuch.de, Sun-Tutorial) sehr gut beschrieben.
- Spezial-Info zu dem Treiber deines RDBMS suchst du am besten in der Dokumentation des RDBMS (DB2: Redbooks, online oder Buch). Beispiel: Info zu jdbc-Treibern von MySql  sucht man am besten auf den MySql-Seiten im Web.
- in den Notes-Büchern sind dann nur noch die Spezial-Infos zu jdbc in Notes interessant. Der Rest ist meist wohl ziemlich müde.

Du hast mich auf eine Idee gebracht: Ich werde hier eine aufgeräumte (nicht chaotische) Liste erzeugen, wo ich gute Bücher aufliste mit Preis (vieles ist Umsonst), kurzer Beschreibung, Fokus, und (wieviel Aspirin soll ich vorher einnehmen, damit ich beim Lesen keine Kopfschmerzen kriege)-Faktor.

Gruss Axel

----
wer jdbc:odbc:Bridge verwendet ist feige und ausserdem soll man das nicht produktiv einsetzen, weil es wirklich (ich schwöre) mehr als Demo denn als vernünftiger jdbc-Treiber gedacht ist.
... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #4 am: 21.06.03 - 11:01:01 »
Ich habs jetzt mal versucht schnell durchzucoden, bin aber auf ein rätselhaftes Problem gestossen.

Probleme macht der DB2-Treiber.
Diese Probleme sind mir bisher unbekannt. Habe diesen unter Websphere4 und 5, Tomcat und aus einer Desktop-App benutzt.

Ich habe mal in einem Projekt mit Oracle via jdbc von Lotus5 aus kommuniziert, da sind solche Schwierigkeiten nicht aufgetreten.

Ich bekome eine
Code
ava.lang.UnsatisfiedLinkError: SQLAllocEnv

   at COM.ibm.db2.jdbc.app.DB2Driver.<init>(DB2Driver.java:244)

   at 

   at 

   at lotus.domino.AgentBase.runNotes(AgentBase.java:160)

   at lotus.domino.NotesThread.run(NotesThread.java:203)

Google gibt ein paar Dinge aus, oft in Verbindung mit DB2. Einige Spuren aber noch keine Ergebnisse.

Tja zu Demo-zwecken ist es vielleiht ok erstmal mit jdbc-odbc-Bridge zu arbeiten ( :P ). Diese ist bereits in den Java-Klassen auf Domino dabei (sollte aber in robusten Produktivumgebungen nicht verwendet werden.

Du kannst den Code ja mal ausprobieren.
Vorher musst du noch eine System ODBC Datenquelle für DB2 erzeugen (in Systemsteuerung/Verwaltung).
Als Datenbank verwende ich die SAMPLE-Datenbank. Eine Art Schulungsdatenbank, die Leute meist auf DB2 installiert haben (ähnlich wie Nordwind auf Access).  
 
Sehr dankbar wäre ich, wenn Leute mit DB2 und LoNo5 oder LoNo6 mal den DB2 code ausprobieren. An den beiden markierten Stellen die Kommentare umswitchen (mach das später konfortabler).

Vielleicht liegt es auch an irgendwelchen Konfigurations-Merkwürdigkeiten bei mir.

Einstellungen des Agenten:
- Manually from actions menu
- (Run once @Commands may be used)

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 jdbcUrl = "jdbc:db2:SAMPLE";
   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() {
      
      /* 
      * Es wird eine JDBC-Verbindung aufgebaut und geschlossen. 
      * Die Abfolge der einzelnen Schritte ist immer gleich. 
      * ... auch wenn man z.B. von einer Desktop-Swing-GUI aus jdbc nutzt. 
      * ... oder von einem Application Server wie IBM-Websphere, Bea Weblogic oder Tomcat. 
      */
      
      // 1. JDBC-Treiber laden 
      // Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");   
      // ---> big OOOOPPPPS: Jdbc-Treiber per Reflection laden geht nicht mit Notes!!!
      // Dies hat mit Sycherheitschecks innerhalb von Java und Besonderheiten des VM-loading in Domino zu tun.
      // sowas muss man wissen.
      try {  
         //das geht bei mir!!!
         jdbcDriver = new COM.ibm.db2.jdbc.app.DB2Driver(); 
         // FUNKTIONIERT NICHT !!! mit db2-jdbc Treiber
         //jdbcDriver = new sun.jdbc.odbc.JdbcOdbcDriver();
      // Dies lokale Version des Treibers. Wesentlich performanter als net-Version (Paket *.net.* statt *.app.*).
      // Kann auch benutzt werden, wenn z.B. DB2 Server auf Box A und Notes-Server auf Box B, aber auf Box B Db2 User-Client, auf 
      // dem anzusprechende Datenbank katalogisiert. 

   
      // 2. Verbindung zur Datenbank herstellen
      Properties props = new Properties ();
      props.put(jdbcUser, jdbcPassword);
      Connection con = jdbcDriver.connect(jdbcUrl, props); 
      
      // 3. Sql Statement generieren
      Statement stmt = con.createStatement();
      // extrem oft ist aus Sicherheits- und Performance-Gründen PreparedStatement, bei LoNo-Agents glaub ich nicht
      
      // 4. Statement gegen Datenbank senden
      String query = "SELECT NAME FROM STAFF ORDER BY SALARY";
      ResultSet rs = stmt.executeQuery(query);
      
      // ZWISCHENSCHRITT START
      // irgendwas mit dem ResultSet machen
      while (rs.next()) 
         System.out.println(rs.getString(1));
         
      
      // ZWISCHENSCHRITT Ende
      
      // 5. Aufräumen --> sehr, sehr wichtig, gerade für connections
      rs.close();
      stmt.close();
       con.close();
       
       // Notes-Besonderheit wg. Oooopppps unter Punkt 1
       DriverManager.deregisterDriver(jdbcDriver);
      } catch (Exception e) {
         e.printStackTrace();
      }
         /*   
         Notes - Zeug erstmal auskommentiert!!!   
         try {
         Session session = getSession();
         AgentContext agentContext = session.getAgentContext();

         

      } catch(Exception e) {
         e.printStackTrace();
      }
      */
   }
}

Gruss Axel
 
« Letzte Änderung: 21.06.03 - 11:19:23 von Axel_Janssen »
... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline qojote

  • Aktives Mitglied
  • ***
  • Beiträge: 229
  • I love YaBB 1G - SP1!
Re:JDBC Treiber einbinden
« Antwort #5 am: 21.06.03 - 14:47:20 »
Hi,

ich hab auch mal eine bisserl probiert.
Ich habs mit dem db2 driver aus der Toolbox für AS400 probiert.
Folgendes trat auf stelle verbindung her werde nach passwort gepromptet geb alles ein und schluss.
Unser 400 Admin war leider nicht da aber normalerweise hab ich zugriff ( auf jeden Fall per client access und odbc )
Da ich mich auf der AS400 nur als Benutzer bewege weiß ich nicht ob da noch was anderes eingestellt bzw freigegeben werden muß.

Ich habs dann mal mit so einem JDBC Test Tool versucht.Und genau dasselbe.
Ich häng das mal hier dran ist ein kleines Applet.
Find ich ganz gut zum lernen weil du da immer den Code angezeigt bekommst den es generiert.

Ich will jetz noch mal ein paar Sachen probieren und werde meiner Ergebnisse nacher nochmal posten.

Gruß
qojote

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #6 am: 22.06.03 - 10:17:59 »
Das Tool überzeugt mich persönlich nicht.

AS400. Remote Zugriff?
Das kann, muss aber nicht ein anderes Problem sein als meins.

Mein Unsatisfied LinkError scheint irgendwas mit irgendwelchen JNI-Einbindungs-Details in Java11 zu tun haben. Bin mir aber nicht ganz sicher.

Leider habe ich immer noch kein Domino6 auf diesem Computer.

Ich bin mir ziemlich sicher, dass das dann problemlos funktioniert.

Keine Ergebnisse auch wenn ich in DB2 Java auf Version 11 zurücksetze.

Im Internet gibt es auch keine richtige Lösung.

Axel
... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #7 am: 22.06.03 - 10:56:29 »
es läuft mit IBM-JDBC treiber. ;D 8) ;D

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();
          con.close();
          DriverManager.deregisterDriver(jdbcDriver);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}


Das Problem war, dass der Treiber nicht funktioniert, wenn man db2java.zip in den Agenten über "Edit Project" einbindet.

Man muss db2java.zip in die Notes.ini einbinden.
Und zwar eben von wo aus man den Agenten startet.
Wenn man den Agenten über das Aktionsmenu im Client startet, dann läuft er auf dem Client.
Die Zeile
Code
JavaUserClasses=D:\SQLLIB\java\db2java.zip;
muss also in der Notes.ini des Clients stehen.

Für den Produktivbetrieb empfehle ich dringend mit serverseitigen Agenten zu arbeiten. Dann braucht db2java.zip nur in der ini des Servers eingebunden zu werden.

UND ZWAR GENAU AUS DEM SQLLIB\JAVA VERZEICHNIS. Nicht aus java11 oder java12 Verzeichnis von DB2 nehmen!!!
Das habe ich erst falsch gemacht.
So ist sichergestellt, das immer der JDBC-Treiber verwendet wird, der auch aktuell in DB2 unterstützt wird. Wenn man das falsche nimmt, stürzt der Notes-Client grundsätzlich ab.  

DB2 läuft mit unterschiedlichen JDBC Treibern. Standardmässig läuft zumidest DB2 7 mit einem Java Version 1 Treiber. Normalerweise ändert jeder halbwegs ambitionierte Java-User das natürlich direkt auf Java2. Über das file usejdbc2.bat --> befindet sich in SQLLIB\java12).
Das kann man über usejdbc1 wieder zurückgeändert werden.
(bevor man das laufen lässt, alle DB2-Dienste und Notes-Client schliesen (letzteres warum auch immer)).

Die bats bewirken File-Copy-Operationen. Man kann sicher sein, dass im SQLLIB\Java Verzeichnis immer das "richtige" db2java.zip steht.
Notes5 läuft problemlos mit beiden, auch wenn das eine für java12 ist und Notes5 nur Java118 unterstützt.  
Das entsprechende file kann dann natürlich auch von der Box des DB2-Server auf die Box des Notes-Servers kopiert werden. Zumindest wenn beides Windows ist. Bin mir nicht ganz sicher, aber kommen nicht auch DB2Clients mit dem SQLLIB\Java Unterverzeichnissen?


@quojote: Wenn du auf deinem Rechner einen DB2User-Client hast, mit dem du auf dem DB2-Server auf der AS400 zugreifen kannst, dann halte ich es für möglich, dass ein Notes-Agenten-Zugriff via JDBC auf die AS-400 möglich ist, ohne dass du dich mit AS400 Spezifika herumschlagen musst. Sicher bin ich mir nicht. Versuch es einfach mal aus, wenn du willst.
Der remote Zugriff auf die DB2 würde dann der optimierte DB2UserClient machen.
Ansonsten kannst du auch den net-Driver für remote Zugriffe auf das RDBMS verwenden. Remote muss aber grundsätzlich als anderes Wort für "Risiko schlechter Performance" verstanden werden.

Dafür müssten die folgenden Zeilen im code ausgetauscht werden:

Code
private final String jdbcUrl = "jdbc:db2//<serverAS400>:<DB2_Java_Daemon_Listener_PORT>/DB_NAME";
statt
private final String jdbcUrl = "jdbc:db2:DB_NAME";

und
 
jdbcDriver = new COM.ibm.db2.jdbc.net.DB2Driver();
statt
jdbcDriver = new COM.ibm.db2.jdbc.app.DB2Driver();

Axel
   
« Letzte Änderung: 22.06.03 - 12:20:12 von Axel_Janssen »
... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re:JDBC Treiber einbinden
« Antwort #8 am: 23.06.03 - 08:17:07 »
Hallo!

AS/400 DB/2 ist nur bedingt mit den anderen DB/2 Implementationen der IBM zu vergleichen. Diese wird nämlich auch von anderen Leuten programmiert. Obwohl IBM versucht das zu vereinheitlichen. @Quote kannst du mal den Source deines Agenten posten, dann schaue ich mal drüber was da nicht passt. Bei mir funktioniert das nämlich einwandfrei. Eventuell poste noch Release Stand der AS/400. Übrigens emfehlenswert ist es immer wenn man das erste mal mit JDBC auf der AS/400 spielt die Java und Database Gruppen-PTF's einzuspielen. Ausserdem dadurch das sich Java Agents nur sehr schwer debuggen lassen, mache ich es in letzter Zeit nicht mer mit Agenten sondern mit Java Programmen die ich über den Job scheduler ausführen lasse.

Grüße

Ralf
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline Till_21

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 708
  • Geschlecht: Männlich
  • I love Germany
Re:JDBC Treiber einbinden
« Antwort #9 am: 23.06.03 - 14:05:01 »
1. In J2EE Servern wie Tomcat oder Websphere arbeitet man this days mit sogenannten Connection Pools.

Hi Axel,
hier kommt es ganz klar auf den verwendungszweck an !!
habe frueher grundsaetzlich mit conn-pooling gearbeitet...
schau dir dann aber mal die belastung des servers an... ;-(
selbst bei 'nur' 5 offenen Connections...

schoenen gruss

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #10 am: 23.06.03 - 18:17:24 »
@Till_21: mit welchem Server  ???

Websphere? Tomcat?



... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline qojote

  • Aktives Mitglied
  • ***
  • Beiträge: 229
  • I love YaBB 1G - SP1!
Re:JDBC Treiber einbinden
« Antwort #11 am: 23.06.03 - 22:48:37 »
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

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #12 am: 23.06.03 - 23:30:30 »
Der entscheidende Hinweis( Danke Axel ) war das der Treiber über die UserClasses kommen muß und nicht beim Agent mitgegeben werden kann.
... 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 :-))
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      }

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();
             }
   }
}
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
... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re:JDBC Treiber einbinden
« Antwort #13 am: 24.06.03 - 07:45:25 »
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
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #14 am: 24.06.03 - 08:45:09 »
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.
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

... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

Offline Ralf_M_Petter

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 1.879
  • Geschlecht: Männlich
  • Jeder ist seines eigenen Glückes Schmied
    • Ralf's Blog
Re:JDBC Treiber einbinden
« Antwort #15 am: 24.06.03 - 08:50:03 »
Hallo Axel!

Habe gerade mit  AS/400 DB/2 Zugriff experimentiert. Sobald das Client Java Programm endet. Sprich alle Connections gc werden, verschwindet auch am Server der Thread der den Client bedient. Also zumindest bei der DB/2 400 funktioniert es wie in der API Beschreibung beschrieben. Aber z.B. bei NotesThread.sinitThread() führt es zu 50 % zum Absturz von Notes Domino wenn man den Thread nicht ordnungsgemäß mit stermThread() schliesst. Also einfach immer machen wie du es beschrieben hast, dann ist man auf der sicheren Seite.

Grüße

Ralf
Jede Menge Tipps und Tricks zu IT Themen findet Ihr auf meinem Blog  Everything about IT  Eine wahre Schatzkiste sind aber sicher die Beiträge zu meinem Lieblingsthema Tipps und Tricks zu IBM Notes/Domino Schaut doch einfach mal rein.

Offline Till_21

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 708
  • Geschlecht: Männlich
  • I love Germany
Re:JDBC Treiber einbinden
« Antwort #16 am: 24.06.03 - 16:27:27 »
@Till_21: mit welchem Server  ???

Websphere? Tomcat?

TomCat...
das 'aufrechthalten' der connections ist sowas von performancefressend...
wenn ich zeit finde, mach ich dir nen netten Screenshot...

schoenen gruss

Offline Axel_Janssen

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 769
Re:JDBC Treiber einbinden
« Antwort #17 am: 24.06.03 - 22:06:22 »

TomCat...
das 'aufrechthalten' der connections ist sowas von performancefressend...
wenn ich zeit finde, mach ich dir nen netten Screenshot...


no.no.no. ;D

So etwas habe ich noch nie gehabt.
Sprechen wir über das selbe?
aufrechterhalten der connection?

Ich habe verschiedenes für connection pooling eingesetzt (o.k. 2 verschiedene Sachen). Letztlich hatte es immer den selben Effekt. Aber performance-Probleme bei 5 connections  ???

Ich habe connection pools mit "code von Frank Carver" und openSource jars benutzt. Heute ist es Bestandteil von Tomcat41 mit jndi, konfigurierbar mit der admin-Konsole und mit jdbc-2.0-j2ee-ext (also mit javax.sql.Datasource).
 
Würde ich jetzt immer damit machen. Hier ist Link:
Tomcat 4.1 doku

Bei dem code schliesst du natürlich die connection nach jeder Verwendung. Nur wird sie eben nicht geschlossen, sondern an den Pool zurückgegeben.

also tendentiell so:
Code
// Das gemäss Service-Locator-J2EE-Pattern einbinden.
// Service Locator Schicht als Singleton realisiert und liefert verschiedene Servlets den Datasource-Pool.  
// Aufruf dieses Konstrukts dann in init() der Servlets. 
// Datasource jeweils als Instanzvariable der Servlets
// Da von doGet/doPost nur lesender Zugriff ist das ok. 

Datasource ds = 
            (DataSource)ctx.lookup(
               "java:comp/env/jdbc/TestDB");


//in doGet(), doPost() Methode. 
      if (this.ds != null) {
        Connection conn = ds.getConnection();

[... do stuff ...]

conn.close();

Sprechen wir über das gleiche?

Werde das wenn ich zeit hab mal für das relativ neue JNDI-Datasource Feature von Tomcat durch-coden. Glaube nicht das das sonderlich den Rechner belastet. Kann mich irren.  

Axel
« Letzte Änderung: 24.06.03 - 23:42:28 von Axel_Janssen »
... design patterns are abstract designs that help identify the structure and elements involved in a specific design solution. From this, a concrete implementation can be produced.
Kyle Brown

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz