Pular para o conteúdo principal

Projeto de sistemas distribuídos usando CORBA, parte II : Primeiros passos

1. Um pouco mais sobre o CORBA

O padrão CORBA é um framework que permite que aplicações distribuídas em uma rede (local ou mesmo na internet) comuniquem-se entre si e troquem informações. Estas aplicações podem estar sendo executadas em diferentes plataformas (Intel, Sun, etc) e sistemas operacionais (Windows, Linux, Unix, etc) e podem ter  sido construídas em diferentes linguagens de programação. 
Utilizando o padrão CORBA é possível ter aplicações completamente distribuídas, potencialmente com cada pedaço de software sendo executado em qualquer parte da rede e em qualquer plataforma, sem que o usuário perceba que isto está acontecendo e sem que o desenvolvedor precise se preocupar em criar soluções que resolvam os problemas de interoperabilidade entre os diferentes pedaços da aplicação. Atualmente, diversas ferramentas já suportam o padrão CORBA, como Delphi 4, JBuilder 2, Oracle 8i, Cold Fusion e C++ Builder. Uma grande vantagem de CORBA é ser um padrão diretamente suportado por empresas em todo o mundo e com dezenas de implementações disponíveis, incluindo algumas gratuitas. Na prática, essa padronização significa que você não precisa ficar preso a determinados fornecedores, plataformas ou produtos, como acontece quando são escolhidas soluções proprietárias.

2. ORB
A arquitetura CORBA define o ORB (Object Request Broker) como um módulo intermediário entre cliente e objeto, sendo responsável em aceitar a requisição do cliente, enviá-la para o objeto competente e, assim que disponível a resposta, entregá-la para o cliente.

3.IDL
A CORBA utiliza a IDL (Interface Definition Language), uma linguagem baseada em C++ que não possui algoritmos nem variáveis, ou seja, é puramente declarativa, e, portanto, é independente da linguagem de programação utilizada para acessá-la. Há padrão de IDL definido pelo OMG para C, C++, Java, TTCN, COBOL, Smalltalk, Ada, Lisp, Python e IDLscript. Possibilita a interoperabilidade entre os diversos sistemas, visto a separação que é definida entre interface e execução. A interface de cada objeto é definida de forma bastante específica, enquanto a sua execução (código fonte e dados) permanece oculta para o resto do sistema.

4.Primeiros passos
A primeira coisa que definimos é que já que o CORBA suporta o paradigma de orientação a objetos , vamos "enviar objetos mensagens" de uma estação para outra , isso vai tornar muito mais fácil o tratamento das mensagens quando elas chegarem nas estações , colocamos enviar objetos entre aspas porque o CORBA não faz exatamente isso, mas vamos explicar isso em momento oportuno.

Definido o formato da mensagem precisamos criar o arquivo IDL (Interface Definition Language), que vai definir como vai acontecer a troca de informação entre as estações , no nosso projeto o arquivo ficou da seguinte forma:


struct Evento{
string tipo;
long timestamp;
long origem;
long ordemEnvio;

};

interface Mensagem{

void sendMensagem(in Evento ev);


};


Nomeamos o arquivo IDL como Mensagem.idl , o objeto mensagem está espelhado na Struct Evento , como a IDL é baseada em C++  temos que usar structs quando quisermos manipular objetos , nesse caso nosso objeto será Evento  e ele terá os seguintes campos :

  • tipo: pode assumir 'e' no caso de evento interno ou 'm' no caso de mensagem sendo enviada para as outras estações.
  • timestamp :  leva o timestamp indicando o momento ( de acordo com o relógio lógico de lamport) quando o evento ocorreu .
  • origem : indica de onde está vindo a mensagem
  • ordem de envio : indica a ordem local do evento ,  1º , 2º , 3º evento a ocorrer na estação "x" e assim sucessivamente.
Para mais detalhes sobre relógios escalares de Lamport , procurar o livro : Sistemas Distribuídos conceitos e projeto - Coulouris etal . Capitulo 11 - Tempo e estados globais.

Depois de definir a struct definimos a interface Mensagem , essa interface será mapeada em diversas classes holder e stubs que mostraremos a seguir , dentro da interface temos um método abstrato sendMensagem ( in Evento ev) ... a escolha do nome do método não foi feliz na verdade ele devia ser mudado para receiveMensagem , quando analisarmos o código vai dar para ver isso melhor ... continuando o in Evento ev  significa que o método recebe um Evento  ev e que só serve para receber ou seja é um método de entrada de dados ( input ) por isso o in.

O projeto foi todo desenvolvido usando o Netbeans , então criamos um projeto java  e um pacote que chamamos de PSD ( projeto de sistemas distribuídos - olha a criatividade ai :-)  ) , depois de criar esse projeto criamos o arquivo Mensagem.idl ...

O próximo passo é usar o compilador IDL que vai ler o arquivo e gerar as classes auxiliares necessárias, para isso utilizamos o prompt de comando ou o terminal (no meu caso) , entramos na pasta que contem os arquivos e digitamos o comando: idlj -fall Mensagem.idl ( veja a figura abaixo)


O compilador IDL vai gerar todas as classes auxiliares necessárias ao projeto , veja abaixo como ficou a pasta do projeto depois da compilação do arquivo idl.





A partir do arquivo idl ( arquivo de texto ) o compilador cria a classe Evento , arquivos holder e helper além do arquivo POA e Stub , basicamente cada uma tem uma tarefa :


  • POA :  Esta classe abstrata é baseada no esqueleto do servidor. Extende org.omg.PortableServer.Servant, e implementa a interface InvokeHandler e a interface MensagemOperations. A classe de servidor, HelloServant, extende MensagemPOA
  • Holder e Helper : implementam operações necessárias a comunicação em corba .
  • Stub : é a classe responsável por serializar e deserealizar os objetos no momento da transmissão , o corba na verdade não envia objetos de uma estação para outra , ele envia um streaming de bytes que podem depois ser convertidos para objetos java , com o uso do stubs isso fica transparente para o programandor.
  • Operations :  Esta interface contém o método sendMessage() . O idlj coloca as operações definidas na interface IDL dentro este arquivo, que é compartilhado por ambos o stubs e esqueletos.

Acabou a parte fácil , agora é programar tudo no braço , muita calma nessa hora . Pela especificação do projeto precisamos de uma camada de aplicação e outra de serviços ( cliente / servidor ).

Na camada de aplicação colocamos uma classe apenas chamada PSD , ela vai ativar na camada de serviço as classes de servidor e emissor como a figura abaixo :



Acima da PSD temos a camada de GUI ( Graphical User Interface ) que foge do escopo do artigo mas que deve ser mostrada no ultimo post , na camada de servico temos as seguintes classes:

Servidor : aciona o servidor da aplicação e publica o objeto no servidor de nomes
Emissor : recebe os eventos do PSD
Relógio : implementação do relógio lógico de lamport ,  acessado tanto pela classe servant quanto pelo emissor.
Servant: esse é o servidor propriamente dito , ele vai receber as mensagens e montar o buffer de delivery das 3 estações .

5. Classe PSD ( camada de aplicação ) :

Vamos explicar essa classe parte por parte

package psd8;

import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Joao
 */
public class PSD1 implements Runnable{

    /**
     * @param args the command line arguments
     */
    
    boolean imprimiu = false;
    private ArrayList buffertmp = new ArrayList();
    ServidorMensagem servm;
    MensagemServant ms = new MensagemServant();
    private static ArrayList b1 = new ArrayList();
    private static ArrayList b2 = new ArrayList();
    private static ArrayList b3 = new ArrayList();
    private static ArrayList bufferDelivery = 
                                               new ArrayList();
    private static boolean bufferNaoMontado = true;
    private static Semaphore semBD ;
    private static boolean terminar = false;


Essa classe é o PSD1 por que tirei da implementação da estação 1 , a primeira coisa importante a dizer é que a classe implementa Runnable , isso por que ela vai funcionar como uma thread , alias esse sistema é cheio de threads o que requer muita atenção e cuidados extras , se vc não entende de threads recomento o artigo do GUJ  Introdução ao sincronismo e monitores .

A classe também tem vários arraylists b1,b2, b3 é para armazenar as mensagens que chegam das estações , essas mensagens depois vão ser usadas na camada gráfica (GUI) , a mesma coisa acontece com o bufferDelivery que é o buffer onde ocorre a montagem da ordem total de entrega das mensagens segundo os relógios lógicos , na verdade o buffer de delivery é montado na classe servant mas é acessado concorrente mente com a classe PSD , e por isso usamos a classe Semaphore , semáforo são uma das formas de se controlar o acesso concorrente de processos em uma variável no caso o buffer de montagem , isso acontece no nosso projeto por que a medida que as mensagens vão chegando o buffer de delivery é montado e a aplicação vai pegando os valores colocados no buffer , tudo concorrentemente , veja que nesse ponto o complicado não é o sistema distribuído em si mas o acesso concorrente e o uso de varias threads .

Continuando na classe PSD ...

    public void run() {
        
        this.iniciar();
        
    }
     
     
  public void iniciar( ){




Esse método run deve ser implementado em cada classe que implemente Runnable quando a thead desse processo começar a rodar é esse método run que vai rodar primeiro , no nosso programa ele chama o método iniciar ...

 
public void iniciar(){
     String[] args=null;
        
        Relogio.initRelogio();//inicia o relógio logico de Lamport
        
        //instancia um servidor que ira publicar as mensagens e criar o servant
         servm = new ServidorMensagem(args);
        Thread tservidor = new Thread(servm);
        tservidor.setName("Thread do servidor");
        tservidor.start();
            try {
                tservidor.join();
                //aguarda aqui até a thread do servidor teminar isso é necessario
                //para que não se tente rodar a thread cliente antes de registar 
                //os objetos no servidor de nomes
            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        //iniciar o montador de bufferFinal    
        ms.iniciarMontagem();    
         
        
        Emissor em = new Emissor(args);
        Thread tcliente = new Thread(em);
        tcliente.setName("Thread do cliente");
        
        tcliente.start();
            try {
                tcliente.join();
                //aguarda o cliente terminar de transmitir a mensagem

            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
        
            
         //já pronto para enviar mensagens
            
        //thread para acesso ao buffer de delivery no servant
        new Thread(new GetBufferDelivery()).start();
        
        //String _tipo, int _timestamp, int _origem, int _ordemEnvio
        
        ArrayList lista = new ArrayList();
        Evento e1 = new Evento("e",0, 1,1);
        lista.add(e1);
        Evento e2 = new Evento("m",0, 1,2);
        lista.add(e2);
        Evento e3 = new Evento("m",0, 1,3);
        lista.add(e3);
        Evento e4 = new Evento("e",0, 1,4);
        lista.add(e4);
        Evento e5 = new Evento("m",0, 1,5);
        lista.add(e5);
        Evento e6 = new Evento("m",0, 1,6);
        lista.add(e6);
        Evento e7 = new Evento("x",100, 1,7);
        lista.add(e7);
        
         //enviar eventos
        for (Evento ev : lista) {
            em.enviarMensagem(ev);
            
        }
                   
        
 }   

Inicialmente o psd inicializa o relógio lógico ( Relogio.initRelogio(); ) que deve começar com timestamp = 0 e ir avançando conforme os eventos internos e mensagens ocorrem , logo depois o psd instanciá a classe Servidor que é responsável por publicar o objeto remoto no servidor de objetos corba ( falamos dele daqui a pouco) , o servidor é instanciado atravez de uma thread , o comando tservidor.join(); obriga a thread atual aguardar a finalização da thread do servidor , isso é necessário por que logo mais vamos chamar o emissor e não podemos começar a emitir as mensagens sem que o servidor esteja "no ar ".

Depois que o servidor estiver funcionando iniciamos uma outra thread que é a thread de montagem do buffer delivery( ms.iniciarMontagem();  ) , essa thread está como uma classe interna do servant logo usamos a referencia ao servant para aciona-la  no comando:
 
O próximo passo é iniciar o emissor de mensagem( Emissor em = new Emissor(args);) , novamente em uma thread (Thread tcliente = new Thread(em); ), ele vai ter o método que possibilita o envio das mensagens . Pelo mesmo motivo do anterior fazemos um join nessa thread , isso por que o emissor deve estar funcionando para que passemos para a próxima etapa do algoritmo que é gerar e enviar os enventos , se o emissor não estiver pronto vamos gerar os eventos e na hora de enviar vai dar erro .

Depois de inicializar o emissor ( também chamado de cliente ) iniciamos uma outra thread de montagem de buffer localmente ou seja , temos uma classe interna em PSD que vai tentar acessar o buffer de delivery  conforme ele for montado e dessa forma "puxar"os valores da camada de serviço para a camada de aplicação ( new Thread(new GetBufferDelivery()).start(); ).

Nesse momento estamos com o aplicativo como a figura sugere
Como já estamos prontos para enviar as mensagens , montamos primeiramente um ArrayList com todos os evento , internos e mensagens , cada um segundo a especificação do problema, aqui cabe algumas explicações , o timestamp de cada evento esta zerado por que vai ser atualizado no momento do envio pela classe Emissor utilizando a classe Relógio . O ultimo elemento da lista é um X isso é um evento que não vai atualizar o relógio ele só é um sinalizador que a estação 1 já enviou tudo que tinha para enviar o timestamp dele é 100 para não interferir na hora de ordenar os eventos , na verdade qualquer numero alto serviria nesse caso . Finalmente o For final envia um a um os evento ao emissor , tanto os internos "e"quanto os externos "m", talvez ai a gente tenha perdido pontos no projeto já que um evento externo não precisava ser enviado só atualizado o relógio mas enviamos mesmo assim ....

O restante do código tem métodos gets e sets para as variáveis , um método que pega os semáforos usados nos buffers , um método que limpa todos os buffers ao final da operação para que a estação comece a transmitir tudo novamente, um método para desconectar do servidor de localização de objetos corba, um método utilitário que imprime os valores que estão nos buffers e  finalmente a classe interna que puxa concorrentemente os valores do buffer de delivery

  
 
public void desconectar(){
     
     servm.unbindNoServidor();
     
 }
 
 public void getSemaforos(){
    semBD = MensagemServant.getSemBD();
 }
    
    public static void insertValorB1(Evento e) {
        b1.add(e);
    }

    public static void insertValorB2(Evento e) {
      b2.add(e);
    }

    public static void insertValorB3(Evento e) {
        b3.add(e);
    }

    public static void insertValorbufferDelivery(Evento e) {
        bufferDelivery.add(e);
    }
    
   
  
//metodos para uso da Interface grafica
    public static ArrayList getB1() {
        return b1;
    }

    public static ArrayList getB2() {
        return b2;
    }

    public static ArrayList getB3() {
        return b3;
    }

    public static ArrayList getBufferDelivery() {
        return bufferDelivery;
    }

    public static boolean isBufferNaoMontado() {
        return bufferNaoMontado;
    }
    
    
    
    public static void imprimirDadosPSD(){
        System.out.println("Imprimindo buffer de Delivery no PSD!!!!!!!!");
        System.out.println("Tamanho do Buffer:"+ bufferDelivery.size() );
             for (Evento ev : bufferDelivery) {
                System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 1:");
             for (Evento ev : b1) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 2:");
             for (Evento ev : b2) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
              System.out.println("Imprimindo Buffer 3:");
             for (Evento ev : b3) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             bufferNaoMontado = false;
    }
    
    
public void limparBuffers(){
   b1.removeAll(b1);
   b2.removeAll(b2);
   b3.removeAll(b3);
   bufferDelivery.removeAll(bufferDelivery);
   bufferNaoMontado = true;
   terminar = false;
    
}



public class GetBufferDelivery implements Runnable{

        public void run() {
            getSemaforos();
            
            while(true){
                
                
                
                
          if(ms.getTamanhoBufferDelivery() != 0 ){
                     // puxar elemento por elemento
                        
                     try {
                        semBD.acquire();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
                    }    
                        
                     
                     
                       Evento e = ms.getValorNoBufferDelivery();
                       if(e.tipo.compareToIgnoreCase("x")==0){
                           terminar = true; //termina thread e nao adiciona eventos nos buffers
                       }else{
                               bufferDelivery.add(e);
                            if (e.origem == 1) {
                                b1.add(e);
                            } else if (e.origem == 2) {
                                b2.add(e);
                            } else if (e.origem == 3){
                                b3.add(e);
                            }
                       } 
                       
                       semBD.release();
                    
          }
              
          
                    if(terminar){
                        imprimirDadosPSD();
                        break;
                    }  
          
                                                     
     }//fim do while
                
                
     }


Vale a pena comentar o código da classe interna (GetBufferDelivery) , essa classe testa se o buffer de delivery no servant não está vazio , quanto não estiver vazio ela vai no servant e pega um evento no BFDelivery , claro que para isso ela aciona o semáforo correspondente para só ela conseguir acessar o BFD , cada valor puxado é adicionado no BufferDelivery local da classe PSD e também nos buffers individuais de cada emissor ( b1, b2, b3) , o processo termina quando a classe puxar um evento tipo x no BFD do servant .
Por enquanto é isso , nos próximos post vamos ver como funciona o relógio e as demais classes terminando com a classe de GUI , o código completo do PSD1 segue abaixo , até o próximo post.

CODIGO COMPLETO DA CLASSE PSD1

package psd8;

import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Joao
 */
public class PSD1 implements Runnable{

    /**
     * @param args the command line arguments
     */
    
    boolean imprimiu = false;
    private ArrayList buffertmp = new ArrayList();
    ServidorMensagem servm;
    MensagemServant ms = new MensagemServant();
    private static ArrayList b1 = new ArrayList();
    private static ArrayList b2 = new ArrayList();
    private static ArrayList b3 = new ArrayList();
    private static ArrayList bufferDelivery = new ArrayList();
    private static boolean bufferNaoMontado = true;
    private static Semaphore semBD ;
    private static boolean terminar = false;
    

     
     
     
     
    public void run() {
        
        this.iniciar();
        
    }
     
     
 public void iniciar(){
     String[] args=null;
        
        Relogio.initRelogio();//inicia o relogio logico de Lamport
        
        
         servm = new ServidorMensagem(args);
        Thread tservidor = new Thread(servm);
        tservidor.setName("Thread do servidor");
        tservidor.start();
            try {
                tservidor.join();
                //aguarda aqui até a thread do servidor teminar isso é necessario
                //para que não se tente rodar a thread cliente antes de registar 
                //os objetos no servidor de nomes
            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
            
        //iniciar o montador de bufferFinal    
        ms.iniciarMontagem();    
         
        
        Emissor em = new Emissor(args);
        Thread tcliente = new Thread(em);
        tcliente.setName("Thread do cliente");
        
        tcliente.start();
            try {
                tcliente.join();
                //aguarda o cliente terminar de transmitir a mensagem

            } catch (InterruptedException ex) {
                Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
            }
        
            
         //já pronto para enviar mensagens
            
        //thread para acesso ao buffer de delivery no servant
        new Thread(new GetBufferDelivery()).start();
        
        //String _tipo, int _timestamp, int _origem, int _ordemEnvio
        
        ArrayList lista = new ArrayList();
        Evento e1 = new Evento("e",0, 1,1);
        lista.add(e1);
        Evento e2 = new Evento("m",0, 1,2);
        lista.add(e2);
        Evento e3 = new Evento("m",0, 1,3);
        lista.add(e3);
        Evento e4 = new Evento("e",0, 1,4);
        lista.add(e4);
        Evento e5 = new Evento("m",0, 1,5);
        lista.add(e5);
        Evento e6 = new Evento("m",0, 1,6);
        lista.add(e6);
        Evento e7 = new Evento("x",100, 1,7);
        lista.add(e7);
        
         //enviar eventos
        for (Evento ev : lista) {
            em.enviarMensagem(ev);
            
        }
                   
        
 }   
    


  
 public void desconectar(){
     
     servm.unbindNoServidor();
     
 }
 
 public void getSemaforos(){
    semBD = MensagemServant.getSemBD();
 }
    
    public static void insertValorB1(Evento e) {
        b1.add(e);
    }

    public static void insertValorB2(Evento e) {
      b2.add(e);
    }

    public static void insertValorB3(Evento e) {
        b3.add(e);
    }

    public static void insertValorbufferDelivery(Evento e) {
        bufferDelivery.add(e);
    }
    
   
  
//metodos para uso da Interface grafica
    public static ArrayList getB1() {
        return b1;
    }

    public static ArrayList getB2() {
        return b2;
    }

    public static ArrayList getB3() {
        return b3;
    }

    public static ArrayList getBufferDelivery() {
        return bufferDelivery;
    }

    public static boolean isBufferNaoMontado() {
        return bufferNaoMontado;
    }
    
    
    
    public static void imprimirDadosPSD(){
        System.out.println("Imprimindo buffer de Delivery no PSD!!!!!!!!");
        System.out.println("Tamanho do Buffer:"+ bufferDelivery.size() );
             for (Evento ev : bufferDelivery) {
                System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 1:");
             for (Evento ev : b1) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             
             System.out.println("Imprimindo Buffer 2:");
             for (Evento ev : b2) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
              System.out.println("Imprimindo Buffer 3:");
             for (Evento ev : b3) {
                 System.out.println(  ev.tipo +ev.ordemEnvio + ev.origem +":"
                                  + ev.timestamp +","+ev.origem );
             }
             bufferNaoMontado = false;
    }
    
    
public void limparBuffers(){
   b1.removeAll(b1);
   b2.removeAll(b2);
   b3.removeAll(b3);
   bufferDelivery.removeAll(bufferDelivery);
   bufferNaoMontado = true;
   terminar = false;
    
}



public class GetBufferDelivery implements Runnable{

        public void run() {
            getSemaforos();
            
            while(true){
                
                
                
                
          if(ms.getTamanhoBufferDelivery() != 0 ){
                     // puxar elemento por elemento
                        
                     try {
                        semBD.acquire();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(PSD1.class.getName()).log(Level.SEVERE, null, ex);
                    }    
                        
                     
                     
                       Evento e = ms.getValorNoBufferDelivery();
                       if(e.tipo.compareToIgnoreCase("x")==0){
                           terminar = true; //termina thread e nao adiciona eventos nos buffers
                       }else{
                               bufferDelivery.add(e);
                            if (e.origem == 1) {
                                b1.add(e);
                            } else if (e.origem == 2) {
                                b2.add(e);
                            } else if (e.origem == 3){
                                b3.add(e);
                            }
                       } 
                       
                       semBD.release();
                    
          }
              
          
                    if(terminar){
                        imprimirDadosPSD();
                        break;
                    }  
          
                                                     
     }//fim do while
                
                
     }
            
}
    
}







Comentários

Postar um comentário

Ajude o blog a melhorar comente!!!

Postagens mais visitadas deste blog

Video Aulas de Java já disponíveis no 4Shared

Turma segue as video aulas já disponíveis para download no 4Shared , espero que vocês gostem das aulas e por favor postem um comentario no blog dizendo o que vc's acharam preciso desse feed back para o constante aprimoramento das aulas . Basta escolher o arquivo clickar  no link para download ( tenha paciencia os arquivos são grandes ) <p>&lt;p&gt;&amp;amp;amp;amp;lt;p&amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;gt;&amp;amp;amp;amp;amp;amp;amp;lt;br&amp;amp;amp;amp;amp;amp;amp;gt;se&amp;amp;amp;amp;lt;/p&amp;amp;amp;amp;gt;&lt;/p&gt;</p> Se a Janela de Download acima não funcionar tente acessar os arquivos usando o seguinte link http://www.4shared.com/dir/34812571/bf01348d/VideoAulas.html Bom estudo  :-)

Notícias da UFSC » UFSC é segunda universidade brasileira melhor colocada no Webometrics

Notícias da UFSC » UFSC é segunda universidade brasileira melhor colocada no Webometrics : A Universidade Federal de Santa Catarina passou à segunda instituição brasileira melhor qualificada no  Ranking Web of World Universities , sendo a primeira universidade federal brasileira no levantamento . No primeiro lugar geral se mantém a USP. No ranking passado, publicado no mês de janeiro, a UFSC ocupava a quarta posição. Na classificação para a América Latina, em que figurava como quinta universidade,  passou a terceira colocada. E no ranking mundial está entre as cem universidades do mundo: subiu da 129ª posição para a 98ª. Harvard University, Massachusetts Institute of Technology e Stanford University se mantêm no topoda classificação mundial. Entre as brasileiras, lideram aUniversidade de São Paulo (USP), UFSC e Universidade Estadual de Campinas (Unicamp)

Serialização de objetos I - Salvando objetos em arquivos

Serialização: como salvar seus objetos Java par utilizar quando precisar  Serialização de objetos é a possibilidade de salvar uma cópia completa de um objeto ou de uma coleção de objetos em um fluxo de saída (arquivo externo), de modo que o objeto pode ser recriado a partir da cópia serializada  quando necessário . A serialização de objetos Java,  fornece um recurso para transformar um grupo ou um único objeto em um fluxo de bits, ou um array de bytes para armazenar ou enviar pela rede,  de modo que o  referido fluxo de bits ou uma matriz de bytes pode ser transformado novamente em objetos Java. O processo de serialização também é conhecido como marshaling de um objeto, e de-serialização é conhecido como un-marshaling. Assim a serialização oferece os seguintes benefícios: Um sistema para persistência de objetos, ou seja, escrever as suas propriedades em arquivos externos ou discos, ou salvá-las em um banco de dados. Um sistema para chamadas d...