P
Prosec
Gast
Hallo Leute,
ich habe ein Problem und komme einfach nicht weiter!
Im Zuge einer Hausarbeit habe ich mit hsql eine Datenbank erstellt, die zur Verwaltung für eine CarSharing Firma dienen soll. In der Datenbank sind Tabellen zu Kunden, Fahrzeuge, Buchen, usw..
Außerdem habe ich einen Thread erstellt, der eine Fahrt simuliert und regelmäßig gefahrene Kilometer und die gefahrene Zeit in der jeweiligen Buchung aktualisiert. Es können auch mehrer Fahrten parallel laufen.
Das klappt auch alles so weit!
Jetzt ist die Aufgabe, dass die simulierten Fahrten nicht direkt auf die Datenbank zugreifen sollen, sondern über ein RMI-Client/Server System.
Ich muss dazu sagen, dass ich wirklich erst seit ein paar Wochen mit Java arbeite und RMI vorher auch noch nie genutzt hab. Ist also alles Neuland für mich.
Ich habs jetzt mal so probiert:
Interface:
[Java]
package RMI.Server;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.sql.SQLException;
public interface Fahrtinterface extends Remote{
public void updateBuchung (int buchnr, int min, int km)
throws RemoteException, ClassNotFoundException, SQLException;
}
[/code]
Implementation:
Server:
Thread:
Client:
Die Klassenstruktur sieht wie folgt aus:
Package RMI.Server:
FahrtInterface
FahrtImpl
FahrtServer
Package RMI.Client:
FahrtInterface (Gleicher Inhalt wie in RMI.Server.FahrtInterface)
RmiFahrt (Thread)
RmisimuliereFahrten (Der Client, der ausgeführt werden soll)
Ich bin schon nicht sicher, ob das geht, dass ich "fi" vom Typ Fahrtinterface aus "RmisimuliereFahrten" an den Thread übergeben kann und dann der Thread mit dem Server kommunizieren kann und über "fi.updateBuchung" (Zeile 49 in "RmiFahrt") auf die Datenbank zugreifen kann.
Aber so weit komme ich eh noch nicht!
Den Server kann ich starten, das ist kein Problem.
Aber wenn ich dann "RmisimuliereFahrten" ausführe, bekomme ich diesen Fehler:
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to RMI.Client.Fahrtinterface
at RMI.Client.RmisimuliereFahrten.main(RmisimuliereFahrten.java:21)
Wieso klappt der Cast da nicht? Ich habe alle meine Vorlesungsunterlagen durchforstet und mache alles (was die Verbindung zwischen Server und Client angeht) genau so, wie es beschrieben wurde.
Habe auch gestern und heute schon stundenlang gegoogelt, habe aber keine Lösung gefunden...
Kann mir bitte jemand helfen, ich bin echt am verzweifeln!?
ich habe ein Problem und komme einfach nicht weiter!
Im Zuge einer Hausarbeit habe ich mit hsql eine Datenbank erstellt, die zur Verwaltung für eine CarSharing Firma dienen soll. In der Datenbank sind Tabellen zu Kunden, Fahrzeuge, Buchen, usw..
Außerdem habe ich einen Thread erstellt, der eine Fahrt simuliert und regelmäßig gefahrene Kilometer und die gefahrene Zeit in der jeweiligen Buchung aktualisiert. Es können auch mehrer Fahrten parallel laufen.
Das klappt auch alles so weit!
Jetzt ist die Aufgabe, dass die simulierten Fahrten nicht direkt auf die Datenbank zugreifen sollen, sondern über ein RMI-Client/Server System.
Ich muss dazu sagen, dass ich wirklich erst seit ein paar Wochen mit Java arbeite und RMI vorher auch noch nie genutzt hab. Ist also alles Neuland für mich.
Ich habs jetzt mal so probiert:
Interface:
[Java]
package RMI.Server;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.sql.SQLException;
public interface Fahrtinterface extends Remote{
public void updateBuchung (int buchnr, int min, int km)
throws RemoteException, ClassNotFoundException, SQLException;
}
[/code]
Implementation:
Java:
package RMI.Server;
import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class FahrtImpl implements Fahrtinterface{
static boolean locked = false;
public FahrtImpl() throws RemoteException {
System.out.println ("Erzeuge Interface");
}
@Override
public synchronized void updateBuchung (int buchnr, int min, int km)
throws RemoteException, SQLException, ClassNotFoundException
{
/**
* Warten, falls momentan ein anderer Thread die Datenbank bearbeitet
*/
while (locked){};
/**
* Die Datenbank "abschließen", damit kein anderer Thread zur selben Zeit
* auf die Datenbank zugreifen kann
*/
locked = true;
/**
* Treiber initialisieren
*/
Class.forName ("org.hsqldb.jdbcDriver");
/**
* Verbindung aufbauen
*/
Connection con = DriverManager.getConnection
("jdbc:hsqldb:file:C:\\hsql\\data\\datenbank; shutdown=true", "SA", "");
/**
* Statement erzeugen
*/
Statement stm = con.createStatement();
/**
* Kilometer und Endzeit in der Datenbankauf den aktuellen Stand der Fahrt setzen
*/
String update =
"UPDATE BUCHT SET ENDE = START + "+min+" MINUTE, "
+ "KILOMETER = "+km+" WHERE BUCHNR = "+buchnr;
stm.executeUpdate(update);
stm.close();
con.close();
/**
* Datenbank wieder für andere Threads freigeben
*/
locked = false;
}
}
Server:
Java:
package RMI.Server;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
class FahrtServer extends UnicastRemoteObject {
public FahrtServer() throws RemoteException{
FahrtImpl fi = new FahrtImpl();
Fahrtinterface stub = (Fahrtinterface)
UnicastRemoteObject.exportObject(fi, 0);
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
Registry reg = LocateRegistry.getRegistry("127.0.0.1");
reg.rebind("Fahrtinterface", stub);
System.out.println("Interface angemeldet.");
}
public static void main(String[] args) throws RemoteException, AlreadyBoundException {
new FahrtServer();
}
}
Thread:
Java:
package RMI.Client;
import java.rmi.RemoteException;
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Rmifahrt extends Thread
{
/**
* Attribute festlegen
*/
private final int buchnr;
private final String fname;
Fahrtinterface fi;
/**
* Konstruktor
*/
public Rmifahrt (int buchnr, String fname, Fahrtinterface fi)
{
this.buchnr = buchnr;
this.fname = fname;
this.fi = fi;
}
@Override public void run()
{
System.out.println(fname+ " wird gestartet!");
/**
* Gefahrene Kilometer und Zeit auf Null setzen
*/
int km = 0;
int min = 0;
/**
* Schleife um Fahrt zu simulieren
*
*/
for ( int i = (int) (Math.random() * 91); i < 95; i++)
{
km = km + (int) (Math.random() * 30);
min = min + 15;
try {
try {
/**
* Aktuell gefahrene Zeit und Kilometer an die Datenbank übermitteln
*/
fi.updateBuchung(buchnr, min, km);
} catch (RemoteException ex) {
Logger.getLogger(Rmifahrt.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (SQLException ex) {
Logger.getLogger(Rmifahrt.class.getName()).log(Level.SEVERE, null, ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(Rmifahrt.class.getName()).log(Level.SEVERE, null, ex);
}
/**
* Statusmeldung ausgeben
*/
System.out.println
(fname+ " hat jetzt "+km+" Kilometer in "+min+" Minuten zurückgelegt!");
}
/**
* Final gefahrenen Kilometer und Zeit ausgeben
*/
int h = min / 60;
min = min % 60;
System.out.println
(fname+ " wurde beendet und hat "+km+" Kilometer "
+ "in "+h+" Stunden und "+min+" Minuten zurückgelegt!");
}
}
Client:
Java:
package RMI.Client;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.NotBoundException;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RmisimuliereFahrten {
public static void main(String[] args) throws RemoteException,
NotBoundException,
UnknownHostException
{
Registry reg = LocateRegistry.getRegistry("127.0.0.1");
String sender = InetAddress.getLocalHost().getHostAddress();
Fahrtinterface fi = (Fahrtinterface) reg.lookup("Fahrtinterface");
/**
* Threads erzeugen
*/
Thread Fahrt1 = new Rmifahrt(5, "Fahrt 1", fi);
Thread Fahrt2 = new Rmifahrt(23, "Fahrt 2", fi);
Thread Fahrt3 = new Rmifahrt(42, "Fahrt 3", fi);
Thread Fahrt4 = new Rmifahrt(54, "Fahrt 4", fi);
/**
* Threads starten
*/
Fahrt1.start();
Fahrt2.start();
Fahrt3.start();
Fahrt4.start();
}
}
Die Klassenstruktur sieht wie folgt aus:
Package RMI.Server:
FahrtInterface
FahrtImpl
FahrtServer
Package RMI.Client:
FahrtInterface (Gleicher Inhalt wie in RMI.Server.FahrtInterface)
RmiFahrt (Thread)
RmisimuliereFahrten (Der Client, der ausgeführt werden soll)
Ich bin schon nicht sicher, ob das geht, dass ich "fi" vom Typ Fahrtinterface aus "RmisimuliereFahrten" an den Thread übergeben kann und dann der Thread mit dem Server kommunizieren kann und über "fi.updateBuchung" (Zeile 49 in "RmiFahrt") auf die Datenbank zugreifen kann.
Aber so weit komme ich eh noch nicht!
Den Server kann ich starten, das ist kein Problem.
Aber wenn ich dann "RmisimuliereFahrten" ausführe, bekomme ich diesen Fehler:
Exception in thread "main" java.lang.ClassCastException: $Proxy0 cannot be cast to RMI.Client.Fahrtinterface
at RMI.Client.RmisimuliereFahrten.main(RmisimuliereFahrten.java:21)
Wieso klappt der Cast da nicht? Ich habe alle meine Vorlesungsunterlagen durchforstet und mache alles (was die Verbindung zwischen Server und Client angeht) genau so, wie es beschrieben wurde.
Habe auch gestern und heute schon stundenlang gegoogelt, habe aber keine Lösung gefunden...
Kann mir bitte jemand helfen, ich bin echt am verzweifeln!?