Última Atualização: 01 de outubro de 2002 01:04 BRST

Um exemplo simples

Esse exemplo trata de uma aplicação de leilão muito simplificada. Nosso objeto compartilhado (Offer) terá apenas quatro operações. Primeiro iremos definir a interface para o objeto compartilhado. Note que a interface deve extender java.io.Serializable e que todos os seus métodos devem lançar br.shob.ShobException.

   1:package auction.core;
   2:
   3:import br.shob.ShobException;
   4:
   5:public interface Offer extends java.io.Serializable {
   6:
   7:    public String getName() throws ShobException;
   8:    public double getValue() throws ShobException;
   9:    public String getWinner() throws ShobException;
  10:    public void doBid(double value, String user) throws InvalidBidException, ShobException;
  11:}
  12:

Uma vez compartilhado o objeto só poderá ser acessado através de uma referência. Podemos utlizar a ferramenta que é distribuída junto com o pacote, o Configurator. Para gerar a referência precisamos definir o seu nome, o arquivo onde serão guardadas as suas configurações, e quais métodos são de escrita. O configurator irá gerar um arquivo XML contendo todas essas informações. o Configurator recebe como parâmetro o arquivo .class com a interface compilada.

Abaixo vemos o XML gerado pelo Configurator.

   1:<?xml version="1.0" encoding="ISO-8859-1"?>
   2:<!DOCTYPE reference PUBLIC "shobreference" "http://www.linux.ime.usp.br/~tminc/shob.dtd">
   3:
   4:<reference name="auction.core.OfferReference">
   5:  <method name="public abstract java.lang.String auction.core.Offer.getName() throws br.shob.ShobException" write = "false" />
   6:  <method name="public abstract double auction.core.Offer.getValue() throws br.shob.ShobException" write = "false" />
   7:  <method name="public abstract java.lang.String auction.core.Offer.getWinner() throws br.shob.ShobException" write = "false" />
   8:  <method name="public abstract void auction.core.Offer.doBid(double,java.lang.String) throws auction.core.InvalidBidException,br.shob.ShobException" write = "true" />
   9:</reference>

A partir do arquivo de configuração podemos gerar a referência propriamente dita. Para isso utilizamos outra ferramenta, também distribuída com o pacote, o shobc. Ele recebe como parâmetro o arquivo XML gerado pelo Configurator e o .class da interface, e cria um arquivo .java com o código fonte da referência, que pode ser compilado junto com a aplicação.

Uma característica importante dessa referência é que o único vínculo entre ela e a classe original é a interface implementada por ambas. Por isso, a mesma referência pode ser utilizada para manipular implementações diferentes da mesma interface, o que pode ser de grande valia.

Abaixo vemos o código fonte da nossa referência. É importante ressaltar que o código abaixo não precisa ser alterado e nem mesmo entendido, ele está sendo mostrado apenas de maneira ilustrativa, assim como o XML mostrado acima.

   1:/*
   2:* Automatically generated class
   3:* Compiler version: br.shob-0.51-2002.09.04
   4:* Message protocol version: br.shob-1.0.1-2002.08.30
   5:*
   6:* File generated on: 09/30/2002 00:41 -0400
   7:*
   8:* http://shob.sourceforge.net/
   9:* http://www.jdom.org/
  10:*/
  11:
  12:package auction.core;
  13:
  14:
  15:import br.shob.*;
  16:import java.lang.reflect.*;
  17:
  18:public class OfferReference extends DefaultSharedReference implements auction.core.Offer {
  19:
  20:  public OfferReference(SharedSpace shob, String globalName) {
  21:    super(shob, globalName);
  22:  }
  23:
  24:  public java.lang.String getName()
  25:    throws ShobException {
  26:    try {// shared try
  27:        try {// call method try
  28:            Class[] argTypes = null;
  29:            Object[] args = null;
  30:
  31:            Object result = srCallMethod("getName", argTypes, args);
  32:            return (java.lang.String) result;
  33:        } catch (InvocationTargetException e) {
  34:            if (e.getTargetException() instanceof br.shob.ShobException) {
  35:                throw (br.shob.ShobException) e.getTargetException();
  36:            }
  37:            throw new ShobException(e);
  38:        }
  39:    } catch (InvocationException e) {
  40:      throw new ShobException(e);
  41:    }
  42:  }
  43:
  44:  public double getValue()
  45:    throws ShobException {
  46:    try {// shared try
  47:        try {// call method try
  48:            Class[] argTypes = null;
  49:            Object[] args = null;
  50:
  51:            Object result = srCallMethod("getValue", argTypes, args);
  52:            return ((Double)result).doubleValue();
  53:        } catch (InvocationTargetException e) {
  54:            if (e.getTargetException() instanceof br.shob.ShobException) {
  55:                throw (br.shob.ShobException) e.getTargetException();
  56:            }
  57:            throw new ShobException(e);
  58:        }
  59:    } catch (InvocationException e) {
  60:      throw new ShobException(e);
  61:    }
  62:  }
  63:
  64:  public java.lang.String getWinner()
  65:    throws ShobException {
  66:    try {// shared try
  67:        try {// call method try
  68:            Class[] argTypes = null;
  69:            Object[] args = null;
  70:
  71:            Object result = srCallMethod("getWinner", argTypes, args);
  72:            return (java.lang.String) result;
  73:        } catch (InvocationTargetException e) {
  74:            if (e.getTargetException() instanceof br.shob.ShobException) {
  75:                throw (br.shob.ShobException) e.getTargetException();
  76:            }
  77:            throw new ShobException(e);
  78:        }
  79:    } catch (InvocationException e) {
  80:      throw new ShobException(e);
  81:    }
  82:  }
  83:
  84:  public void doBid(double p1, java.lang.String p2)
  85:    throws ShobException,
  86:           auction.core.InvalidBidException {
  87:    try {// shared try
  88:        try {// call method try
  89:            srBeginTrans();
  90:            Class[] argTypes = new Class[] {                                          Double.TYPE,
  91:                                          java.lang.String.class};
  92:            Object[] args = new Object[] {                                        new Double(p1),
  93:                                        p2};
  94:
  95:            Object result = srCallMethod("doBid", argTypes, args);
  96:            srCommit();
  97:        } catch (InvocationTargetException e) {
  98:            srRollback();
  99:            if (e.getTargetException() instanceof auction.core.InvalidBidException) {
 100:                throw (auction.core.InvalidBidException) e.getTargetException();
 101:            }
 102:            else if (e.getTargetException() instanceof br.shob.ShobException) {
 103:                throw (br.shob.ShobException) e.getTargetException();
 104:            }
 105:            throw new ShobException(e);
 106:        }
 107:    } catch (AlreadyLockedException e) {
 108:      throw new ShobException(e);
 109:    } catch (NotLockedException e) {
 110:      throw new ShobException(e);
 111:    } catch (InvocationException e) {
 112:      throw new ShobException(e);
 113:    }
 114:  }
 115:
 116:}

 Agora iremos realmente implementar o objeto, como faríamos numa aplicação padrão. Podemos perceber que a classe abaixo não prevê um uso distrbuído, ela é implementada como se o objeto fosse utilizado apenas localmente.

   1:package auction.server;
   2:
   3:import auction.core.*;
   4:
   5:public class OfferImpl implements Offer {
   6:
   7:    private String name;
   8:    private double value;
   9:    private String winner;
  10:
  11:    public OfferImpl(String name, double value, String winner) {
  12:        this.name = name;
  13:        this.value = value;
  14:        this.winner = winner;
  15:    }
  16:
  17:    public String getName() {
  18:        return name;
  19:    }
  20:
  21:    public double getValue() {
  22:        return value;
  23:    }
  24:
  25:    public String getWinner() {
  26:        return winner;
  27:    }
  28:
  29:    public void doBid(double value, String user) throws InvalidBidException {
  30:        if(value < getValue()) {
  31:            throw new InvalidBidException("Invalid bid. " + value + " < " + getValue());
  32:        }
  33:        this.value = value;
  34:        this.winner = user;
  35:    }
  36:}
  37:

 Nossa aplicação de exemplo é bem simples: o servidor compartilha apenas um objeto do tipo Offer e deixa que os clientes façam lances nessa oferta.

   1:package auction.server;
   2:
   3:import br.shob.*;
   4:import auction.core.*;
   5:
   6:public class AuctionServer {
   7:
   8:    public final static void main(String args[])
   9:        throws Exception {
  10:
  11:        //cria um SharedSpace
  12:        SharedSpace shob = new SharedSpace("localhost", 0);
  13:
  14:        //connecta o SharedSpace ao servidor de nomes
  15:        shob.connect("localhost", 5000);
  16:        
  17:        //cria uma Offer
  18:        Offer offer = new OfferImpl("potato", 10.0, null);
  19:
  20:        //compartilha a Offer
  21:        shob.share("offer1", offer, "auction.core.OfferReference");
  22:    }
  23:}
  24:

Os clientes que participam do leilão também são extremamente simples, eles apenas lêem o valor da oferta e realizam um lance maior.

   1:package auction.client;
   2:
   3:import br.shob.*;
   4:import auction.core.*;
   5:
   6:public class AuctionClient {
   7:
   8:    public final static void main(String args[])
   9:        throws Exception {
  10:
  11:        //cria um SharedSpace
  12:        SharedSpace shob = new SharedSpace("localhost", 0);
  13:
  14:        //connecta o SharedSpace ao servidor de nomes
  15:        shob.connect("localhost", 5000);
  16:
  17:        //pega uma Offer
  18:        Offer offer = (Offer)shob.get("offer1");
  19:
  20:        System.out.println("Offer Name:   " + offer.getName());
  21:        System.out.println("Offer Value:  " + offer.getValue());
  22:        System.out.println("Offer Winner: " + offer.getWinner());
  23:        
  24:        double bid = offer.getValue() + 10;
  25:        System.out.println("Bid: " + bid);
  26:        offer.doBid(bid, "user1");
  27:        System.out.println("Offer Value:  " + offer.getValue());
  28:        System.out.println("Offer Winner: " + offer.getWinner());
  29:    }
  30:}
  31:

 Com esse exemplo conseguimos mostrar quias são os passos necessários para se criar uma aplicação que utliza o shob. A dificuldade para se criar uma aplicação distribuída não é muito maior que a dificuldade para se criar uma aplicação local, o que mostra todo o poder do shob.