Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 291
  • Last Modified:

RMI, How to convert an application (JDBC) to make it distributed ?

I currently have a program which will access an Oracle database no problem. However I need to convert the included problem into a distributed program using RMI so that I can run it form an applet.
Yes I know about type four driver, servlets etc.
I HAVE to use RMI.
The question is this.
Given the code below what are the stages required as I am new to RMI.

Can anyone please tell me what the sections/programs will be ?
This is challenging!
( ignore the reference to the bridge in the driver i do not have my oracle example here )>

import java.awt.*;
import java.awt.event.*;
import java.sql.*;


// Works Well, Compiles and shows interface.
// Performs simple select all from a specified table
// Displays results , cool huh ?
//

/** Connect to the specified table on the specified
 *  host and retrieve/display the entire table.
 *  Java 1.1 only.
 */

public class ShowTable extends Frame
                       implements ActionListener {
  public static void main(String[] args) {
    new ShowTable("ShowTable");
  }

  protected LabeledTextField tableField, hostField,
                             dbNameField;
  protected Button showTableButton;
  protected Panel inputPanel, tablePanel;
  protected Connection connection;
  protected ResultSetMetaData metaData;
 
  public ShowTable(String title) {
    super(title);
    inputPanel = makeInputPanel();
    add("North", inputPanel);
    pack();
    setVisible(true);
  }

  /** When the user clicks the "Show Table" button,
   *  the specified table is retrieved and
   *  a Panel is created to hold the results.
   */

  public void actionPerformed(ActionEvent event) {
    if (event.getSource() == showTableButton) {
      makeConnection();
      invalidate();
      if (tablePanel != null)
        remove(tablePanel);
      tablePanel = makeTablePanel();
      add("Center", tablePanel);
      pack();
      validate();
    }
  }

  // Connect to the specified host and database
  // using bridge
  // username and password.
                         
  private void makeConnection() {
    String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
    try {
      Class.forName(driver);
      String host = hostField.getTextField().getText();
      String url =
      "jdbc:odbc:"+  
      dbNameField.getTextField().getText();
      String user = "xxxx", password="xxxx";
      connection =
        DriverManager.getConnection(url, user, password);
      Statement statement = connection.createStatement();
    } catch(ClassNotFoundException cnfe) {
      System.out.println("No such class: " + driver);
    } catch(SQLException se) {
      System.out.println("SQLException: " + se);
    }
  }

  // Create a Panel that holds the textfields that
  // gather user input, plus the "Show Table" button.
                         
  private Panel makeInputPanel() {
    Panel inputPanel = new Panel();
    inputPanel.setBackground(Color.lightGray);
    hostField = new LabeledTextField("Host Name:", 20);
    inputPanel.add(hostField);
    dbNameField = new LabeledTextField("DB Name:", 10);
    inputPanel.add(dbNameField);
    tableField = new LabeledTextField("Table Name:", 15);
    inputPanel.add(tableField);
    showTableButton = new Button("Show Table");
    inputPanel.add(showTableButton);
    showTableButton.addActionListener(this);
    return(inputPanel);
  }

  // Create a Panel with one TextField for each table
  // entry, plus an extra row for the column names.
                         
  private Panel makeTablePanel() {
    Panel tablePanel = new Panel();
    tablePanel.setBackground(Color.white);
    try {
      // Create statement
      Statement statement = connection.createStatement();
      // Lookup table name
      String table = tableField.getTextField().getText();
      // Ask for everything in that table
      ResultSet results =
        statement.executeQuery("SELECT * FROM "+ table);
      // Get MetaData that determines number of columns
      // and column names
      metaData =
        results.getMetaData();
      int cols = metaData.getColumnCount();
      // Layout Panel to hold specified number of
      // columns and whatever number of rows is needed
      tablePanel.setLayout(new GridLayout(0, cols));
      // A boldface textfield for each column name
      TextField field;
      Font headerFont =
        new Font("SansSerif", Font.BOLD, 14);
      for(int i=1; i<=cols; i++) {
        field = new TextField(metaData.getColumnName(i));
        field.setFont(headerFont);
        tablePanel.add(field);
      }
      // A regular-face textfield for each table entry
      Font bodyFont =
        new Font("Serif", Font.PLAIN, 12);
      String value;
      while(results.next())
        for(int i=1; i<=cols; i++) {
          value = results.getString(i);
          if (value == null)
            value = "<null>";
          field = new TextField(value);
          field.setFont(bodyFont);
          tablePanel.add(field);
        }
    } catch(SQLException se) {
      System.out.println("SQL Exception: " + se);
    }
    return(tablePanel);
  }
}


0
docpressman
Asked:
docpressman
  • 2
  • 2
1 Solution
 
msmolyakCommented:
Looks like you GUI code and the code which interacts with the database are in the same class. The main change to you rprogram will be separating the GUI and business logic into separate classes. The GUI class will run on the client. The class containing the business logic (accessing the RDB and supplying the data) will be remote and run on the server. I would recommend making that change before going into RMI.

The GUI class comes up, displays the frame. When the show table button is pressed, the GUI class creates an instance of the class which has methods for getting the relevant data (data class). This second class is called upon whenever new data from the database are required.

Once you are tested that setup you are ready for RMI.

Create a Java interface which extends java.rmi.remote and defines all the method which the GUI class needs for interacting withe the data store (probably all the public methods you have in your data class). Then, change your data class to extend the interface you've just created. The implementation will not change much. You hae to make sure that all teh methods defined in the interface throw RemoteException and that all the data types you take in and return the data class methods are serializable (or remote). Most of the basic object types such as String, Vector, Hashtable are serializable (I am not sure about the ResultSet).

You have to do some special stuff in the constructor (or main() method) to create and register the RMI server. I leave it to you to read and understand. It is really easy. If you have any questions, let me know.

Good luck.

Michael
0
 
evijayCommented:
My advice is to use RMIJdbc directly instead of rewriting the code.
RMIJdbc is a type 4 jdbc driver to connect to applet that uses RMI as its transport and hence you need not change much of the code. You just need to replace driver name with the name of RMIJdbc driver.
See this location for more info.

http://dyade.inrialpes.fr/mediation/download/RmiJdbc/JBuilder/RJPaper.html

 
0
 
drpressmanCommented:
I was looking more for general help with splitting the program into the required sections.
Thanks for the RMiJDBC comment.
However it has to be pure RMI.

Any offers for helping with the code ?
0
 
drpressmanCommented:
I was looking more for general help with splitting the program into the required sections.
Thanks for the RMiJDBC comment.
However it has to be pure RMI.

Any offers for helping with the code ?
0
 
msmolyakCommented:
Let me try.

The ShowTable class will have all the code to create the GUI, define the user interactions and populate the controls. But rather than doing queries by itself it will outsource the job to a specialized class, say, DataConnection.

This subcontractor class will establish the connection to the RDB and provide necessary table data and meta-data. Looks like you need these methods in DataConnection class:

public void connect(String (or URL) connectionString);

public String getColumnName(String tableName, int colId);

public void runSelect(String tableName);

public String[] getNextRow();

Thus, when you construct your GUI, ShowTable class will instantiate the DataConnection class and will use it to get all the data.

This design is very rough, I am sure you will come up with something better suitable to your needs.
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now