[Java] + MySQL en RMI

Pagina: 1
Acties:

  • DieterVDW
  • Registratie: Juli 2002
  • Laatst online: 12-02-2017
Voor een project ben ik een systeem aan het maken dat moet toelaten om een database aan te spreken vanuit een java programma, zonder dat daarvoor een JDBC driver moet geinstalleerd worden of zo. Maw de user downloadt het programma, start het en kan onmiddellijk de database aanspreken, zonder dat er nog extra dingen moeten gebeuren.
(Dit zodat het programma dan ook eventueel als applet kan gebruik worden.)

Het gaat hierbij om een MySQL database. Als ik het goed heb dan moet je eerst
de JDBC driver die MySQL ter beschikking stelt installeren voor je vanuit java
een connectie met de database kunt maken, niet?
Er is toch geen standaard ondersteuning voor MySQL databases in de JRE hé?
(Want dat zou mij het leven wel een stuk makkelijker maken!)

Anyway, ik wil dit oplossen door RMI te gebruiken.
Ik zou graag de server-client architectuur gaan naboodsen met RMI.
Dit zou dus moeten als volgt gaan:
(Op de server bevindt zich de database en de RMI server samen.)
De client maakt connectie met het remote object en roept een bepaalde methode op van dat remote object, met als parameters de login en het wachtwoord van de client. De client krijgt dan een databaseconnectie object terug dat hij kan gebruiken om de database aan te spreken.
Het databaseconnectie object vormt dan de abstractie van de databank, en verbergt alle vieze SQL/JDBC bla bla voor de client.
Het remote object dient dus alleen om databaseconnectie objecten aan te maken en deze uit te delen aan elke client die erom vraagt.

In theorie klinkt dit wel leuk, maar ik heb een paar bedenkingen.
Volgens mij wordt dat databaseconnectie object gewoon doodleuk overgetransporteerd naar de client, aangezien dat object de returnwaarde is van de remote functie die de client heeft opgeroepen. Dit zou dus betekenen dat het databaseconnectie object eigenlijk bij de client uitgevoerd wordt, en dat de client dus eigenlijk nog altijd de JDBC driver moet ge¨installeerd hebben. Dit mag dus niet!
Ook het databaseconnectie object zou moeten remote blijven, zodat de client nooit iets hoeft te weten komen omtrent de database of JDBC of zo...
Hoe kan ik dit bereiken?
Is het voldoende om van mijn databaseconnectie object ook gewoon een remote object te maken, en zal java er dan vanzelf voor zorgen dat dat object aan de serverkant uitgevoerd wordt? Dit lijkt me aannemelijk, maar aangezien RMI nogal vaag is zou ik dit toch wel graag eens bevestigd willen krijgen voor ik alles begin te implementeren!
Het zou in ieder geval wel super zijn als dit zou kunnen!

Mijn vraag is nu dus: zal dit werken? Kan het werken?
Andere voorstellen om de database te verstoppen voor de client?
Liefst met RMI, maar dat zan dan ook wel redelijk onvermijdelijk zijn denk ik...
(Ik heb geen zin om zelf alles door 'n TCP connectie te beginnen pompen of zo)

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Je kunt gewoon een driver als jar meegeven aan je applet. Dus je hoeft niet zo moeilijk te doen. Je moet verder wel uitkijken waar je allemaal contact mee op mag nemen, aangezien een applet alleen contact mag opnemen met de server waar die vandaan komt.

  • DieterVDW
  • Registratie: Juli 2002
  • Laatst online: 12-02-2017
Alarmnummer schreef op 23 mei 2004 @ 08:21:
Je kunt gewoon een driver als jar meegeven aan je applet.
Aha da's inderdaad wel een goed idee... Maar toch, die driver is 700kB of zo, dus ik zou het toch liever vermijden...

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 16:59

Robtimus

me Robtimus no like you

Ik heb zelf ook ooit zoiets gedaan, daar had de server slechts 1 connectie die open was zolang de server actief was. De client kon gewoon zonder iets van de DB af te weten informatie uit de DB halen; de enige connectie zat in de server.
De client riep alleen de methods als getXXXX aan.

Dit heeft natuurlijk als nadeel dat er maar 1 DB connectie is (is dat wel een nadeel?). Een andere oplossing is per client een connectie naar de DB houden, bv in een mapping van client (naam?) naar connectie.

[ Voor 6% gewijzigd door Robtimus op 23-05-2004 14:02 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • DieterVDW
  • Registratie: Juli 2002
  • Laatst online: 12-02-2017
Maar dan kon wel iedereen aan je database? Of had je dan een vorm van authenticatie
in je server verwerkt?
Ik zou ook kunnen gewoon 1 remote object gebruiken dat als frontend voor de database dient,
maar het probleem is dat RMI geen enkele vorm van authenticatie ondersteunt.
Iedereen zou dus zomaar dat remote object kunnen contacteren en aan mijn database kunnen.
Dat mag dus niet!
En ik heb dan ook nog 2 soorten users: admins en gewone users, met verschillende rechten voor elk...

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 16:59

Robtimus

me Robtimus no like you

Ik had slechts 1 user aan die kant, met volledige leesrechten. Deze user met password en al bevond zich dus alleen in de server. Er was dus wel een vorm van authenticatie.

Optie 2 (mapping van client naar connectie) blijft dan nog steeds een optie: hij roept eerst remote via de DB front end een soort van open aan, met user, pw, etc. Die geeft dan een soort handle (long?) terug, hoeft niet de connectie zelf te zijn.
Daarna kun je gewoon die connectie (bevindt zich alleen aan de server kant) gebruiken door de overige methods aan te roepen met die handle als parameter. Als je klaar bent roep je close aan met diezelfde handle.

Beetje hetzelfde als file IO in C. Als je je handle een beetje generiek houdt kun je de achterliggende implementatie in de server altijd veranderen zonder de clients te hoeven aanpassen.

[ Voor 11% gewijzigd door Robtimus op 23-05-2004 18:19 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • bigtree
  • Registratie: Oktober 2000
  • Laatst online: 31-03 15:20
IceManX schreef op 23 mei 2004 @ 14:02:Dit heeft natuurlijk als nadeel dat er maar 1 DB connectie is (is dat wel een nadeel?). Een andere oplossing is per client een connectie naar de DB houden, bv in een mapping van client (naam?) naar connectie.
Als je maar één connectie hebt, hoe ga je dan om met transactions? Kun je meerdere transactions op een enkele connectie hebben? (MySQL verondersteld)

Lekker woordenboek, als je niet eens weet dat vandalen met een 'n' is.


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 16:59

Robtimus

me Robtimus no like you

Dat had ik dus niet nodig ;)
Eenvoudige database structuur.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • bigtree
  • Registratie: Oktober 2000
  • Laatst online: 31-03 15:20
IceManX schreef op 23 mei 2004 @ 21:05:
Dat had ik dus niet nodig ;)
Eenvoudige database structuur.
Niet nodig? Geen relaties of zo? Wat nu als er een record opgeslagen wordt met een foreign key waarvan het achterliggende record net door een andere thread (client) is verwijderd?

Lekker woordenboek, als je niet eens weet dat vandalen met een 'n' is.


  • Robtimus
  • Registratie: November 2002
  • Laatst online: 16:59

Robtimus

me Robtimus no like you

Zo eenvoudig was de DB dus.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


  • DieterVDW
  • Registratie: Juli 2002
  • Laatst online: 12-02-2017
Het werkt!!! Super!
Tenminste onder windows...

Ik zou het nu alleen nog onder linux moeten in gang krijgen, en dan is alles perfect :)
Ik gebruik de volgende commandolijn om m'n rmi server te starten:

code:
1
java -classpath .:..\mysql-connector-java-3.0.12-production-bin.jar -Djava.security.policy=server.policy -Djava.rmi.server.codebase=http://users.pandora.be/elfjuli/cc/ database.CCDBDistributorImpl //localhost/ccdb dietervdw.dyndns.org 3306


server.policy:
code:
1
2
3
4
5
grant {
  permission java.net.SocketPermission "*:*","connect,accept";
  permission java.io.FilePermission
          "/home/Dieter/CarConfigurator/bin/-", "read";
};


en ik krijg de volgende error:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
CCDistributor exception: Error unmarshaling return header; nested exception is: 
        java.net.SocketException: Connection reset
java.rmi.UnmarshalException: Error unmarshaling return header; nested exception is: 
        java.net.SocketException: Connection reset
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:203)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:350)
        at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
        at java.rmi.Naming.rebind(Naming.java:160)
        at database.CCDBDistributorImpl.main(CCDBDistributorImpl.java:72)
Caused by: java.net.SocketException: Connection reset
        at java.net.SocketInputStream.read(SocketInputStream.java:168)
        at java.io.BufferedInputStream.fill(BufferedInputStream.java:183)
        at java.io.BufferedInputStream.read1(BufferedInputStream.java:222)
        at java.io.BufferedInputStream.read(BufferedInputStream.java:277)
        at java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2150)
        at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2163)
        at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2631)
        at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:734)
        at java.io.ObjectInputStream.<init>(ObjectInputStream.java:253)
        at sun.rmi.server.MarshalInputStream.<init>(MarshalInputStream.java:110)
        at sun.rmi.transport.ConnectionInputStream.<init>(ConnectionInputStream.java:38)
        at sun.rmi.transport.StreamRemoteCall.getInputStream(StreamRemoteCall.java:111)
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:197)
        ... 4 more


'k versta niet echt hoe er een 'connection reset' kan gebeuren, want het enige wat er normaal moet gebeuren bij het opstarten van de server is dat de server zich registreert bij de rmiserver (die al draait en is opgestart buiten het classpath) en die draait op dezelfde host. 'm connect dus gewoon naar de loopback device...
Tips iemand?

PS: RMI = dikke schijt

  • DieterVDW
  • Registratie: Juli 2002
  • Laatst online: 12-02-2017
Ok ik heb de oplossing gevonden.
Het probleem lag blijkbaar bij de rmiregistry...
In /usr/sbin stond er een bestand rmiregistry dat blijkbaar werd opgestard
als ik dus rmiregistry typte, maar blijkbaar is dat niet de JAVA rmiregistry....
Ik heb nu gewoon dat bestand weggevaagt, en alles werkt perfect...
Pagina: 1