H2 H2-Connection bei WebStart

hansmueller

Bekanntes Mitglied
Hallo,

ich habe eine H2-Datenbank und möchte diese über WebStart verteilen.
Der Anwender erhält das Programm, das DBMS (H2) und natürlich die Datenbank (read only). Das ganze soll nämlich auch offline funktionieren.
Meine DB habe ich einfach in eine Jar gepackt.

Wie muß ich jetzt die Connection zu der Datenbank machen?

Ich habe schon folgendes probiert:

Code:
jdbc:h2:MeineDB;IFEXISTS=TRUE;ACCESS_MODE_DATA=r;
Code:
org.h2.jdbc.JdbcSQLException: URL Format Fehler; erwartet "jdbc:h2:{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]", erhalten "jdbc:h2:MeineDB"
URL format error; must be "jdbc:h2:{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]" but is "jdbc:h2:MeineDB" [90046-159]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
	at org.h2.message.DbException.get(DbException.java:169)

Code:
jdbc:h2:file:MeineDB;IFEXISTS=TRUE;ACCESS_MODE_DATA=r;
Code:
org.h2.jdbc.JdbcSQLException: URL Format Fehler; erwartet "jdbc:h2:{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]", erhalten "jdbc:h2:file:MeineDB"
URL format error; must be "jdbc:h2:{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value...]" but is "jdbc:h2:file:MeineDB" [90046-159]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
	at org.h2.message.DbException.get(DbException.java:169)

Bei WebStart muß man über den Classpath auf die Dateien zugreifen. Da (unter Windows) die heruntergeladen Jars vor dem Anwender versteckt werden, gibt es leider auch keinen Pfad, den man ermitteln könnte.
In der H2-Anleitung Advanced steht zwar, das man
Code:
classpath:
benutzen kann, aber da bringt er mir die gleiche Fehlermeldung wie oben.

Bei Derby würde es so aussehen:
Code:
jdbc:derby:classpath:MeineDB;create=false;

Wie macht man das bei H2, bzw. geht das überhaupt mit H2?

Ich benutze die Version h2-1.3.159.

Alle Jars sind signiert und die JNLP ist auch in Ordnung.

MfG
hansmueller
 

hansmueller

Bekanntes Mitglied
Hallo,

ich habe jetzt herausbekommen, das man am Ende der Connection-URL kein
Code:
;
setzen darf. Das mag H2 offenbar nicht.

Aber das Problem besteht immer noch.

Bei
Code:
jdbc:h2:MeineDB;IFEXISTS=TRUE;ACCESS_MODE_DATA=r
und
Code:
jdbc:h2:file:MeineDB;IFEXISTS=TRUE;ACCESS_MODE_DATA=r
bekomme ich jetzt folgende Fehlermeldung:
Code:
org.h2.jdbc.JdbcSQLException: Datenbank "C:\Programme\Mozilla Firefox\MeineDB" nicht gefunden
Database "C:\Programme\Mozilla Firefox\MeineDB" not found [90013-159]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
	at org.h2.message.DbException.get(DbException.java:169)
bzw. beim IE
Code:
org.h2.jdbc.JdbcSQLException: Datenbank "C:\Dokumente und Einstellungen\hansmueller\Desktop\MeineDB" nicht gefunden
Database "C:\Dokumente und Einstellungen\hansmueller\Desktop\MeineDB" not found [90013-159]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
	at org.h2.message.DbException.get(DbException.java:169)
	at org.h2.message.DbException.get(DbException.java:146)

Hat jemand einen Tipp oder eine Idee?

MfG
hansmueller
 

hansmueller

Bekanntes Mitglied
Hallo,

anscheinend kann H2 noch nicht mit Datenbanken, die im Classpath liegen umgehen. (Siehe: how can I provide a relative path for H2 database file, using hibernate under Tomcat? - Stack Overflow)

Ich sehe daher für mich jetzt 2 Lösungsmöglichkeiten:
  1. Ich kopiere beim Programmstart die DB in einen Temp-Ordner und greife dann darauf zu.
  2. Ich probiere mal HSQLDB aus. Laut deren Doku kann diese auch mit WebStart. Sie ist wie H2 schön klein und laut diverser Tests nur ein bißchen langsamer als H2.

Meine H2-Datenbank hat momentan ca. 5MB. Da wäre die Lösung 1 noch vertretbar, auch wenn das nicht so sauber ist.
Geschwindigkeit spielt hier schon eine Rolle. Ich hatte zuerst mit Derby gearbeitet. Das macht allerdings bei komplizierten Abfragen und langen Listen immer wieder schlapp. Dann habe ich es mal testweise mit H2 probiert und der Geschwindigkeitsunterschied hat mich wirklich überrascht. Bei den Abfragen ist H2 um mindestens 50% schneller und kommt auch mit Abfragen zurecht, bei denen Derby versagt.

Was ist eure Meinung? Oder kennt jemand doch einen Kniff, das H2 auch mit WebStart funktioniert?

MfG
hansmueller
 

hansmueller

Bekanntes Mitglied
Hallo,

ich habe mal die Lösung 1 umgesetzt.

Damit das Kopieren der Datenbank in den Temp-Ordner richtig schnell funktioniert, mußte ich eine ganze Weile im Netz suchen und habe auf der Seite Fast stream copy using java.nio channels waffel’s Weblog folgendes gefunden:
Java:
public final class ChannelTools {
  public static void fastChannelCopy(final ReadableByteChannel src, final WritableByteChannel dest) throws IOException {
    final ByteBuffer buffer = ByteBuffer.allocateDirect(16 * 1024);
    while (src.read(buffer) != -1) {
      // prepare the buffer to be drained
      buffer.flip();
      // write to the channel, may block
      dest.write(buffer);
      // If partial transfer, shift remainder down
      // If buffer is empty, same as doing clear()
      buffer.compact();
    }
    // EOF will leave buffer in fill state
    buffer.flip();
    // make sure the buffer is fully drained.
    while (buffer.hasRemaining()) {
      dest.write(buffer);
    }
  }
}

Und so benutzt man diese Klasse:
Java:
// allocate the stream ... only for example
final InputStream input = new FileInputStream(inputFile);
final OutputStream output = new FileOutputStream(outputFile);
// get an channel from the stream
final ReadableByteChannel inputChannel = Channels.newChannel(input);
final WritableByteChannel outputChannel = Channels.newChannel(output);
// copy the channels
ChannelTools.fastChannelCopy(inputChannel, outputChannel);
// closing the channels
inputChannel.close();
outputChannel.close();

Die meisten Beispiele im Netz basieren auf dem
Code:
FileChannel inputChannel = fileInputStream.getChannel();
. Das Problem hierbei ist, daß das nur mit Files funktioniert bzw. man zuerst ein File braucht.
Mit dem oberen Code kann man z. B. auch mit einen einfachen InputStream arbeiten.

Ich habe also mit
Java:
InputStream is = getClass().getClassLoader().getResourceAsStream("MeineDatenbank.h2.db");
einen InputStream auf meine Datenbank im Classpath erzeugt und mit
Java:
File tmpH2Datenbank = new File(System.getProperty("java.io.tmpdir"), strDBName);
FileOutputStream fos = new FileOutputStream(tmpH2Datenbank);
eine Datei im Temp-Ordner erstellt.
Mit
Java:
final ReadableByteChannel inputChannel = Channels.newChannel(is);
final WritableByteChannel outputChannel = Channels.newChannel(fos);
// copy the channels
fastChannelCopy(inputChannel, outputChannel);
kopiert man nun die Datenbank aus dem Classpath in den Temp-Ordner.
Und somit habe ich (unter WebStart) eine Datenbank auf die auch H2 zugreifen kann.

Mit diesen Channels geht das Kopieren wesendlich schneller als wenn man den InputStream bitweise in den FileOutputStream schreibt.

Falls jemand einen Verbesserungsvorschlag hat, oder eine andere Idee, immer her damit.

MfG
hansmueller
 
N

nillehammer

Gast
Hallo Hans,
sieht alles ganz vernünftig aus. Ich würde nur aus dieser Zeile:
InputStream is = getClass().getClassLoader().getResourceAsStream("MeineDatenbank.h2.db");
diese Zeile machen:
InputStream is = getClass().getResourceAsStream("MeineDatenbank.h2.db");
Gruß
 

bERt0r

Top Contributor
Hast du hier schon reingeschaut :Database URL Overview
Wenn die DB in einem zip/jar file liegt musst du das anscheinend angeben.
Read Only Databases in Zip or Jar File

To create a read-only database in a zip file, first create a regular persistent database, and then create a backup. The database must not have pending changes, that means you need to close all connections to the database first. To speed up opening the read-only database and running queries, the database should be closed using SHUTDOWN DEFRAG. If you are using a database named test, an easy way to create a zip file is using the Backup tool. You can start the tool from the command line, or from within the H2 Console (Tools - Backup). Please note that the database must be closed when the backup is created. Therefore, the SQL statement BACKUP TO can not be used.

When the zip file is created, you can open the database in the zip file using the following database URL:

jdbc:h2:zip:~/data.zip!/test

Databases in zip files are read-only. The performance for some queries will be slower than when using a regular database, because random access in zip files is not supported (only streaming). How much this affects the performance depends on the queries and the data. The database is not read in memory; therefore large databases are supported as well. The same indexes are used as when using a regular database.

If the database is larger than a few megabytes, performance is much better if the database file is split into multiple smaller files, because random access in compressed files is not possible. See also the sample application ReadOnlyDatabaseInZip.
 

hansmueller

Bekanntes Mitglied
Hallo,

@bERt0r: Ja, mit diesem
Code:
zip:
habe ich auch schon herumgespielt. Ich habe sogar die Jar mit der Datenbank in eine weitere Jar gepackt, damit ich bei WebStart im Classpath dann die Jar mit der DB habe. (Es ist dabei egal, ob es sich dabei um eine zip- oder jar-Datei handelt.) Hat aber leider auch nicht funktioniert.
Das Problem ist, daß H2 einen Pfad zu dieser Zip-Datei haben will. (Ich vermute mal, daß H2 die Pfadangaben letztendlich immer in einen absoluten Pfad umwandelt.) Bei WebStart kann man aber (unter Windows) für die heruntergeladenen jar-Dateien keinen Pfad ermitteln. Weiß auch nicht, was sich die WebStart-Entwickler damals dabei gedacht haben die heruntergeladenen Dateien vor dem Anwender (und auch vor dem Programmierer) zu verstecken. Das ist halt so eine Besonderheit von WebStart.

@nillehammer: Danke für den Tipp. Gibt es denn da einen Unterschied, außer das es kürzer ist? Es gibt da ja eine Menge unterschiedlicher Möglichkeiten an die Methode
Code:
getResourceAsStream
zu kommen.

MfG
hansmueller
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Maxim6394 EclipseLink + SQLite | Unable to acquire a connection from driver [null] Datenbankprogrammierung 6
J PC-Start Problem JDBC Connection Datenbankprogrammierung 10
S Oracle DB-Connection in .jar file ändern Datenbankprogrammierung 11
yakazuqi MySQL MySQL Connection reset Datenbankprogrammierung 7
K Glassfish 4.1.1 Connection Pool u. Resource Ref Datenbankprogrammierung 20
OnDemand Hikari Pool Connection Validation Datenbankprogrammierung 18
Dimax MySQL Methodenaufruf mit Connection Übergabe Datenbankprogrammierung 8
D MySQL Connection richtig herstellen. Wie ? Datenbankprogrammierung 7
D Multiple Connection mit MySQL Datenbankprogrammierung 4
S Connection Pool Hikari Datenbankprogrammierung 7
P MySQL Connection Global Datenbankprogrammierung 13
J Connection Datenbankprogrammierung 1
F Brauche dringend Hilfe Java-Access Connection Datenbankprogrammierung 3
S New Connection Wizard / NetBeans Datenbankprogrammierung 0
P Frage zu Connection.close() Datenbankprogrammierung 4
T NoSQL Connection für die Thesis [GWT] Datenbankprogrammierung 1
M Connection erstellen Datenbankprogrammierung 1
F Monitoring DB Connection Pool Datenbankprogrammierung 3
H JDBCODBC - Connection-Objekt Datenbankprogrammierung 3
E MySQL SQL - wann connection schließen Datenbankprogrammierung 2
R HSQLDB Connection refused Datenbankprogrammierung 2
B JDBC Connection Fehler Datenbankprogrammierung 8
B JDBC-Connection: Data source name too long Datenbankprogrammierung 3
crashfinger jdbc-connection mit jre7 funktioniert nicht Datenbankprogrammierung 5
reibi Derby/JavaDB Connection refused Datenbankprogrammierung 14
S Ressourcenverbrauch Connection Open/Close Datenbankprogrammierung 11
W MySQL-Connection-Objekt übergeben Datenbankprogrammierung 2
N SQL-Connection Datenbankprogrammierung 3
B MySQL Datenbank Connection als String zurückgeben Datenbankprogrammierung 7
M Connection Pooling Datenbankprogrammierung 7
B MySQL Fehler: Cannot open connection mit Tomcat7, Hibernate und MySQL Datenbankprogrammierung 4
K Connection - möglich & nicht möglich Datenbankprogrammierung 2
T Datenbank connection mit Servlet Datenbankprogrammierung 4
S Applet stucks at SQL Connection (jTDS JDBC) Datenbankprogrammierung 15
c_sidi90 JDBC Oracle Connection schlägt fehl Datenbankprogrammierung 2
JavaKaffee Derby/JavaDB Quartz-WebAnwendung - Connection/Treiber Problem Datenbankprogrammierung 47
ruutaiokwu jdbc connection als singleton Datenbankprogrammierung 11
S Wie überprüfe ich ob die Instanz einer Connection gerade werwendet wird? Datenbankprogrammierung 4
X Connection schließen oder speichern? Performance Frage Datenbankprogrammierung 7
C Derby/JavaDB JavaDB: Keine Connection Datenbankprogrammierung 7
T Pooled Connection und Connection Pool Datenbankprogrammierung 2
S Java Connection to MySQL Datenbank FunPic Datenbankprogrammierung 4
Q java.lang.NullPointerException connection = null Datenbankprogrammierung 13
N Connection bleibt null Datenbankprogrammierung 7
H DB-Connection zu MySQL Datenbankprogrammierung 12
D Wie bekommt man die JDBC connection zum laufen?(Eclipse) Datenbankprogrammierung 16
T MySQL ResultSet zurückgeben nachdem Connection geschlossen wurde? Datenbankprogrammierung 3
B db2 jdbc connection Datenbankprogrammierung 4
G MySQL Connection Problem Datenbankprogrammierung 3
R sql.Connection vs. mysql.Connection Datenbankprogrammierung 3
R Connection Pooling - Tote Verbindungen Datenbankprogrammierung 5
S Connection Pool Datenbankprogrammierung 23
P JPA Connection dynamisch hinzufügen Datenbankprogrammierung 2
S JDBC connection open Datenbankprogrammierung 3
D MySQL Verständnisproblem mit globalen Variablen (Connection) Datenbankprogrammierung 7
F Connection refused: connect Bei Verbindungsherstellung zu MySQL Datenbank Datenbankprogrammierung 3
R Connection Problem für eine externe DB mit Java (JDBC) Datenbankprogrammierung 9
R Connection nur als root Datenbankprogrammierung 3
N Connection kann nicht geschlossen werden!? Datenbankprogrammierung 4
S JPA Hibernate: "The user must supply a jdbc connection" Datenbankprogrammierung 4
F MySQL - Connection JDBC-Driver Problem Datenbankprogrammierung 4
E MSSQL-Server connection aufbau sehr langsam Datenbankprogrammierung 2
S Zuviele DB Connection Datenbankprogrammierung 4
A Connection Variable in anderer Klasse verwenden -> statement Datenbankprogrammierung 2
S Connection String MS Access mit Systemdatenbank / Arbeitsgruppeninformationsdatei Datenbankprogrammierung 4
R DB-Connection, aber wie? Datenbankprogrammierung 2
F Java SQL Connection mit Rollback Datenbankprogrammierung 2
P DB- Connection lösen Datenbankprogrammierung 7
padde479 Connection String Oracle Datenbankprogrammierung 5
W JDBC Connection isValid()? Datenbankprogrammierung 4
G Frage zu connection? Datenbankprogrammierung 9
G allgemeine JDBC-Connection Frage Datenbankprogrammierung 2
H Wie kann ich eine Datenbank Connection aus XML-Datei lesen! Datenbankprogrammierung 2
J jdbc Oracle Connection refused Datenbankprogrammierung 6
D Probleme mit mysql-Connection Datenbankprogrammierung 10
K Wo "Connection" Object erstellen? Datenbankprogrammierung 7
N Kleine Frage zu Connection Pooling mit DataSource Datenbankprogrammierung 2
M Hilfe - keine Connection zur DB Datenbankprogrammierung 4
G Connection zu einer Oracle DB erstellen Datenbankprogrammierung 8
K Oracle XE Connection Problem Datenbankprogrammierung 2
S Connection/Statement/ResultSet auf einmal geschlossen Datenbankprogrammierung 8
C Resultset nach connection close weiterreichen Datenbankprogrammierung 5
G SQL Server Connection Datenbankprogrammierung 12
K "Connection timed out: connect" bei MySQL-Verbindu Datenbankprogrammierung 10
R Warum ist meine Connection null? Datenbankprogrammierung 6
B Connection Pools Datenbankprogrammierung 3
U Connection läuft nicht als jar Datenbankprogrammierung 6
R Interessantes Problem mit Connection-Pool. Datenbankprogrammierung 2
C Statement/Connection SQLWarning Datenbankprogrammierung 4
P Connection problems Datenbankprogrammierung 15
J Keine Connection zur MySQL Db Datenbankprogrammierung 6
K db connection wann schließen Datenbankprogrammierung 4
W Problem bei Connection mit SQLServer-Datenbanke mittels Java Datenbankprogrammierung 2
S Viele Klassen sollen eine Connection benutzen Datenbankprogrammierung 3
K Connection error Datenbankprogrammierung 18
G SQLException: No operations allowed after connection closed Datenbankprogrammierung 2
T problem mit mysql connection Datenbankprogrammierung 6
H Connection Pool + Tomcat + Oracle10g Datenbankprogrammierung 7
T JDBC Connection refused Problem Datenbankprogrammierung 6
L DB2 connection problem Datenbankprogrammierung 2

Ähnliche Java Themen

Neue Themen


Oben