problemas al implementar runnable

El problema que tengo con este codigo es el siguiente, como ven hago uso de runnable para comunicarme con mi listener hecho en java el cual hace el trabajo correctamente, ya que mis objeto (ticketPremiado) se carga con lo datos del premio el problema es que si ese objecto
lo llamo desde el main usando un funcion getter simepre me llega null y no se porque????
ya que el debugger y seguimiento mi objetoticketPremio le lleguan datos?????

sera que el problema etiene que ver porque ese objeto lo carga una funcion que llama el metodo
Run ???? o como se debe hacer para que pueda hacer ese getter de objeto y pueda usar los datos en cualquier lado???

package com.ac75.utility;

import com.ac75.dto.loticolombia.TicketPremiado;
import com.ac75.listener.ClienteService;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author fabio.rojas
 */

public class UtilSendServer implements Runnable, Serializable
{
   
    private ClienteService service;
    private BufferedReader bufferInput;
    private Socket socket;
    private ArrayList<String> encabezadoTrama;
    private ArrayList<String> datosPremios;
    private String algo;
    public TicketPremiado ticketPremiado;  
    public void conectar(String path)
    {
   
    try {
            this.service= new ClienteService();
            this.socket=this.service.conect(path);
            this.bufferInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            Thread thread = new Thread(this);
            thread.start();
        }
   
    catch(UnknownHostException e)
    {
        System.out.println("error"+e.getMessage());
    }
   
     catch(IOException e)
   {
       UtilFrame.setMensajeError("No hay comunicacion con el server \n Intente mas tarde", "MENSAJE ERROR");
       System.exit(0);
   }
    }
   
     private void desconectar()
    {
        try {
            this.socket.close();
             this.bufferInput.close();
        } catch (IOException ex) {
            System.out.println("cerrando Conexion");
        }
       
    }
   
    private boolean enviaMensajeAlserver(String mensaje)
      {
          return this.service.send(mensaje);
               
      }
    @Override
    public void run() {
       
         String tramaRespuestaServer;
         try {
              this.bufferInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
              while((tramaRespuestaServer = (String) bufferInput.readLine())!=null)
              {
                encabezadoTrama= UtilListener.descompilaraEncabezado(tramaRespuestaServer);
               
                if(Long.parseLong(encabezadoTrama.get(0))==tramaRespuestaServer.length())
                {
                   switch (Integer.parseInt(encabezadoTrama.get(1)))
                     {
                         
                          case 84:pagoPremios(tramaRespuestaServer);break;
                             
                     }
                 
                }
               }
             
             
         } catch (IOException ex) {
           
             Logger.getLogger(UtilSendServer.class.getName()).log(Level.SEVERE, null, ex);
         }
       
    }
   
    private void queryToServer(String codigoBoleto)
    {
     
       String aux="~84~00|"+trnGana+"~"+"0264"+"~"+ UtilCadena.IDTerminal()+"|";
       String mensajef = UtilCadena.Lpad((aux.length()+4)+"", '0', 4)+aux;
       enviaMensajeAlserver(mensajef);
   
    }
    private void pagoPremios(String mensaje)
           
     {
       ticketPremiado = new TicketPremiadoLoticolDTO();
         datosPremios =UtilListener.descompilaraDatos(mensaje, 0);
         //System.out.println(encabezadoTrama.get(2));
         if(datosPremios.size()==1)
         {
             //error servidor no disponible
             if("03".equals(encabezadoTrama.get(2)))
             {
               UtilFrame.setMensajeInformation(datosPremios.get(0), "INFORMACION");
             
             }
             
             
             else if("02".equals(encabezadoTrama.get(2)))
             {
               UtilFrame.setMensajeInformation(datosPremios.get(0), "INFORMACION");
             
             }
             //error trn gana no disponibl
             else if("01".equals(encabezadoTrama.get(2)))
             {  
             UtilFrame.setMensajeInformation(datosPremios.get(0), "INFORMACION");
           
             }
         }
       
           // AQUI ESTE OBJETO QUE CARGO CON LOS DATOS QUE RECIBO DEL LISTENER
          // ME GUSTARIA PODER USARLOS EN CUALQUIER LADO(EN EL MAIN  O EN  //OTRA   //CLASE  QUE CONSIDERE PERO ) Y AL HACER  getTicketPremiado()  siempre me llega null :(
     
           
             ticketPremiado.setIdPremio(datosPremios.get(0));
             ticketPremiado.setVlrGanado(Double.parseDouble(datosPremios.get(1)));
             ticketPremiado.setNumero(datosPremios.get(2));
             ticketPremiado.setSerie(datosPremios.get(3));
       
           
         
             
         
         
      }
   
      public void BuscaTicketPremiado(String codigoBoleto)
    {
        queryToServer(codigoBoleto);
       
    }

    public TicketPremiadoLoticolDTO getTicketPremiado() {
        return ticketPremiado;
    }

   
   
     
     
   
}

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.

SIMPRE...

o en la clase que necesito los datos ella simpre debe inpmenetar runnable , sobreescribir el metodo run
???????? ,

Esto:            Thread

Esto:

           Thread thread = new Thread(this);
            thread.start();

Crea un nuevo hilo y si estas intentando saber el resultado inmediatamente después de encontrarás con nulo porque aun no se ha llenado.

           /// Main thread ....
           
           Thread thread = new Thread(this);  // new Thread  
            thread.start();   // ahora hay dos hilos, Main y new
            System.out.println( " Despues de start" );
            this.getTicketPremiado(); ///  en Main thread el resultado sigue siendo nulo en el el otro esta obteniéndose

Dependiendo de lo que necesites puedes utilizar otro mecanismo, como que el hilo nuevo le avise al otro hilo que ya termino, o usar otras clases como Future o SwingWorker.Échalee un ojo a ambas y ve cual te puede servir.

Cuando encuentres tu solucion escribe un post sobre cual era tu problema y como lo resolviste ;)

Ok gracias

por ahi estoy mirando la de swingWorker y estoy mirando el ejemplo de la documentacion oficial de una barra de progresos si no estoy mal el metodo que me indica que si mi hilo termino es done
creo que por ahi es la cosa si no me equivoco.

public class TaskBarraProgreso extends SwingWorker<Void, Void> {

    public TaskBarraProgreso() {
    }
   
   

    @Override
    protected Void doInBackground() throws Exception
    {
           Random random = new Random();
            int progress = 0;
            //Initialize progress property.
            setProgress(0);
            while (progress < 100) {
                //Sleep for up to one second.
                try {
                    Thread.sleep(random.nextInt(1000));
                } catch (InterruptedException ignore) {}
                //Make random progress.
                progress += random.nextInt(10);
                setProgress(Math.min(progress, 100));
            }
            return null;
       
    }
     @Override
        public void done() {
            Toolkit.getDefaultToolkit().beep();
            //startButton.setEnabled(true);
            //setCursor(null); //turn off the wait cursor
            //taskOutput.append("Done!\n");
        }
}

trate de impelemntar swingWorker

pero sigo sin obtener resultados positivos, sigue llegando null, trate de implemntar el swing worker pero tal vez no lo estoy usando bien, como soy nuevo en estos conceptos, bueno seguire intentando haber

Que es lo que quieres hacer?

Que es lo que quieres hacer? ( en términos de funcionalidad, no de programacion )

lo que necesito

simplemente la clase UtilSendServer la primera que publique consultar al sevidor el servidor devuevle unos datos que los metos en el objeto ticketpremiado, lo que necesito es obtener referencia de esa clase ticketpremiado y usar sus datos ya se en otra clase o en un main por ejemplo. pero simpre que intento acceder a ese ticketpremiado esta null :(

REEMPLACE RUNNABLE POR UN CALLABLE

intente hacer esto reemplace la interfaz runnable por un callable
para hacer algo como:

         server.conectar("C:\\rutaconfig\\");
          server.BuscaTicketPremiado("9019000");
          ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(12);
          Future<TicketPremiadoLoticolDTO> resultado = executor.submit(server);  

          System.out.println(resultado.get().getIdPremio());  //aqui sigue siendo nulo

Pues segun yo te iba a dar un

Pues segun yo te iba a dar un ejemplo muy sencillo pero por el manejo de excepciones, hilos y demas me salio un ejemplo que esta algo grande y además tiene varios puntos malos.

En fin, como ya lo hice ahi te va. Quiza aun te sirva para entendre porque esta regresando nulo.

Lo que hice son tres clases

1. Server
2. Client
3. App
( bueno 4, Ticket )

Cada uno maneja un aspecto diferente, el server genera el ticket ganadar, el client solo lo obtiene y la app solo lo pinta.

Algo que esta mal aqui es que estoy creando un thread por cada client y eso no escala muy bien, mejor seria usar un executer con un fixedThreadPool con un tamananio igual al numero de procesadores ( asi cada hilo es atendido por un core ). El manejo de exceptiones tambien deja mucho que desear, es muy malo simplemente cachar Exception. Etc. etc

import java.net.*;
import java.io.*;
import java.util.*;
import java.util.concurrent.TimeUnit;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

import static java.lang.System.out;

/**
 * Genera un ticket nuevo y atiende a los clientes
 */

class Server {

    private Ticket winner;
    private Random random;
    private ServerSocket server;

    public static void main( String ... args ) throws Exception {
        new Server().run();
    }
    private void run() throws Exception {
        out.println("Starting");
        random = new Random();
        selectWinnerEvery(TimeUnit.SECONDS.toMillis(5));
        createServer();
        handleClients();
    }

    private void selectWinnerEvery( final long delay ) {
        java.util.Timer assignNewWinner = new java.util.Timer();
        assignNewWinner.schedule( new TimerTask() {
            public void run() {
                winner = Ticket.newTicket( random.nextInt( 1000000 ) ); // aleatorio del 0 al millon
                out.println("Server has a new winner " + winner);
            }
        }, 0, delay );
    }
    private void createServer() throws Exception {
        server = new ServerSocket(8090);
        out.println("Server running "+ server );

    }

      private void handleClients() throws Exception {
        for ( ;; ) {
            final Socket client = server.accept();
            Thread t = new Thread( new Runnable() {
                public void run() {
                    try {
                        out.println("Handling: "+ client );
                        Thread.currentThread().sleep(10000); // simula carga ( mucha ) de un retraso de 10 s
                        ObjectOutputStream oos = new ObjectOutputStream(client.getOutputStream());
                        oos.writeObject( winner );
                        oos.close();
                    } catch ( Exception e ) {
                        out.println( e );
                    } finally {
                        if ( client != null ) try  {
                            client.close();
                        } catch ( IOException ioe ) {}
                    }
                }
            });
        t.start();
        }
    }
}

/**
 * Se conecta al servidor y obtiene el ticket ganador, o null si no hay servidor
 */

class Client {
    public Ticket fetchWinner() {

        Socket client = null;
        try {
            client = new Socket("localhost", 8090);
            ObjectInputStream ois = new ObjectInputStream(client.getInputStream());
            return ( Ticket ) ois.readObject();
        } catch ( ClassNotFoundException cnfe ) {
            return null;
        } catch ( IOException ioe ) {
            return null;
        } finally {
            if ( client != null ) try  {
                client.close();
            } catch ( IOException ioe ) {}
        }
    }
    public static void main( String ... args )  {
        Client c = new Client();
        out.println( c.fetchWinner());
    }
}

/**
 * Crea una ventana y utiliza la clase cliente para obtener el ticket ganador
 */

class App {
   
    public static void main( String ... args ) {

        JFrame frame = new JFrame();
        JLabel label = new JLabel("Ticket ganador");
        final JTextField tf = new JTextField(5);
        JButton search = new JButton("Buscar");
        search.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent e ) {
                Thread t = new Thread( new Runnable()  {
                    public void run() {
                        Client c = new Client();
                        final Ticket ticket = c.fetchWinner();
                        if ( ticket == null ) {
                            out.println("No hay ticket. Estara arriba el servidor?");
                            return;
                        }
                        SwingUtilities.invokeLater( new Runnable() {
                            public void run() {
                                tf.setText( ticket.toString() );
                            }
                        });
                    }
                });
                t.start();
           
            }
        });

        JPanel panel = new JPanel();
        panel.add( label );
        panel.add( tf );
        panel.add( search );
        frame.add( panel );
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible( true );
    }
}

/**
  * El ticket ...
  */

class Ticket implements Serializable {
    private int number;
    static Ticket newTicket( int number ) {
        Ticket t = new Ticket();
        t.number = number;
        return t;
    }
    public String toString() {
        return "#"+number;
    }
}

ok estoy mirando linea a linea tu codigo

hay unas lineas que nunca habia usado y me resalta de una que son:

SwingUtilities.invokeLater( new Runnable() {
    @Override
    public void run() {
        tf.setText( ticket.toString() );
    }
});

En el metodo actionPerformed

En el metodo actionPerformed creo un nuevo hilo para obtener la informacion ( aqui es donde deberia utilizarse el SwingWorker ) . Cuando el resultado esta listo ( cuando el cliente regresa el ticket ) entonces hay que poner de nuevo el valor en el textfield. En Java Swing , las actualizaciones a los componentes se deben de hacer en un hilo especial que se llama.... EDT creo ( event dispatcher thread ) o algo asi; el metodo SwingUtilities.invokeLater hace precisamente eso, llama al tf.setText en ese hilo especial.

Podrias no hacerlo y llamar directamente tf.setText() y estoy seguro que no notarias diferencia, pero cuando el cambio es mas grande se puede congelar momentaneamente la pantalla ( porque swing deja de pintar los controles para ejecutar el codigo ) Eso pasaba mucho antes y Java se gano una mala reputacion de que hacia interfaces que congelaban.

~~

ok mira lo que necesito

package com.ac75.utility;

import com.ac75.dto.loticolombia.TicketPremiadoLoticolDTO;
import com.ac75.listener.ClienteService;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;

public class UtilSendServer implements Runnable, Serializable
{
   
 
    private ClienteService service;
    private BufferedReader bufferInput;
    private Socket socket;
    private ArrayList<String> encabezadoTrama;
    private ArrayList<String> datosPremios;
    private TicketPremiadoLoticolDTO ticket;
   

    public UtilSendServer() {
    }
   
    public void conectar(String path) throws InterruptedException
    {
     
       try {
            this.service= new ClienteService();
            this.socket=this.service.conect(path);
            this.bufferInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            Thread thread = new Thread();
            thread.start();
           
        }
   
    catch(UnknownHostException e)
    {
        System.out.println("error"+e.getMessage());
    }
   
     catch(IOException e)
   {
       UtilFrame.setMensajeError("No hay comunicacion con el server \n Intente mas tarde", "MENSAJE ERROR");
       System.exit(0);
   }
    }

 
   
     public void desconectar()
    {
        try {
            this.socket.close();
             this.bufferInput.close();
        } catch (IOException ex) {
            System.out.println("cerrando Conexion");
        }
       
    }
   
     private boolean enviaMensajeAlserver(String mensaje)
      {
          return this.service.send(mensaje);
      }
     
     private void queryToServerTrnGana(String trnGana)
    {
     
       mensajef="mi mensaje al server";
       enviaMensajeAlserver(mensajef);
    }
    private void pagoPremios(String mensaje)
    {
     

         datosPremios =UtilListener.descompilaraDatos(mensaje, 0);
         //System.out.println(encabezadoTrama.get(2));
         if(datosPremios.size()==1)
         {
             //error servidor no disponible
             if("03".equals(encabezadoTrama.get(2)))
             {
               UtilFrame.setMensajeInformation(datosPremios.get(0), "INFORMACION");
             
             }
             
             
             else if("02".equals(encabezadoTrama.get(2)))
             {
               UtilFrame.setMensajeInformation(datosPremios.get(0), "INFORMACION");
             
             }
             //error trn gana no disponibl
             else if("01".equals(encabezadoTrama.get(2)))
             {  
             UtilFrame.setMensajeInformation(datosPremios.get(0), "INFORMACION");
           
             }
         }
            ticket = TicketPremiado.newTicket(datosPremios.get(0), datosPremios.get(1),datosPremios.get(2),Double.parseDouble(datosPremios.get(3)));
                   
       
     }
   
      public void BuscaTicketPremiado(String codigo)
    {
        queryToServerGana(codigo);
       
    }

    @Override
    public void run()
    {  
       
          String tramaRespuestaServer;
         try {
              this.bufferInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
              while((tramaRespuestaServer = (String) bufferInput.readLine())!=null)
              {
                encabezadoTrama= UtilListener.descompilaraEncabezado(tramaRespuestaServer);
               
                if(Long.parseLong(encabezadoTrama.get(0))==tramaRespuestaServer.length())
                {
                     switch (Integer.parseInt(encabezadoTrama.get(1)))
                     {
                         
                          case 84:pagoPremios(tramaRespuestaServer);break;
                             
                     }
                 
                }
               
               

               }
             
             
         } catch (IOException ex) {
           
             Logger.getLogger(UtilSendServer.class.getName()).log(Level.SEVERE, null, ex);
         }
       
    }

    public TicketPremiado getTicket() {
        return ticket;
    }

    public void setTicket(TicketPremiado ticket) {
        this.ticket = ticket;
    }

   
   

   
   
 
 
 
   

}

public class TicketPremiado implements ITicketPremiado, Serializable {
   
    String idPremio;
    Double vlrGanado;
    String numero;
    String serie;
   
   
   public static TicketPremiado newTicket(String id,String numero,String serie,Double vlrGadado)
    {
        TicketPremiado t = new TicketPremiado();
        t.setIdPremio(id);
        t.setNumero(numero);
        t.setSerie(serie);
        t.setVlrGanado(vlrGadado);
        return t;
   
    }

   
   
    @Override
    public String getIdPremio() {
        return idPremio;
    }

    @Override
    public void setIdPremio(String idPremio) {
        this.idPremio = idPremio;
    }

    @Override
    public Double getVlrGanado() {
        return vlrGanado;
    }

    @Override
    public void setVlrGanado(Double vlrGanado) {
        this.vlrGanado = vlrGanado;
    }

    @Override
    public String getNumero() {
        return numero;
    }

    @Override
    public void setNumero(String numero) {
        this.numero = numero;
    }

    @Override
    public String getSerie() {
        return serie;
    }

    @Override
    public void setSerie(String serie) {
        this.serie = serie;
    }

    @Override
    public int compareTo(ITicketPremiado o) {
        return this.getIdPremio().compareTo(o.getIdPremio());
    }

    @Override
    public int hashCode() {
        return this.getIdPremio().hashCode()*31;
    }

    @Override
    public boolean equals(Object obj) {
        boolean r = false;
        if(obj instanceof ITicketPremiado)
        {
       
            ITicketPremiado iticketpremiado = (ITicketPremiado)obj;
            r=this.getIdPremio().equals(iticketpremiado.getIdPremio());
        }
        return r;
    }
   
   
   
}

AQui es donde necesito que me llegue ese objeto con los datos y no un simple null

public class Principal {

     
    public static void main(String[] args) throws UnknownHostException, InterruptedException, Exception
    {
         
         
       
          ControlLoteria control = new ControlLoteria("C:\\idr\\");
         
          server.conectar("C:\\webapps\\");
          server.BuscaTicketPremiado("90190003384951201602");
         System.out.println(server.getTicket());
       
           
     
       
    }
}

:-oCreí que era un proyecto

:-o

Creí que era un proyecto en el que estabas experimentando / de la escuela

No parece tener mucho sentido que inventes tu propio protocolo pues como puedes ver trae muchos problemas. Y no van a parar aquí, el manejo de concurrencia por ejemplo te va a dar muchos problemas y ya los estas viendo con algo sencillo como esto.

Seria mucho mejor que tu server fuera un servidor como tomcat y tu cliente lo podrías codificar con HttpClient de Apache Commons y el mensaje puede ser json o algún otro formato. Servirá mejor, sera mas sencillo, robusto y seguro.

Al parecer la razón por la que no funciona ( y es lo que te escribí desde el post inicial ) es porque estas preguntando el numero de ticket mucho antes de que se obtenga y por lo tanto es nulo

A ver si con este ultimo ejemplo te queda claro ( si no creo que no tendrás muchas esperanzas )

import static java.lang.System.out;
import java.util.Date;

class ThreadDemo {

    public static void main( String ... args ) {

        L.og("Creando el servicio" );
        Service s = new Service();

       
        new Thread((Runnable)s).start();
        L.og("Despues de iniciarl el hilo" );

        L.og("Obteniendo el resultado" );        
        L.og("El resultado es: "+ s.getElDato() ); // Obviamente es nulo

    }
}
class Service implements Runnable {

    private String elDato = null;

    public void run() {

        L.og("Comienza la ejecucion del servicio");
        L.og("Va a simular trabajo por 2 segundos");
        try {
            // esto simula trabajo ....
            Thread.currentThread().sleep(2000);
            L.og("Termina la simulacion");
        } catch ( InterruptedException ie ) {}

        L.og("Asignando valor");
        elDato = "Algo";
        L.og("Resultado elDato = "+ elDato );
    }
    public String getElDato() {
        return  elDato;
    }
}
// Muestra el mensaje con hora y nombre del hilo que lo envia
class L {
    static void og( String message ) {
        System.out.printf("[%1$tS.%1$tL - %2$-8s] %3$s%n", new Date(), Thread.currentThread().getName(), message);
    }
}

Como puedes ver la razón por la que sale nulo es porque esa linea con el get, se ejecuta inmediatamente después de crear el servicio y en ese momento aun en nulo. Es dos segundos después cuando se asigna el valor. De dejo la salida con milisegundos incluidos para que veas cuando van sucediendo las cosas.

// Ejecucion del programa
$ java ThreadDemo
[44.968 - main    ] Creando el servicio
[44.978 - main    ] Despues de iniciarl el hilo
[44.978 - Thread-0] Comienza la ejecucion del servicio
[44.978 - main    ] Obteniendo el resultado
[44.979 - Thread-0] Va a simular trabajo por 2 segundos
[44.979 - main    ] El resultado es: null
[46.980 - Thread-0] Termina la simulacion
[46.981 - Thread-0] Asignando valor
[46.982 - Thread-0] Resultado elDato = Algo

server

si con la sugerencia del webservice estoy migrando ya a restful y devuelvo todo a json y me apoyo con json
lo de server a mano era solo que nunca habia tocado estos temas y queria aprender disculpa por molestar tanto.....

:) Si es para aprender

:)

Si es para aprender solamente me parece magnífico, yo mismo a veces hago las cosas desde cero para aprender los conceptos que hay y como puedes ver yo estoy dispuesto a ayudar.

Si es para algo más profesional, me parece que la mejor manera es usando otras herramientas.

Por ejemplo para la aplicación web puedes usar Spring MVC y para el cliente HttpClient

Yo mismo estoy aprendiendo spring MVC apenas y encontré estos recursos muy buenos.

(... después de mucho tiempo )

Hice el ejemplo de la aplicación web con el cliente

Cree un post con los detalles:

http://www.javamexico.org/blogs/oscarryz/ejemplo_de_aplicacion_web_clien...

Saludos!!

SPRING MVC

con el me apoyo para construcción del webservice??? porque el web service su construccion manual son jersey y gson me parecio sencilla

Super! Podrias publicar un

Super!

Podrias publicar un post con los links o lo que hiciste para usar jersey y gson. Suena interesante.

vale ya lo posteo

ok ya posteo el ejemplo.
nunva me he apoya de framework y estava mirando lo de spring mvc suena bien, claro que ese mvc en mis aplicaciones siempre la he hecho a mano
mis clases (simpre manejo DTO ) ejemplo: PERSONADTO(clase) IPERSONADTO(interface) para el acceso a los datos manejos mis daos
ejemplo: PERSONADAO(clase ) IPERSONADAO(interface) tengo un facade donde intacio mis daos PERSONAFACADE y finalmente tengo mi controler
CONTROLPERSONA(que maneja la intacia de personafacade) todo esto por lo general lo tengo en un jar y en mis aplicaciones sobre ese modelo añado el jar y solo intacion los controler que necesito esa es la forma manual en que hagos las cosas.