Avatar billede napisok Nybegynder
07. juni 2004 - 17:34 Der er 24 kommentarer og
2 løsninger

rmi med database

Jeg er ved at lave noget rmi med database, men kan kun komme i kontakt med Kontrol/modellaget der er på serveren, den skriver nullpointerexception med fejl i databaseforbindelse. Men før kørte det fint uden rmi. Hvad er der galt, måske nogle der har et kodeeksempel, hvor man fra en gui opretter i en sqldatabase.
eks fejl er: Database.executeQuery StationDB.selectObject
Avatar billede arne_v Ekspert
07. juni 2004 - 17:43 #1
Hvis du giver os en stack trace af fejlen og 20 linier kode omkring
stedet så kan vi sikkert hjælpe
Avatar billede arne_v Ekspert
07. juni 2004 - 17:43 #2
Jeg har eksepel på db gui, men din db app er jo en server app og ikke
en gui app !?
Avatar billede napisok Nybegynder
07. juni 2004 - 17:46 #3
Den første fejl er executeQuery i denne kode

import java.sql.*;
import java.lang.reflect.Proxy;
import java.lang.reflect.*;
public class Database{
  public static Database database = null;  //singleton
    private String driver = "org.gjt.mm.mysql.Driver";
  private Connection connection = null;
    private Database(){
  }
      public static Database instance(){
      if( database == null ){
          database = new Database();      }
      return database;  }
      public void open(String url, String user, String password){
      try{
        Class.forName(driver);
        connection = DriverManager.getConnection(url+ user+password );
        System.out.println("åbnet");      }
      catch ( ClassNotFoundException cnfex ) {
        System.err.println("Failed to load JDBC/ODBC driver." );
        cnfex.printStackTrace();      }
      catch ( SQLException sqlex ) {
        System.err.println( "Unable to connect" );
        sqlex.printStackTrace();      }  }
      public int executeUpdate(String update) throws SQLException{
      return connection.createStatement().executeUpdate(update);  }
      public ResultSet executeQuery(String query) throws SQLException{
      return connection.createStatement().executeQuery(query);  }
      public void close(){
      try{
        connection.close();
        database = null;
      }
      catch(SQLException sqlex){
        sqlex.printStackTrace();      }  }}
Avatar billede napisok Nybegynder
07. juni 2004 - 17:48 #4
den næste StationDB er der en fejl i alle metoder men virkede før i rmi, det skal lige nævnes at jeg ikke er 100 meter mester i rmi

import java.sql.*;
import java.util.*;
public class StationDB implements IPersistent{
  private static StationDB stationDB = null;    //singleton
    private String table = "Station";
    private StationDB(){
    }
  public static StationDB instance(){
      if( stationDB == null ){
          stationDB = new StationDB();
      }
      return stationDB;
  }
  public synchronized void insert(Object o){
      try{
        Station st = (Station) o;
          String insertSt = "INSERT INTO " + table + " VALUES ('"+st.getAfgStation()+"','"+
                                                        st.getAnkStation()+"',"+
                                                        st.getTrspPris()+","+
                                                        st.getTrspTid()+")"; 
          Database.instance().executeUpdate( insertSt );
          System.out.println(insertSt);
          }
    catch(SQLException e){
        e.printStackTrace();
    }
  }
  public synchronized void update(Object o){
    try{
        Station sta=(Station) o;
        String update = "UPDATE " + table +
                    " SET AnkStation ='"+sta.getAnkStation()+"',"+
                                " TrspPris = " + sta.getTrspPris() + "," +
                    " TrspTid = " + sta.getTrspTid() + "" +
                      " WHERE AfgStation = '" + sta.getAfgStation() + "'";
           
            System.out.println(update);
        Database.instance().executeUpdate( update );
      }
    catch(SQLException e){
        e.printStackTrace();
    }
  }
  public synchronized void delete(Object o){
      try{
            Station st = (Station) o;
            String delete = "DELETE FROM " + table +
            " WHERE afgStation = '" + st.getAfgStation() + "'";
            Database.instance().executeUpdate( delete );
        }
        catch(SQLException sqlex){
            sqlex.printStackTrace();
        }
    }
 
 
  public synchronized Object selectObject(Object key){
    try{
        String id = (String ) key;
            String select = "SELECT * FROM " + table + " WHERE afgstation = '"+id+"'";
           
            ResultSet resultSet = Database.instance().executeQuery( select );
          Station st = null;
            if( resultSet.next() ){
            st=new Station();
            st.setAfgStation(resultSet.getString("AfgStation"));
             
            st.setAnkStation(resultSet.getString("AnkStation"));
            st.setTrspPris(resultSet.getDouble("TrspPris"));
            st.setTrspTid(resultSet.getInt("TrspTid"));
        }
        return st;
    }
    catch(SQLException sqlex){
        sqlex.printStackTrace();
        return null;
    }
  }
  public synchronized java.util.List selectObjects(String query){
    try{
        ResultSet resultSet = Database.instance().executeQuery( query );
        java.util.List list = new java.util.ArrayList();
        Station st = null;
       
        while( resultSet.next() ){
            st =new Station();
         
          st.setAfgStation(resultSet.getString("AfgStation")); 
       
          st.setAnkStation(resultSet.getString("AnkStation"));
          st.setTrspPris(resultSet.getDouble("TrspPris"));
          st.setTrspTid(resultSet.getInt("TrspTid"));       
         
         
         
         
          list.add( st );
        }
        resultSet.close();
       
        return list;
    }
    catch(SQLException sqlex){
        sqlex.printStackTrace();
        return null;
    }
  }
 
  public synchronized Station getAfgStation  (String id){
          return (Station)selectObject(id);
    }
  public synchronized java.util.List getAlleStation(){
      return selectObjects("SELECT * FROM Station");
  }
   
    }
Avatar billede arne_v Ekspert
07. juni 2004 - 17:50 #5
Hvordan ser stacktrace ud ?
Avatar billede simonvalter Praktikant
07. juni 2004 - 17:56 #6
laver du en
Database.instance().open();

og close()

før du kører  selectObjects
hvis ikke skulle du måske åbne den i metoden.
Avatar billede simonvalter Praktikant
07. juni 2004 - 17:59 #7
rettelse:
open før selvfølgelig og close efter..
og det gælder vel for alle dine metoder.
Avatar billede napisok Nybegynder
07. juni 2004 - 18:02 #8
Man åbner databasen i GUI (dette er for at gemme i databasen
åbnet
java.rmi.ConnectException: Connection refused to host: 192.168.2.101; nested exception is:
        java.net.ConnectException: Connection refused: connect
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:567)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:101)
        at StationKontrol_Stub.søgStation(Unknown Source)
        at StationGUI.actionPerformed(StationGUI.java:123)
        at java.awt.Button.processActionEvent(Button.java:382)
        at java.awt.Button.processEvent(Button.java:350)
        at java.awt.Component.dispatchEventImpl(Component.java:3615)
        at java.awt.Component.dispatchEvent(Component.java:3477)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
Caused by: java.net.ConnectException: Connection refused: connect
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158)
        at java.net.Socket.connect(Socket.java:452)
        at java.net.Socket.connect(Socket.java:402)
        at java.net.Socket.<init>(Socket.java:309)
        at java.net.Socket.<init>(Socket.java:124)
        at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
        at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:562)
        ... 15 more
Avatar billede napisok Nybegynder
07. juni 2004 - 18:05 #9
ups her er den rigtigt stacktrace
java.lang.NullPointerException
        at Database.executeQuery(Database.java:46)
        at StationDB.selectObject(StationDB.java:68)
        at StationDB.getAfgStation(StationDB.java:116)
        at StationKontrol.søgStation(StationKontrol.java:39)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:324)
        at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
        at sun.rmi.transport.Transport$1.run(Transport.java:148)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
        at java.lang.Thread.run(Thread.java:534)
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(StreamRemoteCall.java:247)
        at sun.rmi.transport.StreamRemoteCall.executeCall(StreamRemoteCall.java:223)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:133)
        at StationKontrol_Stub.søgStation(Unknown Source)
        at StationGUI.actionPerformed(StationGUI.java:123)
        at java.awt.Button.processActionEvent(Button.java:382)
        at java.awt.Button.processEvent(Button.java:350)
        at java.awt.Component.dispatchEventImpl(Component.java:3615)
        at java.awt.Component.dispatchEvent(Component.java:3477)åbnet

        at java.awt.EventQueue.dispatchEvent(EventQueue.java:456)
        at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:201)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:145)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:137)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:100)
Avatar billede arne_v Ekspert
07. juni 2004 - 18:08 #10
Tja det kan næsten kun være connection som er null

og Simons gæt på manglende open kald er ikke dårligt
Avatar billede napisok Nybegynder
07. juni 2004 - 18:11 #11
har placeret den i guien det er måske forkert
public void actionPerformed(ActionEvent e) {
              if(e.getSource()==SBgem){
            try{
                IStation sk=(IStation) Naming.lookup("rmi://192.168.2.101/onetrain");
            String url = "jdbc:mysql://localhost/onetrain?";
            String user = "user=root&";
            String password = "password=masterkey";
                   
            Database.instance().open(url,user,password);
                   
            double trsppris = Double.parseDouble(STtrsppris.getText());
            int trsptid = Integer.parseInt(STtrsptid.getText());
         
            if(sk.søgStation(STafgstation.getText())==null){
               
                sk.opretStation(STafgstation.getText(), STankstation.getText(), trsppris,trsptid);
               
                JOptionPane.showMessageDialog(null,"Station oprettet");
                rydFelter();
            }
            else{
                JOptionPane.showMessageDialog(null,"Station er oprettet vil du ændre den");
            }
            }
catch (Exception p){
    p.printStackTrace();
}
}
Avatar billede arne_v Ekspert
07. juni 2004 - 18:17 #12
Øh.

GUI'en er client ikke ?

Og koden køres på server ikke ?

Det går ikke !
Avatar billede arne_v Ekspert
07. juni 2004 - 18:17 #13
Overvej at flytte open kode op i constructor - jeg tror at det er nemmere
Avatar billede napisok Nybegynder
07. juni 2004 - 18:18 #14
du mener i main program eller gui (har et opstart der starter guien op)
Avatar billede napisok Nybegynder
07. juni 2004 - 18:25 #15
på client er kun guien
på server er resten af koden
Avatar billede simonvalter Praktikant
07. juni 2004 - 18:30 #16
i klienten kører du

Database.instance().open(url,user,password);

det kan du ikke da den ligger på server siden.

for at kunne gøre det skal du have fat i den over rmi.
det ville være smartere hvis du kaldte open på server siden når en af serverens metoder bliver brugt.
Avatar billede arne_v Ekspert
07. juni 2004 - 18:31 #17
Enten skal du kalde open i server programmer eller så skal du vælge den nemme løsning
og fjerne open metoden helt og flytte logikken op i constructor
Avatar billede napisok Nybegynder
07. juni 2004 - 18:36 #18
Tusinde tak arne det virker, men jeg har et spørgsmål ang. sikkerheden i mysql kan man oprette flere forskellige bruger med forskellige rettigheder, hvordan kan man få clienten til at logge på med dens rettigheder hvis man skal bruge server til at oprette forbindelse med databasen
Avatar billede arne_v Ekspert
07. juni 2004 - 18:39 #19
Du kan godt oprette forskellige brugere i MySQL.

I de fleste tilfælde vil man nok lade applikationen logge på MySQL med
et brugernavn/password og styre adgangen for applikations brugerne i
applikationen.

Men det kan også lade sig gøre at sende brugernes brugernavne/password
over til server programmet og lade det bruge dem til at logge på MySQL med.

Det kræver så en connection per client. Og altså ikke singleton pattern.

Og det skalerer ikke med rigtigt mange klienter.

Men det er muligt.
Avatar billede napisok Nybegynder
07. juni 2004 - 18:45 #20
Så lige det sidste spr. I denne kode er det kun en tabel der bliver brugt, men hvis der skal bruges flere tabeller og dette er ensbetydende med at der kommer flere kontrolklasser, hvordan undgår man at oprette flere interface (der skal være på client og server, (der er ikke en metode der er ens))
Avatar billede arne_v Ekspert
07. juni 2004 - 18:49 #21
Nu var det jo en oplagt mulighed at oprette et interface per tabel.

Men hvis det bliver for uoverskueligt så laver du noget generisk.

Et interface med en metode:

public List executeQuery(String sqlstr);

hvor implementationen laver executeQuery, løber result settet igennem
og laver en bean per række og gemmer dem i en ArrayList som returneres.
Avatar billede napisok Nybegynder
07. juni 2004 - 18:55 #22
Hvis du giver et svar, så jeg kan give point
Avatar billede arne_v Ekspert
07. juni 2004 - 19:01 #23
svar

(men Simon var faktisk også på banen og han havde faktisk fat i open
allerede  17:56:21)
Avatar billede napisok Nybegynder
07. juni 2004 - 19:04 #24
ja du har ret h
Avatar billede simonvalter Praktikant
07. juni 2004 - 19:11 #25
Jamen så smider jeg også et svar
Avatar billede arne_v Ekspert
21. juni 2004 - 22:22 #26
Tid at få afsluttet spørgsmålet ?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester