Per MS SQL-JDBC Driver vom Domino auf SQL-Server zugreifen

  • Hallo zusammen,


    ich versuche gerade von meinem Dominoserver eine Verbindung zu einem MS SQL 2000 Server herzustellen. Mal kurz zum Istzustand.
    Der Dominoserver 6.5.4 FP 2 läuft auf einem Debian Linux Server. Als JVM verwende ich dies:


    java version "1.3.1"
    Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1)
    Classic VM (build 1.3.1, J2RE 1.3.1 IBM build cxia32131-20031021 (JIT enabled: jitc))


    Der Webzugriff funktioniert auch wunderbar.


    Um die Verbdindung herzustellen, verwende ich den MS SQL JDBC Treiber von http://www.microsoft.com/downl…47969E66AE&displaylang=en"


    Ich habe mir nun mit Eclipse ein kleines Progrämmchen geschrieben:


    package sql;


    import java.io.*;
    import java.sql.*;


    public class DbTableShow
    {
    public static void main( String[] argv )
    {
    String sDbDrv=null, sDbUrl=null, sTable=null, sUsr="", sPwd="";
    sDbDrv = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    sDbUrl = "jdbc:sqlserver://192.168.0.194:1433";
    sTable = "Personen";
    sUsr = "sa";
    sPwd = "whatever;
    if( null != sDbDrv && 0 < sDbDrv.length() &&
    null != sDbUrl && 0 < sDbUrl.length() &&
    null != sTable && 0 < sTable.length() ) {
    Connection cn = null;
    Statement st = null;
    ResultSet rs = null;
    try {
    // Select fitting database driver and connect:
    Class.forName( sDbDrv );
    cn = DriverManager.getConnection( sDbUrl, sUsr, sPwd );
    st = cn.createStatement();
    rs = st.executeQuery( "select * from Adressen.dbo." + sTable );
    // Get meta data:
    ResultSetMetaData rsmd = rs.getMetaData();
    int i, n = rsmd.getColumnCount();
    // Print table content:
    for( i=0; i<n; i++ )
    System.out.print( "+---------------" );
    System.out.println( "+" );
    for( i=1; i<=n; i++ ) // Attention: first column with 1 instead of 0
    System.out.print( "| " + extendStringTo14( rsmd.getColumnName( i ) ) );
    System.out.println( "|" );
    for( i=0; i<n; i++ )
    System.out.print( "+---------------" );
    System.out.println( "+" );
    while( rs.next() ) {
    for( i=1; i<=n; i++ ) // Attention: first column with 1 instead of 0
    System.out.print( "| " + extendStringTo14( rs.getString( i ) ) );
    System.out.println( "|" );
    }
    for( i=0; i<n; i++ )
    System.out.print( "+---------------" );
    System.out.println( "+" );
    } catch( Exception ex ) {
    System.out.println( ex );
    } finally {
    try { if( null != rs ) rs.close(); } catch( Exception ex ) {}
    try { if( null != st ) st.close(); } catch( Exception ex ) {}
    try { if( null != cn ) cn.close(); } catch( Exception ex ) {}
    }
    }
    }


    // Extend String to length of 14 characters
    private static final String extendStringTo14( String s )
    {
    if( null == s ) s = "";
    final String sFillStrWithWantLen = " ";
    final int iWantLen = sFillStrWithWantLen.length();
    final int iActLen = s.length();
    if( iActLen < iWantLen )
    return (s + sFillStrWithWantLen).substring( 0, iWantLen );
    if( iActLen > 2 * iWantLen )
    return s.substring( 0, 2 * iWantLen );
    return s;
    }
    }


    Das läuft von meinem Client auch wunderbar durch. Da sollte es doch eigentlich auch vom Dominoserver in einem Agent möglich sein, auf den SQL-Server zuzugreifen.


    Also fluchs eine DB erstellt, ein Agent mit imported Java und die leicht modifizierte Klasse importiert. Wenn der Agent aber nun losrennt, kommt folgende Meldung auf dem Dominoserver:


    11.02.2006 16:32:48 AMgr: Agent ('SQL' in 'SQL-DB.nsf') error message: java.lang.NoClassDefFoundError: com/microsoft/sqlserver/jdbc/Util
    11.02.2006 16:32:48 AMgr: Agent ('SQL' in 'SQL-DB.nsf') error message: at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(Unknown Source)
    11.02.2006 16:32:48 AMgr: Agent ('SQL' in 'SQL-DB.nsf') error message: at java.sql.DriverManager.getConnection(DriverManager.java:543)
    11.02.2006 16:32:48 AMgr: Agent ('SQL' in 'SQL-DB.nsf') error message: at java.sql.DriverManager.getConnection(DriverManager.java:194)
    11.02.2006 16:32:48 AMgr: Agent ('SQL' in 'SQL-DB.nsf') error message: at com.ibm.sqlnotes.ConnectSQL.NotesMain(ConnectSQL.java:70)
    11.02.2006 16:32:48 AMgr: Agent ('SQL' in 'SQL-DB.nsf') error message: at lotus.domino.AgentBase.runNotes(Unknown Source)
    11.02.2006 16:32:48 AMgr: Agent ('SQL' in 'SQL-DB.nsf') error message: at lotus.domino.NotesThread.run(NotesThread.java:218)


    Hat jemand eine Idee, an was das liegen kann?


    Ach so. Den SQL-JDBC Treiber habe ich so eingebunden:
    Im Verzeichnis domino des notesdatenverzeichnis ein Verzeichnis lib erstellt, dort die sqljdbc.jar abgelegt und in die notes.ini den Eintrag JavaUserClasses=/home/notes/notesdata/domino/lib/sqljdbc.jar eingetragen und den Dominoserver neu gestartet.


    cu

  • Hm, wenn ich mit dem MidnightCommander in das Jar-File schaue, gehts da direkt mit den Verzeichnis


    META-INF


    und


    com/microsoft/sqlserver/jdbc/


    los. In dem jdbc verzeichnis liegen dann eine ganze mende von Class-files.


    Hab ich da eventuell die falsche jar Datei?


    Added:


    Hab noch andere Jars gefunden und die mal eingebunden. Schauen wir mal........

  • Was du brauchst sind auch die Dateien aus dem Util und Base-Jar die in dem Download Package dabei sind.
    Da sind genau drei Jar Files, und alle drei musst du einbinden.
    Entweder seperat oder du baust aus den Inhalten ein neues Jar File

  • Okay, jetzt habe ich ein JAR-File, welche aus den sqljdb.jar, msbase.jar, mssqlserver.jar und msutil.jar besteht.


    Das habe ich dann via JavaUserClasses=/..../lib/sql.jar eingebunden.


    Allerdings meldet der Agent jetzt direkt:


    java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver


    Was ist denn nu falsch?

  • Hab ich ehrlich gesagt noch nie ausprobiert ob Jar-Files innerhalb eines Jar Files überhaupt funktionieren.
    Ich bezweifle es aber.


    Entpack doch die Jar Files und generier aus den Verzeichnissen einfach ein neues oder binde alle 4 mit ein

  • War auch eine blöde Idee, die jar's in ein neues zu packen. :-o
    Jetzt habe ich die mal alle entpackt, ein neues Jar gebaut und dies eingebungen.


    Allerdings kommt immer noch die Meldung


    error message: java.lang.NoClassDefFoundError: com/microsoft/sqlserver/jdbc/Util


    Obwohl in dem jar diese ja drin ist.

  • Hi, ich hab noch mal ein wenig sortiert.
    So sieht nun der wichtige Teil des Quellcodes aus:


    ...
    System.out.println("Class.for...");
    sDbDrv = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    Class.forName( sDbDrv );
    System.out.println("cn = DriverManager...");
    cn = DriverManager.getConnection( sDbUrl, sUsr, sPwd );
    ...


    Wenn ich nun in der notes.ini die JAR-Datei falsch einbinde (mit einem falschen Dateinamen), so kommt das im Noteslog:


    12.02.2006 18:20:02 AMgr: Agent ('SQL-Connect' in 'Test.nsf') printing: Class.for...
    12.02.2006 18:20:02 AMgr: Agent ('SQL-Connect' in 'Test.nsf') printing: Error handling
    12.02.2006 18:20:02 AMgr: Agent ('SQL-Connect' in 'Test.nsf') printing: java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver


    Binde ich meine neu erstellte JAR-Datei (sql.jar) richtig ein, so kommt das:


    12.02.2006 18:25:39 AMgr: Agent ('SQL-Connect' in 'Test.nsf') printing: Class.for...
    12.02.2006 18:25:39 AMgr: Agent ('SQL-Connect' in 'Test.nsf') printing: cn = DriverManager...
    12.02.2006 18:25:39 AMgr: Agent ('SQL-Connect' in 'Test.nsf') error message: java.lang.NoClassDefFoundError: java/util/logging/Logger
    12.02.2006 18:25:39 AMgr: Agent ('SQL-Connect' in 'Test.nsf') error message: at com.microsoft.sqlserver.jdbc.Util.<clinit>(Unknown Source)



    Das heisst doch, dass er im 2. Fall die JAR-Datei korrekt lesen kann, denn das Class.forName( sDbDrv ); scheint ja zu funktionieren. Denn im ersten Fall "schmiert" mir der Agent ja bereits bei dem Befehl ab.
    Aber warum findet er hier die java/util/logging/Logger nicht?
    Muss ich hier eventuell noch etwas anderes einbinden?

  • Jau, das habe ich zwischenzeitlich auch gefunden.
    Daraufhin habe ich mal jre 1.4.2_10 von sun gezogen und was ist?


    Nu läuft mein HTTP-Task auf meinem Linuxrechner nicht mehr. :hammer:


    Zum Glück ist der nicht richtig produktiv. Damit ist dann der SQL-Test auch erst mal verschoben.


    Beim restart des Servers bekomme ich nun:


    12.02.2006 20:54:42 HTTP Server: Error Loading Java Virtual Machine
    12.02.2006 20:54:42 HTTP Server: JVM: Missing entrypoint in JVM runtime library.


    Werde erst mal versuchen den Task wieder ans rennen zu bekommen - möglichst mit JRE 1.4.

  • JRE 1.4 ist bei JDBC für SQL Server 2005 Vorraussetzung, der JDBC Driver für SQL 2000 tut auch noch mit 1.1.8.
    http://www.microsoft.com/downl…29BB18E1E5&displaylang=en


    Ich habs dadurch zum Laufen gebracht, daß ich die 3 Jar-Files mit in den Agenten reingepackt habe, Schaltfläche <Projekt bearbeiten> und dann im Fenster <Java-Dateien organisieren> die 3 Jar Files in den Agenten importieren.


    Wenn man es für mehrere Agenten braucht, dann einfach bei <Gemeinsamer Code\Script Bibliotheken> eine Java Bibliothek mit den 3 Jar-Files machen und später die Java Bibliothek in den Agenten einbauen.


    Andreas Hoster
    mailto:andreas.hoster@herma.de

  • Hi,


    das hört sich doch schon mal vielversprechend an.


    Allerdings compiliert er mir den Agent nicht.
    Er meckert, dass er die Classe Connection nicht finden kann.


    import lotus.domino.*;


    public class JavaAgent extends AgentBase {


    public void NotesMain() {


    try {
    Session session = getSession();
    AgentContext agentContext = session.getAgentContext();


    // (Your code goes here)


    String sDbDrv = null, sDbUrl = null, sTable = null, sUsr = "", sPwd = "";
    sDbDrv = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    sDbUrl = "jdbc:sqlserver://ccccccc:1433";
    sTable = "Personen";
    sUsr = "sa";
    sPwd = "yyyyyyy";
    Connection cn = null;
    Statement st = null;
    ResultSet rs = null;
    try {
    System.out.println("Class.for...");
    Class.forName(sDbDrv);
    System.out.println("cn = DriverManager...");
    cn = DriverManager.getConnection(sDbUrl, sUsr, sPwd);
    System.out.println("st = cn.CreateStatement.......");
    st = cn.createStatement();
    System.out.println("Select ............");
    rs = st.executeQuery("select * from Adressen.dbo." + sTable);


    ResultSetMetaData rsmd = rs.getMetaData();
    int i, n = rsmd.getColumnCount();
    for (i = 1; i <= n; i++)
    System.out.print(rsmd.getColumnName(i) + " - ");
    System.out.println("");
    while (rs.next()) {
    for (i = 1; i <= n; i++)
    System.out.print(rs.getString(i) + " - ");
    System.out.println("");
    }
    } catch (Exception ex) {
    System.out.println("catch ..........");
    System.out.println(getStackTraceAsString(ex));
    } finally {
    try {
    if (null != rs)
    rs.close();
    } catch (Exception ex) {
    }
    try {
    if (null != st)
    st.close();
    } catch (Exception ex) {
    }
    try {
    if (null != cn)
    cn.close();
    } catch (Exception ex) {
    }
    }


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



    Hast Du eine Idee, warum er die nicht findet? Ich habe wie du beschrieben hast, die 3 jars mit eingebunden.


    cu