H2 Datenbank - Verbindung klappt nicht!
Ich versuche mitlerweile etwas verzweifelt eine H2 Datenbank (http://www.h2database.com/html/main.html ) einzubinden. Ich habe die 'Version 1.2.147 (2010-11-21) - All Platforms' runtergeladen und die Datei 'h2-1.2.147.jar' in den Java classpath - 'C:\Programme\Java\jre6\lib\ext' verschoben. In Jabaco hab ich unter Projektverweise das .jar Archiv hinzugefügt und den Verweis auf 'org.h2.Driver gesetzt'.
Wenn ich das Projekt nun laufen lasse bekomme ich die Fehlermeldung 'java.lang.ClassNotFoundException: org.h2.driver' in Zeile 12.
Ich bin mir sicher, daß das Ganze schon lief... Sqlite läuft z.B. auf anhieb!!
Hat vielleicht einer von Euch eine Idee was da los ist?
Hier noch der wesentliche Source...
und die Fehlermeldung...
Wenn ich das Projekt nun laufen lasse bekomme ich die Fehlermeldung 'java.lang.ClassNotFoundException: org.h2.driver' in Zeile 12.
Ich bin mir sicher, daß das Ganze schon lief... Sqlite läuft z.B. auf anhieb!!
Hat vielleicht einer von Euch eine Idee was da los ist?
Hier noch der wesentliche Source...
|
|
Source code |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Option Explicit
Private DatabaseH2 As New DataBase
Import org#h2#Driver
Private Sub dbInitialisieren()
Dim dbH2 As String
Dim driver As class
dbH2 = "C:\Dokumente und Einstellungen\xy\Eigene Dateien\Soft Entwicklung\Jabaco\H2\test"
dbH2 = Replace(dbH2, "\", "/")
driver = class.forName("org.h2.driver")
If driver = Nothing Then
MsgBox "h2 Treiber nicht vorhanden!", vbCritical, ""
Exit Sub
End If
DatabaseH2.Connect("jdbc:h2:" & dbH2, "xy", "")
End Sub
|
und die Fehlermeldung...
|
|
Source code |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
java.lang.ClassNotFoundException: org.h2.driver at java.net.URLClassLoader$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Unknown Source) at Form1.Initialization(Form1.jsrc:42) at Form1.Form_Load(Form1.jsrc:17) at VB.AbstractForm.fireLoaded(AbstractForm.jsrc) at VB.LoadAdapter.run(LoadAdapter.jsrc) at java.awt.event.InvocationEvent.dispatch(Unknown Source) at java.awt.EventQueue.dispatchEvent(Unknown Source) at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.pumpEvents(Unknown Source) at java.awt.EventDispatchThread.run(Unknown Source) |
Das folgende Beispiel klappt bei mir:
Ich habe die aktuelle H2-Version "for all platforms" heruntergeladen und das File h2-1.2.147.jar in den Projekt-Classpath aufgenommen.
Worin jetzt genau dein Fehler oder Problem lag, habe ich nicht erkennen können.
Aber vielleicht inspiriert es auch so.
Gruß!
A1880
|
|
Jabaco Source |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
Option Explicit #Import java.sql.* Public Sub Command1_Click() Dim conn As Connection Dim qry As String Dim st As java#sql#Statement Dim Meta As DatabaseMetaData Dim rs As ResultSet Dim tableNames As String Dim s As String Dim arr() As String java#lang#Class.forName("org.h2.Driver") conn = DriverManager.getConnection("jdbc:h2:~/test", "sa", "") If Not (conn Is Nothing) Then qry = "SELECT * FROM INFORMATION_SCHEMA.TABLES" st = conn.createStatement() rs = st.executeQuery(qry) Do While rs.next() tableNames = rs.getString(3) s = s & tableNames & vbCrLf Loop s = s & vbCrLf Meta = conn.getMetaData() rs = Meta.getTables(Null, Null, "%", arr) tableNames = "" Do While rs.next() tableNames = rs.getString(3) s = s & tableNames & vbCrLf Loop conn.close() MsgBox s Else MsgBox "No connection to DB!", vbCritical End If End Sub |
Ich habe die aktuelle H2-Version "for all platforms" heruntergeladen und das File h2-1.2.147.jar in den Projekt-Classpath aufgenommen.
Worin jetzt genau dein Fehler oder Problem lag, habe ich nicht erkennen können.
Aber vielleicht inspiriert es auch so.
Gruß!
A1880
Tja, das funktioniert... Vielen Dank! Jetzt kann ich wenigstens weiter arbeiten.
Java ist mir noch recht fremd. Es gibt ja in Deinem Beispiel nur einen Verweis auf den H2-Treiber, wie findet java denn diesen? Schaut es standartmässig im Classpath ' \Java\jre6\lib\ext ' nach? Warum mußt Du ' Import org#h2#Driver ' nicht anweisen? Und muß ich ' #Import java.sql.* ' wirklich auf alles verweisen? Ist das nicht unnötiger Overhead oder schmeißt der Compiler Überflüssiges wieder raus? Ich glaub ich muß mir hierzu doch grundsätzlich nochmal ein bischen was anschauen!
Trotzdem bin ich etwas verunsichert was meinen Weg angeht. Wie gesagt mit Sqlite klappt es so wie ich es hier gepostet hab! Und ich hatte vor ein bestehendes Projekt, das Sqlite verwendet alternativ mit H2 auszuprobieren.
Mir ist auch aufgefallen, wenn ich einmal im Code ' #Import ' verwendet habe, dann ist es schwer die entsprechende Klasse wieder loszuwerden. Häkchen wegclicken funktioniert oft nicht! Ist das ein bekanntes Problem von Jabaco? Gibt es ein ' #unImport ' ?
Nochmals ... Danke!
Java ist mir noch recht fremd. Es gibt ja in Deinem Beispiel nur einen Verweis auf den H2-Treiber, wie findet java denn diesen? Schaut es standartmässig im Classpath ' \Java\jre6\lib\ext ' nach? Warum mußt Du ' Import org#h2#Driver ' nicht anweisen? Und muß ich ' #Import java.sql.* ' wirklich auf alles verweisen? Ist das nicht unnötiger Overhead oder schmeißt der Compiler Überflüssiges wieder raus? Ich glaub ich muß mir hierzu doch grundsätzlich nochmal ein bischen was anschauen!
Trotzdem bin ich etwas verunsichert was meinen Weg angeht. Wie gesagt mit Sqlite klappt es so wie ich es hier gepostet hab! Und ich hatte vor ein bestehendes Projekt, das Sqlite verwendet alternativ mit H2 auszuprobieren.
Mir ist auch aufgefallen, wenn ich einmal im Code ' #Import ' verwendet habe, dann ist es schwer die entsprechende Klasse wieder loszuwerden. Häkchen wegclicken funktioniert oft nicht! Ist das ein bekanntes Problem von Jabaco? Gibt es ein ' #unImport ' ?
Nochmals ... Danke!
Jabaco findet den H2-Treiber, indem man die *.jar-Datei im Projekt angibt:
Taste "F1"; "Add Jar-Archive"
Standardmäßig sind nur Jabaco.jar und rt.jar im Zugriff.
Die "#Import"-Statements bewirken, dass Jabaco Klassennamen findet, ohne dass man den kompletten Pfad angibt.
Ich kann dann also "Statement" statt "java#sql#Statement" schreiben.
Die Falle besteht darin, dass manche Klassennamen in mehreren Paketen auftauchen.
Ein Beispiel ist die Klasse "Statement". Jabaco findet java#beans#Statement statt java#sql#Statement.
Das habe ich gemerkt, weil ich die Methode "executeQuery()" nicht finden konnte.
Deswegen habe ich den Pfad explizit angegeben.
Im Zweifel sollte man also den kompletten Pfad schreiben.
Gibt man zuviele #import Statements an, so steigt die Lade- und Suchzeit.
Zum Experimentieren kannst du einzelne Zeilen auskommentieren.
"#unimport" gibt es nicht. Du kannst die #import-Zeile auskommentieren oder löschen.
Witzigerweise (oder merkwürdigerweise) intepretiert Jabaco "Statment" als "java#sql#Statement", sobald ich irgendwo im
Code den kompletten Pfad angegeben habe. Man kann sich also das #import sparen, indem man die erste Verwendung ausschreibt.
Happy Experimenting!
A1880
Taste "F1"; "Add Jar-Archive"
Standardmäßig sind nur Jabaco.jar und rt.jar im Zugriff.
Die "#Import"-Statements bewirken, dass Jabaco Klassennamen findet, ohne dass man den kompletten Pfad angibt.
Ich kann dann also "Statement" statt "java#sql#Statement" schreiben.
Die Falle besteht darin, dass manche Klassennamen in mehreren Paketen auftauchen.
Ein Beispiel ist die Klasse "Statement". Jabaco findet java#beans#Statement statt java#sql#Statement.
Das habe ich gemerkt, weil ich die Methode "executeQuery()" nicht finden konnte.
Deswegen habe ich den Pfad explizit angegeben.
Im Zweifel sollte man also den kompletten Pfad schreiben.
Gibt man zuviele #import Statements an, so steigt die Lade- und Suchzeit.
Zum Experimentieren kannst du einzelne Zeilen auskommentieren.
"#unimport" gibt es nicht. Du kannst die #import-Zeile auskommentieren oder löschen.
Witzigerweise (oder merkwürdigerweise) intepretiert Jabaco "Statment" als "java#sql#Statement", sobald ich irgendwo im
Code den kompletten Pfad angegeben habe. Man kann sich also das #import sparen, indem man die erste Verwendung ausschreibt.
Happy Experimenting!
A1880
So, ich bin es jetzt nochmal durchgegangen! Also wenn ich in meinem Code...
... ' driver = class.forName("org.h2.driver") ' mit Deinem ' java#lang#Class.forName("org.h2.Driver") ' ersetze und dann noch ' Import java.sql.* ' verwende läuft es! Du hast mich also prima auf den Weg gebracht
Noch zwei Dinge:
1. Ich habe in Deinem Beispiel mal das Sql Statement verändert ' qry = "SELECT * FROM TEST" ' . Die Tabelle ' TEST ' habe ich mit dem in H2 vorgegebenen Muster-CREATE Statement erstellt, wenn ich nun Dein Beispiel laufen lasse bekomme ich die Fehlermeldung ' TableNotFound ' ! Fällt Dir dazu etwas ein?
2. ' #Import ' Statements löschen, auskommentieren oder wegclicken ist mir schon alles klar, nur was tun wenn die Häkchen im ' Projektverweise - Dialog ' (F1) trotzdem gesetzt bleiben. Also die ' #Imports' bestehen bleiben? Auch wenn Jabaco neu gestartet wurde!!
Dani
|
|
Source code |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Option Explicit
Private DatabaseH2 As New DataBase
Import org#h2#Driver
Private Sub dbInitialisieren()
Dim dbH2 As String
Dim driver As class
dbH2 = "C:\Dokumente und Einstellungen\xy\Eigene Dateien\Soft Entwicklung\Jabaco\H2\test"
dbH2 = Replace(dbH2, "\", "/")
driver = class.forName("org.h2.driver")
If driver = Nothing Then
MsgBox "h2 Treiber nicht vorhanden!", vbCritical, ""
Exit Sub
End If
DatabaseH2.Connect("jdbc:h2:" & dbH2, "xy", "")
End Sub
|
... ' driver = class.forName("org.h2.driver") ' mit Deinem ' java#lang#Class.forName("org.h2.Driver") ' ersetze und dann noch ' Import java.sql.* ' verwende läuft es! Du hast mich also prima auf den Weg gebracht
Noch zwei Dinge:
1. Ich habe in Deinem Beispiel mal das Sql Statement verändert ' qry = "SELECT * FROM TEST" ' . Die Tabelle ' TEST ' habe ich mit dem in H2 vorgegebenen Muster-CREATE Statement erstellt, wenn ich nun Dein Beispiel laufen lasse bekomme ich die Fehlermeldung ' TableNotFound ' ! Fällt Dir dazu etwas ein?
2. ' #Import ' Statements löschen, auskommentieren oder wegclicken ist mir schon alles klar, nur was tun wenn die Häkchen im ' Projektverweise - Dialog ' (F1) trotzdem gesetzt bleiben. Also die ' #Imports' bestehen bleiben? Auch wenn Jabaco neu gestartet wurde!!
Dani
Wenn H2 die Tabelle "TEST" nicht findet, wird sie in der gerade verbundenen Datenbank nicht enthalten sein.
Du kannst ja in der interaktiven H2-Oberfläche nachschauen, ob und wo dein CREATE geklappt hat.
Im Ausgangsbeispiel heißt ja nur die Datenbank "TEST", nicht die Tabelle in der Datenbank.
Die genaue Wirkung der Häkchen in der Projektverwaltung habe ich noch nicht nachvollzogen.
Sieh mal mit einem Texteditor in der *.jba Projektdatei nach.Das geht am besten, wenn du die Datei in xxx.xml
umbenennst und mit einem XML-Editor (oder einfach dem Internet Explorer) ansiehst.
Ich vermute, dass jedem <Implements Name="..."/> ein Häkchen entspricht.
Eine andere Möglichkeit besteht darin, einfach ein neues Projekt aufzumachen und die alten Inhalte hinein zu kopieren.
Gruß!
A1880
Du kannst ja in der interaktiven H2-Oberfläche nachschauen, ob und wo dein CREATE geklappt hat.
Im Ausgangsbeispiel heißt ja nur die Datenbank "TEST", nicht die Tabelle in der Datenbank.
Die genaue Wirkung der Häkchen in der Projektverwaltung habe ich noch nicht nachvollzogen.
Sieh mal mit einem Texteditor in der *.jba Projektdatei nach.Das geht am besten, wenn du die Datei in xxx.xml
umbenennst und mit einem XML-Editor (oder einfach dem Internet Explorer) ansiehst.
|
|
Source code |
1 2 3 4 5 6 |
<Implements Name="java/io/FileDescriptor"/> <Implements Name="java/sql/Wrapper"/> <Implements Name="java/sql/ResultSet"/> <Implements Name="java/lang/ClassLoader"/> <Implements Name="java/sql/ResultSetMetaData"/> <Implements Name="java/sql/Connection"/> |
Ich vermute, dass jedem <Implements Name="..."/> ein Häkchen entspricht.
Eine andere Möglichkeit besteht darin, einfach ein neues Projekt aufzumachen und die alten Inhalte hinein zu kopieren.
Gruß!
A1880
Jetzt fällt mir gerade noch etwas ein, wenn ich ein kleines Beispielprogramm compiliere ' .jar ' und unter XP laufen lasse funktioniert es enwandfrei. Das selbe ' .jar ' auf dem Mac - SnowLeopard ruft folgende Fehlermeldung auf:
Warum verhält sich das Programm auf dieser Plattform anders? Wie bekomme ich die Fehlermeldung weg? Liegt das an Apples Java?
Dani
Danach läuft das Programm dann ohne Fehler weiter; ruft Daten von einer H2 Datenbank ab, füllt eine Combobox, etc. Den ' sun.jdbc.odbc.JdbcOdbcDriver ' habe ich im Projekt nirgens refferenziert!
Quoted
java.lang.ClassNotFoundException: sun.jdbc.odbc.JdbcOdbcDriver
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:24
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:169)
at VB.DataBase.Class_Initialize(DataBase.jsrc)
at VB.DataBase.<init>(DataBase.jsrc)
at Form1.initVars(Form1.jsrc:3)
at Form1.<init>(Form1.jsrc)
at Module1.<clinit>(Module1.jsrc)
Warum verhält sich das Programm auf dieser Plattform anders? Wie bekomme ich die Fehlermeldung weg? Liegt das an Apples Java?
Dani
Die Klasse DataBase enthält in ihrer Initialisierung:
Damit wird der ODBC-Treiber als Standard vereinbart.
Auf Nicht-PCs gibt es keinen ODBC-Treiber in der rt.jar. Daher die ClassNotFoundException.
Dies kann man an der Zeile "at VB.DataBase.Class_Initialize(DataBase.jsrc)" im Stack Trace erkennen.
Um diesen Umstand zu umgehen, könntest Du entweder auf "DataBase" verzichten (siehe mein Beispiel) oder das "New DataBase" in Deinen Code einbauen und die Exception mit "on error goto" abfangen. DataBase ist eine Klasse speziell für den Zugriff auf ODBC-Datenbanken, hilft also für H2 nicht wirklich weiter. Du könntest als Programmierübung den Code von DataBase aus dem Framework kopieren und Dir eine eigene Klasse DataBaseH2 daraus basteln.
Gruß!
A1880
|
|
Jabaco Source |
1 2 3 |
Public Sub Class_Initialize Call Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") End Sub |
Damit wird der ODBC-Treiber als Standard vereinbart.
Auf Nicht-PCs gibt es keinen ODBC-Treiber in der rt.jar. Daher die ClassNotFoundException.
Dies kann man an der Zeile "at VB.DataBase.Class_Initialize(DataBase.jsrc)" im Stack Trace erkennen.
Um diesen Umstand zu umgehen, könntest Du entweder auf "DataBase" verzichten (siehe mein Beispiel) oder das "New DataBase" in Deinen Code einbauen und die Exception mit "on error goto" abfangen. DataBase ist eine Klasse speziell für den Zugriff auf ODBC-Datenbanken, hilft also für H2 nicht wirklich weiter. Du könntest als Programmierübung den Code von DataBase aus dem Framework kopieren und Dir eine eigene Klasse DataBaseH2 daraus basteln.
Gruß!
A1880
This post has been edited 1 times, last edit by "A1880" (Dec 1st 2010, 10:14am)
Similar threads
-
Allgemeine Themen, Fragen und Diskussionen »-
Applet lokal okay - "access denied" wenn vom Server gestartet
(Jul 3rd 2010, 5:35pm)
-
Allgemeine Themen, Fragen und Diskussionen »-
Update auf Mysql DB
(Mar 2nd 2009, 11:20pm)
-
Allgemeine Themen, Fragen und Diskussionen »-
Controls erweitern
(Dec 19th 2008, 11:22am)
