advanced topics in operating systems manual for lab

36
University of New York, Tirana M.Sc. in Computer Science Advanced Topics in Operating Systems Manual for Lab Practices PART II - Remote Method Invocation Three Tier Application with a Database Server Assoc. Prof. Marenglen Biba, Ph.D Department of Computer Science E-mail: [email protected]

Upload: others

Post on 22-Feb-2022

2 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Advanced Topics in Operating Systems Manual for Lab

University of New York, Tirana

M.Sc. in Computer Science

Advanced Topics

in Operating Systems

Manual for Lab Practices

PART II - Remote Method Invocation

Three Tier Application with a

Database Server

Assoc. Prof. Marenglen Biba, Ph.D

Department of Computer Science E-mail: [email protected]

Page 2: Advanced Topics in Operating Systems Manual for Lab

1. Document Purpose

This document contains explanations on how to run the following programs: RMI Servers, RMI Client and

Database Server.

For running the programs, a correct configuration of the running environment is

necessary (path and classpath variables).

Install JAVA (JDK)

Install Netbeans

Install MySQL

Install MySQL Workbench

Set path and Classpath variables in the operating system

Click on Enviroment Variables.

Page 3: Advanced Topics in Operating Systems Manual for Lab

Find the Path system variable and click Edit. Set the value of the variable to the directory where you have

installed Java, for example:

D:\Program Files\Java\jdk1.6.0\bin

Page 4: Advanced Topics in Operating Systems Manual for Lab

Download and Install MySQL Server:

After you download use MySQL Server Instance Config Wizard

Choose the detailed configuration:

Page 5: Advanced Topics in Operating Systems Manual for Lab

Choose developer machine:

Choose multifunctional:

Choose Drive:

Page 6: Advanced Topics in Operating Systems Manual for Lab

Choose decision support:

Perform the following checks:

Page 7: Advanced Topics in Operating Systems Manual for Lab

Best Support For Multilingualism: Choose this option if you want to use utf8 as the default server character

set. This is a Unicode character set that can store characters from many different languages.

Set the password for root:

Page 8: Advanced Topics in Operating Systems Manual for Lab

Press Execute:

Page 9: Advanced Topics in Operating Systems Manual for Lab

Restart the computer and the installation should be complete.

Install the MySQL Workbench.

You can create the database in two ways:

1. By commands in the MySQL console

2. By graphical user interface in MySQL Workbench

Click on local instance with the right and click Query Database.

Page 10: Advanced Topics in Operating Systems Manual for Lab

Click with the right and select create schema.

Give a name to the database: and press Apply.

Page 11: Advanced Topics in Operating Systems Manual for Lab

Click with the right on the Tables options and select Create Table:

Page 12: Advanced Topics in Operating Systems Manual for Lab

Choose a name for the Table:

Page 13: Advanced Topics in Operating Systems Manual for Lab

Click on Columns and add the columns for the table. At the end click Apply.

Page 14: Advanced Topics in Operating Systems Manual for Lab

Following the above procedure create three tables:

Table Account

Fields: IdAccount (int), Balance (float)

Table Customer

Fields: IdCustomer(int), Name (Varchar), Surname (Varchar)

Table AccountCustomer

Fields: IdAccount, IdCustomer

2. Developing the RMI Client and Server

When you finish this exercise, you will have run your first RMI system.

It consists of three major parts:

The RMI Registry that hold references to the remote services.

Page 15: Advanced Topics in Operating Systems Manual for Lab

The RMI host server program that creates the remote services, registers them with the registry and

waits for client requests.

The RMI client program. A program that obtains references to remote service object from the RMI

registry and then uses those services.

2.1 Fundamentals of RMI

This exercise will introduce you to the definition of RMI remote services using Java interfaces.

Educational goals:

Introduce the UML Description of a banking system

Complete the Java source code for the system interfaces

These are the interfaces to develop in the project.

File Account.java

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface Account extends Remote

{

// Add method to return master BankManager

// Add method to return Client of this account

// Add method to return balance of this account

// Add method to withdraw cash from this account

}

Page 16: Advanced Topics in Operating Systems Manual for Lab

------------------------------------------------

File BankManager.java

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface BankManager extends Remote

{

// Add method to return an Account service

// Add method to return a Client service

}

------------------------------------------------

File Client.java

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface Client extends Remote

{

// Add method to return master BankManager

// Add method to return the name of this client

}

2.2 Development of a Simple Banking System

In this part you will run your first RMI system. It is based on the Banking System that you started in the

previous exercise.

Educational goals:

Learn to run the RMI Registry as a separate process

Run a server that support remote RMI objects

Implement an RMI client that uses remote services.

The RMI Registry manages the publication of the RMI remote services. You have to run a server program

that creates the actual remote services, and finally, finish coding the program BankUser, which will use the

RMI remote services.

Page 17: Advanced Topics in Operating Systems Manual for Lab

Step 1: Code Development

Develop the following code in Netbeans:

Account.java

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface Account extends Remote {

// Add method to return master BankManager

public BankManager getBankManager()

throws RemoteException;

// Add method to return Client of this account

public Client getClient()

throws RemoteException;

// Add method to return balance of this account

public long getBalance()

throws RemoteException;

// Add method to withdraw cash from this account

public long getCash (long amount)

throws NoCashAvailableException, RemoteException;

}

BankManager.java

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface BankManager extends Remote {

// Add method to return an Account service

public Account getAccount(String accountNumber)

throws RemoteException;

// Add method to return a Client service

public Client getClient(String clientName)

throws RemoteException;

}

AccountImpl.java

import java.rmi.RemoteException;

public class AccountImpl implements Account {

private BankManager bankManager;

private Client client;

private long balance;

Page 18: Advanced Topics in Operating Systems Manual for Lab

private String accountNumber;

// public constructor

public AccountImpl (

BankManager bankManager,

Client client,

String accountNumber) {

this.bankManager = bankManager;

this.client = client;

this.balance = 0;

this.accountNumber = accountNumber;

}

public void deposit(long amount) {

balance += amount;

}

public BankManager getBankManager()

throws RemoteException {

return bankManager;

}

public Client getClient()

throws RemoteException {

return client;

}

public long getBalance()

throws RemoteException {

return balance;

}

public long getCash(long amount)

throws NoCashAvailableException, RemoteException {

if (amount > balance) {

throw new NoCashAvailableException();

}

balance = balance - amount;

return amount;

}

}

BankManagerImpl.java

import java.util.Hashtable;

import java.rmi.server.UnicastRemoteObject;

import java.rmi.RemoteException;

import java.util.ArrayList;

import java.sql.*;

Page 19: Advanced Topics in Operating Systems Manual for Lab

public class BankManagerImpl implements BankManager {

private Hashtable accounts;

private Hashtable clients;

private Connection conn;

private Statement s;

private int CustomerID;

// public No-argument constructor

public BankManagerImpl()

throws java.rmi.RemoteException {

initialize();

}

public Account getAccount(String accountNumber)

throws RemoteException {

AccountImpl account = (AccountImpl)accounts.get(accountNumber);

return account;

}

public Client getClient(String clientName)

throws RemoteException {

ClientImpl client = (ClientImpl)clients.get(clientName);

return client;

}

// public int getCustomerId(int accountId) throws RemoteException {

//return Database.getCustomerId2(accountId);

Page 20: Advanced Topics in Operating Systems Manual for Lab

// }

public void initialize()

throws java.rmi.RemoteException {

// Create the hashtables

accounts = new Hashtable(20);

clients = new Hashtable(10);

CreateConnection();

// Create clients and put them in the hashtable

Client clientCharlie = new ClientImpl(this, "Charlie");

UnicastRemoteObject.exportObject(clientCharlie);

Client clientShannon = new ClientImpl(this, "Shannon");

UnicastRemoteObject.exportObject(clientShannon);

clients.put("Charlie", clientCharlie);

clients.put("Shannon", clientShannon);

/// Threee Tier part: Connect to the Database server and get data

CustomerID = getCustomerId(1);

System.out.println("The customer Id from the database is:" + CustomerID);

Account account;

account = new AccountImpl(this, clientCharlie, Integer.toString(CustomerID));

((AccountImpl)account).deposit(500);

UnicastRemoteObject.exportObject(account);

accounts.put(CustomerID, account);

}

public boolean initializeConnection(String SERVER, String DATABASE, String USER_ID,

Page 21: Advanced Topics in Operating Systems Manual for Lab

String PASSWORD) throws ClassNotFoundException, SQLException {

try {

Class.forName("com.mysql.jdbc.Driver").newInstance();

String path = ("jdbc:mysql://"+ SERVER + "/" + DATABASE + "?user="

+ USER_ID + "&password=" + PASSWORD);

conn = DriverManager.getConnection(path);

s = conn.createStatement();

return true;

}

catch (SQLException e) {

return false;

}

catch (Exception e) {

e.printStackTrace();

return false;

}

}

public void CreateConnection(){

if(conn == null)

try{

initializeConnection("localhost","bank","root","password");

}catch(Exception e){e.printStackTrace();}

}

public int getCustomerId(int idAccount){

ArrayList<Integer> ids = new ArrayList<Integer>();

Page 22: Advanced Topics in Operating Systems Manual for Lab

try {

Statement s = conn.createStatement();

String sql = "Select IdCustomer from accountCustomer where idAccount ='" + idAccount +

"'";

ResultSet r = s.executeQuery(sql);

while(r.next()){

ids.add(r.getInt("IdCustomer"));

}

} catch (Exception ex) {

ex.printStackTrace();

}

return ids.get(0).intValue();

}

}

BankUser.java

import java.rmi.*;

import java.net.MalformedURLException;

import java.util.Locale;

import java.text.NumberFormat;

public class BankUser {

// Interface reference to BankManager

private BankManager bm;

// No-argument constructor

public BankUser() {

try {

bm = (BankManager)Naming.lookup(

"rmi://localhost:1099/BankSystem");

} catch (MalformedURLException malformedException) {

System.err.println("Bad URL: " + malformedException);

} catch (NotBoundException notBoundException) {

System.err.println("Not Bound: " + notBoundException);

} catch (RemoteException remoteException) {

System.err.println("Remote Exception: " + remoteException);

}

Page 23: Advanced Topics in Operating Systems Manual for Lab

try {

// Lookup account 1

Account account = bm.getAccount("1");

// Get client for account

Client client = account.getClient();

// Get name for client

String name = client.getName();

// Get balance for account

long cash = account.getBalance();

// Format and display output

NumberFormat currencyFormat =

NumberFormat.getCurrencyInstance(Locale.US);

String balanceString = currencyFormat.format(cash);

System.out.println(name + "'s account has " + balanceString);

} catch (RemoteException remoteException) {

System.err.println(remoteException);

}

}

public static void main(String[] args) {

new BankUser();

}

}

Client.java

import java.rmi.Remote;

import java.rmi.RemoteException;

public interface Client extends Remote {

// Add method to return master BankManager

public BankManager getBankManager()

throws RemoteException;

// Add method to return the name of this client

public String getName()

throws RemoteException;

}

ClientImpl.java

import java.rmi.RemoteException;

public class ClientImpl implements Client {

private BankManager bankManager;

private String clientName;

// public constructor

Page 24: Advanced Topics in Operating Systems Manual for Lab

public ClientImpl(BankManager bm, String name) {

this.bankManager = bm;

this.clientName = name;

}

public BankManager getBankManager()

throws RemoteException {

return bankManager;

}

public String getName()

throws RemoteException {

return clientName;

}

}

NoCashAvailableException.java

public class NoCashAvailableException extends Exception {

}

BankSystemServer.java

import java.io.IOException;

import java.rmi.Naming;

import java.rmi.RemoteException;

import java.rmi.server.UnicastRemoteObject;

import java.net.MalformedURLException;

public class BankSystemServer {

// public No-argument constructor

public BankSystemServer() {

}

public static void main(String args[]) {

new BankSystemServer();

BankManager bm = null;

try {

// Create a BankManager object

bm = new BankManagerImpl();

// Export it to RMI

UnicastRemoteObject.exportObject( bm );

} catch (RemoteException remoteException) {

System.err.println(

"Failure during object export to RMI: " +

remoteException);

}

// Register an external name for the service

try {

Page 25: Advanced Topics in Operating Systems Manual for Lab

Naming.rebind("//localhost/BankSystem", bm);

} catch (RemoteException remoteException) {

System.err.println(

"Failure during Name registration: " +

remoteException);

} catch (MalformedURLException malformedException) {

System.err.println(

"Failure during Name registration: " +

malformedException);

}

System.out.println("Server started.");

System.out.println("Enter <CR> to end.");

try {

int i = System.in.read();

} catch (IOException ioException) {

}

System.exit(0);

}

}

Step 2: Compile the code following these steps:

All the steps should be performed on the same directory where you have your .java files.

1. Compile the interfaces

Commands:

javac Account.java

javac BankManager.java

javac Client.java

2. Compile the implementation classes (Impl files)

javac AccountImpl.java

javac BankManagerImpl.java

javac ClientImpl.java

javac NoCashAvailableException.java

Page 26: Advanced Topics in Operating Systems Manual for Lab

3. Compile with rmic the implementation classes (Impl files)

Commands:

rmic AccountImpl

rmic BankManagerImpl

rmic ClientImpl

4. Compile the Client

javac BankUser.java

5. Compile the Server

javac BankSystemServer.java

In order to connect Java with MySQL we need the following connector:

mysql-connector-java-5.1.15-bin.jar

Add the connector to the libraries of the project in Netbeans as follows:

Click with right of the mouse on the Project.

Page 27: Advanced Topics in Operating Systems Manual for Lab

Select Properties

Page 28: Advanced Topics in Operating Systems Manual for Lab

Select Libraries

Page 29: Advanced Topics in Operating Systems Manual for Lab

Select on the right “Add JAR/Folder”.

Page 30: Advanced Topics in Operating Systems Manual for Lab

Select the file

mysql-connector-java-5.1.15-bin.jar

Now the Java program is properly set to connect to MySQL.

Page 31: Advanced Topics in Operating Systems Manual for Lab

Observe the content of the folder. You will find all the .class files.

Page 32: Advanced Topics in Operating Systems Manual for Lab

3. Run the services and programs

3.1 Run the RMI Registry program.

The RMI Registry program is provided as a separate executable in the rmiregistry program.

Create a console and move to the directory that will contain your code from this exercise.

From that location, run the registry with the following command:

rmiregistry

Do not close this window!

3.2 Run the RMI server that hosts the remote service objects.

You need to instruct your Java program where to find the JDBC driver in order to load it at runtime:

These are several ways with which you can achieve this:

1. You can copy the file mysql-connector-java-5.1.15-bin.jar under the directory of JRE:

Lib/ext/ (for example: D:\Program Files\Java\jre1.6.0\lib\ext)

This approach does not require that you set the classpath.

2. You may also try the following command that sets the classpath when you call the java program:

java –classpath= drive:/directory/mysql-connector-java-5.1.15-bin.jar yourprogram

One of the above methods is sufficient for the program to work correctly.

Page 33: Advanced Topics in Operating Systems Manual for Lab

Having set up correctly the JDBC path, you simply need to start the host program, BankSystemServer.

This is accomplished by creating a new console, moving to the directory which contains your code from this

exercise and running the following program:

java BankSystemServer

3.3 Run a program that will use the exported RMI services.

You simply need to start the client program, BankUser.

This is accomplished by creating a new console, moving to the directory which containts your code from

this exercise and running the following program: java BankUser.

If the database is as follows:

Page 34: Advanced Topics in Operating Systems Manual for Lab
Page 35: Advanced Topics in Operating Systems Manual for Lab

Depending on the above values of the fields in the AccountCustomer table you should see the effects of the

following code in BankManagerImpl:

CustomerID = getCustomerId(1);

System.out.println("The customer Id from the database is:" + CustomerID);

For example, if IDaccount is “1” as above, you will have the corresponding CustomerId printed.

If on your machine you have problems with the JDBC driver, you may also try the following command that

sets the classpath when you call the java program:

Page 36: Advanced Topics in Operating Systems Manual for Lab

Or if you have set the environment variable CLASSPATH you will see the following :

With command: echo %classpath% you may check the value of the CLASSPATH variable.