Última Atualização: 01 de outubro de 2002 01:04 BRST
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.