Tag Archives: Java

Instalar ubuntu64-general basado en Ubuntu Server 9.10 64 bits en KVM

Introducción.

De manera análoga a como se realizó anteriormente la instalación de una imagen con CentOS (para Scientific Linux se igual procedimiento) procedimos a crear una máquina virtual KVM con una instalación genérica de Ubuntu Server 9.10 para futuras experimentaciones con un plan de trabajo ligeramente modificado.

  1. Actualización de paquetes.
  2. Instalar ACPID.
  3. Instalación del JDK de Java.
  4. Instalación del ambiente de desarrollo C/C++.
  5. Instalación del servidor X y IceWM como administrador de ventanas.
  6. Depurar el software instalado.

Creación de la máquina virtual para la instalación del sistema operativo.

$ virt-install \
–connect qemu:///system \
-n ubuntuserver-9.10_x64-general \
-r 384 \
–os-type linux \
–os-variant generic26 \
–hvm \
–cdrom /u/isos/ubuntu-9.10-server-amd64.iso \
–network bridge:br0 \
–disk path=/u/vms/ubuntuserver-9.10_x64-general.img,size=7 \
–vnc –noautoconsole \
–accelerate

Conexión remota a la KVM para el proceso de instalación y administración.

$ /usr/bin/virt-viewer -c qemu+ssh://ivy/system ubuntuserver-9.10_x64-general

Actualización de paquetes.

$ sudo aptitude update

$ sudo aptitude safe-upgrade

Instalación de ACPID.

$ sudo aptitude install acpid

Instalación del JDK de Java.

$ sudo aptitude install sun-java6-bin sun-java6-fonts sun-java6-jdk sun-java6-jre sun-java6-plugin

Instalación del ambiente de desarrollo C/C++.

$ sudo aptitude install build-essential

Instalación del servidor X y IceWM como administrador de ventanas.

$ sudo aptitude install xorg icewm icewm-themes

Instalar centos64-general basado en CentOS 5.4 64 bits en KVM

Introducción.

El fin del presente artículo es el de preparar una imagen básica del sistema operativo, en este caso CentOS 5.4 de 64 bits, para futuros usos en experimentos y pruebas.  La infraestructura de virtualización que utilizo para implementarla es KVM.

En términos generales estos son las adecuaciones que tendrá está imagen básica.

  1. Actualización de paquetes.
  2. Instalar ACPID.
  3. Permitir la ejecución de sudo para el usuario jimezam.
  4. Bloquear la contraseña del usuario root.
  5. Instalación del JDK de Java.
  6. Instalación del ambiente de desarrollo C/C++.
  7. Depurar el software instalado.

Creación de la máquina virtual para la instalación del sistema operativo.

$ virt-install \
–connect qemu:///system \
-n
centos-5.4_x64-general \
-r 384 \
–os-type linux \
–os-variant generic26 \
–hvm \
–cdrom /u/isos/CentOS-5.4-x86_64-bin-DVD.iso \
–network bridge:br0 \
–disk path=/u/vms/
centos-5.4_x64-general.img,size=7 \
–vnc –noautoconsole \
–accelerate

Conexión remota a la KVM para el proceso de instalación y administración.

$ /usr/bin/virt-viewer -c qemu+ssh://ivy/system centos-5.4_x64-general

Actualización de paquetes.

# yum check-update

# yum update

Instalación de ACPID.

# yum install acpid

Activar el acceso a sudo para wheel.

# visudo

%wheel     ALL=(ALL)    ALL

# usermod -G wheel jimezam

Bloquear la contraseña del usuario root.

# passwd -l root

Instalación del JDK de Java.

# yum install java-1.6.0-openjdk java-1.6.0-openjdk-devel

Instalación del ambiente de desarrollo C/C++.

# yum install gcc gcc-c++ autoconf automake

Probando Atomic Authoring Tool en Linux Ubuntu 9.10

Introducción.

Atomic Authoring Tool es una aplicación de realidad aumentada desarrollada por Sológico Libre desarrollando Processing y la librería ARToolKit.  En su estado actual, versión 0.7, permite asociar el patrón de una imagen a un objeto tridimensional de forma que cuando el primero se muestre en la cámara se reemplace por el segundo.

Según lo mencionó José David, se encuentran próximos a liberar una nueva versión y leyendo en el FAQ del sitio del proyecto me entero que su plataforma objetivo son los OLPC.  Esta aplicación promete ser muy interesante en su área a medida que vaya siendo complementada.  Por ahora es una forma rápida y simple de experimentar con la realidad aumentada.

Su proceso de instalación fue un poco truculento, sin embargo después de superar un par de baches y siguiendo los pasos descritos a continuación no debe haber problemas para quienes quieran ensayarla.

Instalación.

Como precondición es necesario tener instalado al entorno de ejecución de aplicaciones Java o JRE.

Descargar e instalar las librerías necesarias (aqui se describen las utilizadas por la versión 0.7 de la aplicación).

$ wget http://www.sologicolibre.org/downloads/dependencias/904/libopenvrml4_0.14.3-3_i386.deb

$ wget http://www.sologicolibre.org/downloads/dependencias/904/libstdc++5_13a3.3.6-17ubuntu1_i386.deb

$ sudo dpkg -i libstdc++5_13a3.3.6-17ubuntu1_i386.deb libopenvrml4_0.14.3-3_i386.deb

$ sudo aptitude install freeglut3

Descargar la distribución mas reciente desde la siguiente ubicación.  En este caso se utilizará la versión 0.7 sin embargo se recomienda visitar el sitio para obtener la última distribución disponible.

http://www.sologicolibre.org/projects/atomic/es/index.php?page=Descargas

$ wget http://www.sologicolibre.org/downloads/ATOMICbeta07/linux/atomic07linuxen.zip

Descomprimir el archivo.

$ unzip atomic07linuxen.zip

Ejecutar la aplicación.

$ cd atomic07linux/

$ ./ATOMICbeta07linux_i

Solución a problemas.

Cuando instalé la aplicación encontré algunos problemas para ejecutarla en mi equipo, siempre arrojaba el siguiente mensaje.

Using config string from environment [v4l2src device=/dev/video0 ! video/x-raw-yuv,width=640,height=480,framerate=30/1 ! ffmpegcolorspace ! capsfilter caps=video/x-raw-rgb,bpp=24 ! identity name=artoolkit ! fakesink].
libARvideo: GStreamer 0.10.25

** ERROR **: libARvideo: failed to put GStreamer into PAUSE state!

aborting…
./atk.sh: line 3: 11616 Aborted                 ./simpleVRML

Aparentemente tiene que ver con la resolución que acepta la cámara.  Todo se solucionó después de que instalé Cheese, verifiqué cuales eran las resoluciones que efectivamente soportaba mi cámara (Editar > Preferencias) y actualicé con estos valores las variables width y height del script atk.sh en el directorio raíz de la aplicación.

Uso.

El sitio cuenta con un video explícito en el cual se explica su modo de operación, sin embargo a continuación mencionaré brevemente algunos elementos que es necesario tener en cuenta.

Al hacer clic con el ratón sobre cualquier lugar de la ventana se obtiene el menú desde el cual se podrán seleccionar las opciones que se mencionarán a continuación.

El primer paso consiste en la selección del marcador que va a ser reconocido por la aplicación.  Para hacer esto se debe elegir el ícono y seleccionar el archivo que contiene el patrón.  Para la selección del marcadores es necesario tener en cuenta que estos archivos (patt.calib, patt.hiro, patt.kanji, patt.sample1 y patt.sample2)  se encuentran bajo el directorio Data/ mientras que los archivos PDF ubicados bajo el directorio patterns/ corresponden a versiones de estos mismos marcadores pero para imprimir.

En el segundo paso se selecciona el objeto 3D que se mostrará cuando la aplicación detecte la aparición del marcador previamente configuarado.  Para hacer esto se debe elegir el ícono y seleccionar el archivo correspondiente de manera similar al paso anterior.  En este caso los archivos se ubican bajo el directorio /Wrl y deberán tener la extensión wrl.

El tercer paso es grabar la configuración elegida.  Para hacer esto se debe elegir el ícono .  Es muy importante recordar este paso porque de lo contrario se utilizará la configuración anterior.

El paso final consiste en ejecutar la aplicación con el marcador y el objeto 3D seleccionados haciendo clic sobre el ícono .

Screenshots.

Mi cabeza aumentada con una flor y una abeja

Mi cabeza aumentada con una flor y una abeja

Un muñeco de nieve sobre el marcador Hiro

Un muñeco de nieve sobre el marcador Hiro

Enlaces.

Víncular los Javadocs con Netbeans

Introducción.

El siguiente procedimiento permite relacionar la documentación oficinal de Java SE (Javadocs) con Netbeans permitiéndole al desarrollador tener una mejor información mas allá de la contextual que provee por defecto el IDE.

Configuración.

Seleccione el menú Tools > Java Platforms.

p1

Seleccione la pestaña Javadoc y presione el botón Add ZIP/Folder.

p2

Seleccione el archivo ZIP o el folder donde se encuentra la documentación de los Javadoc en el equipo.

p3

Presione el botón Close para terminar la configuración.

Uso.

En el editor de código fuente seleccione la clase que desea consultar en los Javadocs y presione ALT+F1 o haga clic derecho y elija la opción Show Javadoc del menú contextual.

p4

Netbeans abrirá la documentación correspondiente a la clase solicitada en el navegador web disponible.

p5

Enlaces.

Experimentando con WiiUseJ en Linux Ubuntu 9.04

Introducción.

WiiUseJ es otra de las prometedoras librerías para manipular la información proveniente del Wiimote desde java que el día de hoy estoy probando después de una primera experiencia con WiiRemoteJ.

Una diferencia importante de esta librería frente a otras probadas anteriormente es que no necesita del complemento de terceras librerías de soporte como Avetana o BlueCove ya que se basa en WiiUse el cual incluye librerías nativas (para Windows y Linux) lo que le permite acceder directamente a la pila de bluetooth del sistema operativo.

Esto es regularmente un punto a favor sin embargo puede llegar a ser una desventaja ya que las librerías al ser nativas deben, especialmente en Linux, corresponder con las versiones correctas de otras librerías a las se enlazan como sucede efectivamente en este momento cuando el release 0.12 fue compilado para libbluetooth 2.0 y esta librería fue actualizada  a la versión 3.0 en Ubuntu 8.10 y posteriores, obligando a que se deban actualizar o compilar nuevamente.

Implementación.

Es necesario importar los siguientes paquetes para la conexión con el wiimote y el manejo de los eventos generados por él.

 import wiiusej.*;
 import wiiusej.wiiusejevents.*;
 import wiiusej.wiiusejevents.utils.*;
 import wiiusej.wiiusejevents.physicalevents.*;
 import wiiusej.wiiusejevents.wiiuseapievents.*;

La clase encargada de manejar los eventos deberá implementar la interfaz WiimoteListener lo que le obligará a implementar los siguientes métodos.

 public void onButtonsEvent(WiimoteButtonsEvent arg0) {}
 public void onClassicControllerInsertedEvent(ClassicControllerInsertedEvent e) {}
 public void onClassicControllerRemovedEvent(ClassicControllerRemovedEvent e) {}
 public void onIrEvent(IREvent arg0) {}
 public void onMotionSensingEvent(MotionSensingEvent arg0) {}
 public void onExpansionEvent(ExpansionEvent arg0) {}
 public void onStatusEvent(StatusEvent arg0) {}
 public void onDisconnectionEvent(DisconnectionEvent arg0) {}
 public void onNunchukInsertedEvent(NunchukInsertedEvent arg0) {}
 public void onNunchukRemovedEvent(NunchukRemovedEvent arg0) {}
 public void onGuitarHeroInsertedEvent(GuitarHeroInsertedEvent e) {}
 public void onGuitarHeroRemovedEvent(GuitarHeroRemovedEvent e) {}

Para la demostración se hizo uso del método onButtonsEvent el cual permite a través del parámetro que recibe de tipo WiimoteButtonsEvent verificar que botón del control fue presionado mediante los métodos isButtonXXXPressed donde XXX puede ser los botones A, B, One, Two, Minus, Plus, Home, Up, Down, Left y Right.

Ejecución.

Se obtuvo la última versión disponible de WiiUseJ, en este caso era la 0.12.

$ wget http://wiiusej.googlecode.com/files/wiiusej%200.12b.zip

$ wget http://wiiusej.googlecode.com/files/WiiuseJ%200.12a%20Javadoc.zip

La segunda descarga es opcional y corresponde con la documentación del API de la librería.

Coo se mencionó en la introducción, las librerías nativas para Linux incluídas en la versión binaria 0.12 se encuentran obsoletas ya que fueron compiladas con libbluetooth 2.0 mientras que las distribuciones actuales ya incluyen la versión 3.0.  Para hacer esto se descarga el siguiente archivo, se descomprime y se reemplaza el archivo libwiiuse.so con la nueva versión.

$ wget http://wiiusej.googlecode.com/files/libwiiuse.zip

Asegúrese de copiar las librerías nativas incluídas con WiiUseJ al directorio raíz de la nueva aplicación.

  • Para Windows: wiiuse.dll y WiiUseJ.dll.
  • Para Linux: libwiiuse.so y libWiiuseJ.so.

De igual manera es necesario contar con el archivo wiiusej.jar en una ubicación conocida.

Para compilar el programa de demostración invocamos el siguiente comando.

$ javac -classpath wiiusej.jar:. WiiUseJTest.java

Para ejecutar el progrmaa de instalación utilizamos el siguiente comando.

$ java  -classpath ../wiiusej.jar:. -Djava.library.path=. WiiUseJTest

Enlaces.

Experimentando con WiiRemoteJ en Linux Ubuntu 9.04

Introducción.

Hace un tiempo (parte 1 y parte 2) hice algunas pruebas acerca de como utilizar el control del Wii (wiimote) desde el PC desarrollando aplicaciones con C# utilizando la librería WiimoteLib de Brian Peek.  Desafortunadamente ni esta librería ni ninguna otra de C# que pudiera encontrar son de plataforma cruzada y por lo tanto no se pueden utilizar desde Linux así que me vi obligado a cambiarme nuevamente a mi lenguaje preferido: Java.

Después de revisar las librerías disponibles obtuve tres candidatos: WiiRemoteJ, WiiUseJ, MoteJ y WiiMote-Simple.

A pesar de que la página de WiiRemoteJ parece haber desaparecido es una de las mas mencionadas y parece ser una de las mas estables.  Requiere de una pila Bluetooth como Avetana o Bluecove para ejecutarse sobre ella.

Implementación.

Básicamente el uso de la librería se basa en la manipulación de un objeto WiiRemote y en la implementación de la interfaz WiiRemoteListener encargada de manejar los eventos provenientes del Wiimote y de sus extensiones.

Las clases se encuentran almacenadas en los siguientes paquetes.

import wiiremotej.*;
import wiiremotej.event.*;

Al implementar la mencionada interfaz es necesario especificar la implementación de los siguientes métodos.

MétodoEvento
buttonInputReceivedSe presionó un botón del wiimote.
disconnectedSe desconectó el wiimote.
extensionConnectedSe conectó una extensión al wiimote.
extensionPartiallyInsertedLa extensión recién conectada quedó mal insertada.
extensionUnknownLa extensión recién conectada es desconocida.
extensionInputReceivedLa extensión envía datos al wiimote.
extensionDisconnectedLa extensión ha sido desconectada del wiimote.
accelerationInputReceivedEl wiimote ha generado información de aceleración.
IRInputReceivedEl wiimote ha generado información de su cámara infrarroja.
statusReportedHa sucedido un reporte de estado.
combinedInputReceivedSuceso de eventos combinados.

Evento de presión de botones.

 public void buttonInputReceived(WRButtonEvent evt)
 {
     // boolean     isAnyPressed(int buttonMask)    Returns true if any of the given buttons are pressed; otherwise false.
     // boolean     isOnlyPressed(int buttonMask)   Returns true if all of the given buttons are pressed and no others are; otherwise false.
     // boolean     isPressed(int buttonMask)       Returns true if all of the given buttons are pressed; otherwise false.
     // boolean     wasOnlyPressed(int buttonMask)  Returns true if all of the given buttons were pressed and no others are; otherwise false.
     // boolean     wasPressed(int buttonMask)      Returns true if all of the given buttons were pressed; otherwise false.
     // boolean     wasReleased(int buttonMask)     Returns true if one of the given buttons was released; otherwise false.
     if (evt.wasPressed(WRButtonEvent.TWO))
         this.log("2");
     if (evt.wasPressed(WRButtonEvent.ONE))
         this.log("1");
     if (evt.wasPressed(WRButtonEvent.B))
         this.log("B");
     if (evt.wasPressed(WRButtonEvent.A))
         this.log("A");
     if (evt.wasPressed(WRButtonEvent.MINUS))
         this.log("Minus");
     if (evt.wasPressed(WRButtonEvent.HOME))
         this.log("Home");
     if (evt.wasPressed(WRButtonEvent.LEFT))
         this.log("Left");
     if (evt.wasPressed(WRButtonEvent.RIGHT))
         this.log("Right");
     if (evt.wasPressed(WRButtonEvent.DOWN))
         this.log("Down");
     if (evt.wasPressed(WRButtonEvent.UP))
         this.log("Up");
     if (evt.wasPressed(WRButtonEvent.PLUS))
         this.log("Plus");
 }

Evento de desconexión del control.

 public void disconnected()
 {
     this.log("The remote controller was disconnected.");
     wiimote = null;
 }

Eventos de la extensión.

 public void extensionConnected(WiiRemoteExtension extension)
 {
     this.log("An extension has been connected! (" +
     extension.getCode() + "): " +
     this.getExtensionTypeName(extension));
     try
     {
         wiimote.setExtensionEnabled(true);
     }
     catch(Exception e)
     {
         this.log(e.getMessage());
     }
 }
 public void extensionPartiallyInserted()
 {
     this.log("An extension was partially inserted, push it harder next time");
 }
 public void extensionUnknown()
 {
     this.log("The extension is unknown, what are you putting into me ?");
 }
 public void extensionInputReceived(WRExtensionEvent evt)
 {
     // this.log("The extension is sending me some kind of data ... ");
 }
 public void extensionDisconnected(WiiRemoteExtension extension)
 {
     this.log("An extension has been disconnected! (" +
     extension.getCode() + "): " +
     this.getExtensionTypeName(extension));
 }

Evento de aceleración.

 public void accelerationInputReceived(WRAccelerationEvent evt)
 {
     // double     getPitch()         Returns the pitch of the remote, in radians from -PI to PI.
     // double     getRoll()          Returns the roll of the remote, in radians from 0 to 2PI.
     // double     getXAcceleration() Returns the X-Acceleration of the remote, in terms of G's.
     // double     getYAcceleration() Returns the Y-Acceleration of the remote, in terms of G's.
     // double     getZAcceleration() Returns the Z-Acceleration of the remote, in terms of G's.
     // boolean    isStill()          Returns true if the remote is not being moved; otherwise false.
 }

Evento de la cámara infrarroja.

 public void IRInputReceived(WRIREvent evt)
 {
     // IRLight[] getIRLights()       Returns the array of IR lights seen by the IR sensor.
     // int          getMode()        Returns the mode of the IR sensor.    
 }

Evento de reporte de estado.

 public void statusReported(WRStatusEvent evt)
 {
     // double      getBatteryLevel()       Returns the battery level of the remote.
     // boolean[]   getLEDStatus()          Returns the status of the LED lights.
     // boolean     getLEDStatus(int light) Returns the status of the specified light.
     // boolean     isContinuousEnabled()   Returns the status of continuous reporting.
     // boolean     isExtensionConnected()  Returns the status of the extension port.
     // boolean     isSpeakerEnabled()      Returns the status of the speaker.    
 }

Reporte de recepción combinada de eventos.

 public void combinedInputReceived(WRCombinedEvent evt)
 {
     // WRAccelerationEvent getAccelerationEvent()  Returns the acceleration event of this combined event.
     // WRButtonEvent       getButtonEvent()        Returns the button event of this combined event.
     // WRExtensionEvent    getExtensionEvent()     Returns the extension event of this combined event.
     // WRIREvent           getIREvent()            Returns the IR event of this combined event.
 }

Ejecución.

Para el desarrollo de esta aplicación de demostración se utilizó la librería de BlueCove, en este caso en la versión 2.10.  Es obligatorio obtener el paquete bluecove-*.jar mientras que bluecove-gpl-*.jar sólo es requerido bajo Linux.

$ wget http://bluecove.googlecode.com/files/bluecove-2.1.0.jar

$ wget http://bluecove.googlecode.com/files/bluecove-gpl-2.1.0.jar

Además se requiere de la librería WiiRemoteJ.jar, en este caso en la versión 1.6.

$ wget http://www.world-of-cha0s.hostrocket.com/WiiRemoteJ/WiiRemoteJ%20v1.6.zip.gz

$ cp WiiRemoteJ\ v1.6/WiiRemoteJ.jar .

Se compila el programa de demostración.

$ javac -classpath bluecove-2.1.0.jar:bluecove-gpl-2.1.0.jar:WiiRemoteJ.jar:. WiiRemoteJTest.java

Se ejecuta.

$ java  -classpath bluecove-2.1.0.jar:bluecove-gpl-2.1.0.jar:WiiRemoteJ.jar:. WiiRemoteJTest

Al iniciar la aplicación se debe presionar el botón que dice "Buscar Wiimote" y presionar los botones 1 y 2 del control para ponerlo en modo de descubrimiento.  Después de encontrado los eventos (botón, extensión y desconexión) generados en él deberán ser documentados en la ventana de la aplicación.

WiiRemoteJTest 0.1

WiiRemoteJTest 0.1

Enlaces.

http://www.world-of-cha0s.hostrocket.com/WiiRemoteJ/WiiRemoteJ%20v1.6.zip.gz
http://www.world-of-cha0s.hostrocket.com/WiiRemoteJ/WiiRemoteJ%20v1.6.zip.gz

Descubriendo dispositivos Bluetooth con Java y BlueCove

Introducción.

Después de la fallida búsqueda de una librería para acceder al protocolo Bluetooth desde Mono vuelvo entonces a Java buscando la opción mas portable posible.  Esta vez voy a probar BlueCove que soporta Mac OSX, WIDCOMM, BlueSolei, Windows nativo y Linux con BlueZ.

Instalación.

Descargar las últimas versiones disponibles desde la siguiente ubicación: http://sourceforge.net/project/showfiles.php?group_id=114020

  1. bluecove-*.jar: módulo principal, incluye el soporte para las pilas de Mac OS X, WIDCOMM, BlueSoleil and Microsoft Bluetooth.
  2. bluecove-gpl-*.jar: adiciona el soporte para la pila en Linux.

Descargar estos archivos JAR en una ubicación conocida.

Descubriendo dispositivos Bluetooth.

Para esto se parte de un objeto que implementa DiscoveryListener, él define que se debe hacer cuando cuando se encuentra un nuevo dispostivo y cuando se termina la búsqueda.

        /**
         * The DiscoveryListener interface allows an application to
         * receive device discovery and service discovery events.
         */
        DiscoveryListener listener = new DiscoveryListener()
        {
            /**
             * Called when a device is found during an inquiry.
             */
            public void deviceDiscovered(RemoteDevice btDevice, DeviceClass cod)
            {
                System.out.println("Device " + btDevice.getBluetoothAddress() + " found");
                devicesDiscovered.addElement(btDevice);
                try
                {
                    System.out.println("     name " + btDevice.getFriendlyName(false));
                }
                catch (IOException cantGetDeviceName) {}
            }
            /**
             * Called when an inquiry is completed.
             */
            public void inquiryCompleted(int discType)
            {
                System.out.println("Device Inquiry completed!");
                synchronized(inquiryCompletedEvent)
                {
                    inquiryCompletedEvent.notifyAll();
                }
            }
            // Not used in this example.
            public void serviceSearchCompleted(int transID, int respCode) {}
            public void servicesDiscovered(int transID, ServiceRecord[] servRecord) {}
        };

En este ejemplo, cuando se identifica a un nuevo dispositivo Bluetooth (ver deviceDiscovered) se obtiene su dirección, de ser posible su nombre y se agrega en la lista de dispositivos encontrados.

public static final Vector<RemoteDevice> devicesDiscovered = new Vector<RemoteDevice>();

Para ejecutar finalmente la búsqueda de dispositivos de acuerdo con el comportamiento definido anteriormente, se crea un objeto sobre el cual se sincronizarán las próximas acciones.

final Object inquiryCompletedEvent = new Object();
synchronized(inquiryCompletedEvent)
{
         // The search code ...
}

Con él se inicia la búsqueda de dispositivos accediendo al Agente Descubridor del Dispositivo Local.

boolean started = LocalDevice.getLocalDevice().getDiscoveryAgent().startInquiry(DiscoveryAgent.GIAC, listener);

Finalmente se verifica que la búsqueda haya comenzado exitosamente y se espera para garantizar su ejecución.

     if (started)
     {
          System.out.println("Starting Device Discovery process ...");
          /**
           * Wait for Discovery Process end
           */
          inquiryCompletedEvent.wait();
          System.out.println("There was " + devicesDiscovered.size() +  " device(s) found");
     }

Compilación & ejecución.

Para compilar y posteriormente ejecutar el programa de demostración es necesario garantizar que el JAR de bluecove, descargado inicialmente, se encuentre en el CLASSPATH.  También es necesario recordar que si la plataforma objetivo es Linux, es necesario incluír además el JAR de bluecove-gpl.

Para compilar se utiliza un comando preparado de la siguiente manera.

javac -cp ../lib/current/bluecove-2.1.0.jar:../lib/current/bluecove-gpl-2.1.0.jar RemoteDeviceDiscovery.java

Debe tenerse en cuenta que para la compilación se está suponiendo que los archivos JAR se encuentran en el directorio ../lib/current y que corresponden con la versión 2.1.0.   Además se está realizando en Linux, motivo por el cual el separador de directorios es : en lugar del ; utilizado por Windows.  Es necesario que adapte el comando según sus características específicas.

Para interpretar se utiliza un comando similar, preparado de la siguiente manera.

java -cp ../lib/current/bluecove-2.1.0.jar:../lib/current/bluecove-gpl-2.1.0.jar RemoteDeviceDiscovery

La salida de la aplicación.

La aplicación de demostración deberá imprimir por salida estándar la información de los dispositivos Bluetooth que se encuentren cerca durante el tiempo que dure la búsqueda.  Algo similar a lo siguiente.

BlueCove version 2.1.0 on bluez
Starting Device Discovery process …
Device 001ADE8BF510 found
name Jimezam Phone
Device 0017AE39DCB0 found
name Nintendo RVL-CNT-01

Device Inquiry completed!
There was 2 device(s) found
BlueCove stack shutdown completed

En la respuesta anterior se puede apreciar que la aplicación detectó exitosamente a mi teléfono celular y a un Wiimote que pasaba por allí.

Enlaces.

Instalación de Java 1.6 en OpenSuse 11.1

Esta mañana encontré que Aptana ya no estaba funcionando.  En sus logs aparecían excepciones extrañas.

eclipse.buildId=unknown
java.version=1.7.0
java.vendor=Sun Microsystems Inc.
BootLoader constants: OS=linux, ARCH=x86, WS=gtk, NL=en_US
Framework arguments:  Studio
Command-line arguments:  -os linux -ws gtk -arch x86 Studio

!ENTRY org.eclipse.equinox.common 4 0 2009-02-17 08:25:28.330
!MESSAGE FrameworkEvent.ERROR
!STACK 0
org.osgi.framework.BundleException: The bundle could not be resolved. Reason: Missing Constraint: Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3
at org.eclipse.osgi.framework.internal.core.BundleHost.startWorker(BundleHost.java:294)

Sin embargo algo llamó mi atención.  Al parecer el día de ayer se había actualizado el sistema operativo y había modificado el Java 1.6 que tenía anteriormente, instalándole una versión preliminar de Java 1.7 con Icedtea.

$ java -version

java version "1.7.0"
IcedTea Runtime Environment (build 1.7.0-b24)
IcedTea Server VM (build 1.7.0-b24, mixed mode)

Aparentemente esto no le gustaba a Aptana.  Tuve que regresar a Java 1.6 Sun.  Para hacer esto seguí los pasos a continuación.

  1. Iniciar YaST: System > System > YaST.
  2. De la sección [Software] elegir Software Repositories.
  3. Presionar el botón Add (+).
  4. Agregar el repositorio Java con el siguiente URL.
    http://download.opensuse.org/repositories/Java:/packages/openSUSE_11.1/
  5. Presionar el botón Ok para aceptar los cambios.
  6. De vuelta en YaST, de la sección [Software] elegir la opción Software Management.
  7. Buscar la cadena Java-1_6 del software Available.
  8. Seleccionar para instalar a los siguientes paquetes de java-1_6sun, sun-alsa, sun-devel, sun-jdbc, sun-plugin.
  9. Presione el botón Apply para ejecutar la instalación.

Finalmente la versión que tengo instalada es la 1.6.0_12 y Aptana ha vuelto a la vida.

$ java -version

java version "1.6.0_12"
Java(TM) SE Runtime Environment (build 1.6.0_12-b04)
Java HotSpot(TM) Server VM (build 11.2-b01, mixed mode)

Enlaces.

Generando diagramas entidad-relación con SchemaSpy

Introducción.

SchemaSpy screenshot - All relationships

SchemaSpy screenshot - All relationships

Dando vueltas el mes pasado por los lados de SourceForge encontré esta aplicación y no había tenido tiempo de probarla hasta el día de hoy.  Para mi satisfacción resultó ser muy interesante.  Es una aplicación desarrollada en Java que genera el diagrama Entidad-Relación de una base de datos y otras cositas, como sus desarrolladores la llaman, un navegador gráfico de esquemas de metadatos de una base de datos.  Puede acceder a cualquier motor de base de datos desde que se cuente con su correspondiente driver JDBC.

Requerimientos.

Para utilizar la aplicación se requiere lo siguiente.

  1. Contar con Java5 o superior.
  2. Descargar la última distribución de SchemSpy.
  3. Obtener el driver correspondiente a su base de datos.

Para realizar la conexión con una base de datos Microsoft SQL Server recomiendo utilizar el driver de jTDS ya que el proporcionado por Microsoft me generó problemas del siguiente estilo.

Driver version is x.x.xxx.xxx
com.microsoft.sqlserver.jdbc.SQLServerException: The "variant" data type is not supported.
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(Unknown Source)
        at com.microsoft.sqlserver.jdbc.TypeInfo.init(Unknown Source)
        at com.microsoft.sqlserver.jdbc.StreamColumns.processBytes(Unknown Source)
        at com.microsoft.sqlserver.jdbc.IOBuffer.processPackets(Unknown Source)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(Unknown Source)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.sendExecute(Unknown Source)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteQuery(Unknown Source)
        at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeQuery(Unknown Source)
        at one_con.main(one_con.java:26)

Instalación.

La instalación de la aplicación no excede el descomprimir los paquetes descargados, sin embargo su ubicación es importante.  Para esto utilicé la siguiente estructura de directorios.

  1. ~/Applications/SchemaSpy – directorio de la aplicación.
  2. ~/Applications/SchemaSpy/drivers – controladores de acceso a la base de datos.

En la carpeta [1] se ubica el JAR de la aplicación: schemaSpy_4.1.1.jar.

En la carpeta [2] se ubican los JAR de los drivers JDBC: mysql-connector-java-5.1.7-bin.jar para MySQL y jtds-1.2.2.jar para MSSQL.

Ejecución.

Para esto acostumbro a crear scripts del shell que ubico en ~/Applications, sin embargo lo importante es su contenido que puede invocarse directamente desde la línea de comando.

Para MySQL.

$ java -jar SchemaSpy/schemaSpy_4.1.1.jar -dp ~/Applications/SchemaSpy/drivers/mysql-connector-java-5.1.7-bin.jar -t mysql -host HOST -db DBNAME -u DBUSER -p DBPASS -o OUTDIR

Para MSSQL.

$ java -jar SchemaSpy/schemaSpy_4.1.1.jar -dp ~/Applications/SchemaSpy/drivers/jtds-1.2.2.jar -t mssql-jtds -host HOST -port PORT -db DBNAME -s DBSCHEMA -u DBUSER -p DBPASS -o OUTDIR

Por supuesto se deben reemplazar apropiadamente las siguientes variables.

  • HOST – servidor de base de datos.
  • PORT (requerido por MSSQL) – puerto de conexión al motor de base de datos.  El puerto por defecto de MSSQL es el 1433.
  • DBNAME – nombre de la base de datos.
  • DBSCHEMA (sólo con MSSQL) – esquema de la base de datos.  Utilizo dbo.
  • DBUSER – usuario de la base de datos.
  • DBPASS – contraseña del usuario $DBUSER.
  • OUTDIR – ubicación donde la aplicación generará los archivos resultantes.

Los comandos utilizan la sintaxis del shell de Linux, para utilizarlos desde Windows adapte las rutas según su conveniencia, recuerde modificar los slashes (/) por backslashes (\).

Nota acerca de la generación de gráficos.

Para que se generen correctamente los gráficos de los diagramas Entidad-Relación es necesario que se cuente previamente con la librería Graphviz.  Para instalar esta librería desde Ubuntu Linux sólo es necesario ejecutar el siguiente comando.

$ sudo apt-get install graphviz

Conclusiones.

Muy intersante esta aplicación, me gustó bastante.  Genera una buena documentación de la base de datos en formato HTML con varias secciones que se pueden navegar entre ellas.  Incluye varias perspectivas de la misma información que facilita su documentación.  Incluso siendo una presentación local, incluye JQuery para mejorar la usabilidad de los reportes.

Enlaces.

Instalación de Java, Netbeans y JavaFX en Ubuntu Linux

Instalación de Java.

$ sudo apt-get install sun-java6-bin sun-java6-fonts sun-java6-jdk sun-java6-plugin

$ java -version

java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Server VM (build 10.0-b23, mixed mode)

Instalación de Netbeans.

De la página de descargas de Netbeans obtener la versión para J2SE.

http://www.netbeans.org/downloads/zip.html

A continuación se describen los pasos necesarios para realizar la instalación local de Netbeans.

$ mkdir ~/Netbeans

$ cd ~/Netbeans

$ unzip ~/netbeans-*-javase.zip

$ mv netbeans/ javafx/

$ mkdir -p profiles/javafx

$ mkdir bin

$ vi bin/javafx

~/Netbeans/javafx/bin/netbeans –userdir ~/Netbeans/profiles/javafx

$ chmod +x bin/javafx

Instalación de los módulos para JavaFX.

$ mkdir tmp

$ cd tmp

Modificar la versión (6.5) a la que corresponda realmente con su distribución de Netbeans.

$ wget -r -l1 -np -nH –cut-dirs=9 -A.nbm http://updates.netbeans.org/netbeans/updates/6.5/uc/final/stable/modules/javafx

Ejecutar la instancia de Netbeans recién instalada.

$ ~/Netbeans/bin/javafx &

Agregar los módulos descargados a Netbeans.

Tools > Plugins.

Seleccionar la pestaña Downloaded.

Presionar el botón Add Plugins …

Agregue a todos los archivos del directorio ~/Netbeans/tmp/ exceptuando a los siguientes archivos

  1. org-netbeans-modules-javafx-sdk-mac.nbm.
  2. org-netbeans-modules-javafx-sdk-win.nbm.

Seleccione todos los agregados exceptuando los siguientes.

  1. Java FX 1.0.
  2. Java FX Source Debug.
  3. Java FX Weather Sample.

Presionar el botón Install para iniciar el proceso de instalación.

Instalación del JavaFX SDK.

$ unzip org-netbeans-modules-javafx-sdk-mac.nbm

$ cp -rf netbeans/* ~/Netbeans/javafx/javafx2/

$ chmod +x ~/Netbeans/javafx/javafx2/javafx-sdk1.0/bin/*

$ ~/Netbeans/javafx/javafx2/javafx-sdk1.0/bin/javafx -version

java version "1.6.0_07"
Java(TM) SE Runtime Environment (build 1.6.0_07-b06)
Java HotSpot(TM) Server VM (build 10.0-b23, mixed mode)

Limpieza de los residuos de la instalación.

$ cd ..

$ rm -rf tmp

Enlaces.