domingo, 31 de agosto de 2008

pgcedit: Eliminar todos los botones de un menu

Para eliminar un menu que contiene varios botones, es necesario utilizar PgcEdit de la siguiente manera:
  • Editar el menu y eliminar los botones que contiene uno por uno
  • Eliminar el pgc correspondiente al menu directamente
La segunda opcion es mas rapida, ya que no requiere eliminar los botones del menu uno por uno, sino que son eliminados todos a la vez.

Tenga en cuenta que un slideshow se compone de varios menues, que se unen unos con otros mediante botones. Para este caso existen botones seguir el siguiente slide o volver al anterior o al menu principal, que suele ser el de "Extras".

Edite el dvd para el cual desea eliminar el menu con PgcEdit. Busque en la lista de pgc el correspondiente al menu a eliminar:


Presione la combinacion de teclas Ctrl+k o habra el menu contextual para el pgc selecionado y elija la opcion "Kill PGC Playback". Aparecera entonces el siguiente mensaje:


Mediante esta advertencia, PgcEdit le informa que la navegabilidad del dvd puede resultar inconsistente. No es conveniente realizar este procedimiento si existe algun camino de navegacion que lleve a este menu. Solo debe hacerce cuando el menu quedo aislado y ya no es posible accederlo, por ejemplo, el menu de "Extras" y el menu principal o raiz que permite acceder a el.

Para continuar, presione el boton "OK" y aperecera la ventana "Menu buttons":


Puede observar los botones remarcados, asi como tambien el boton "Kill playback", que es el que debe presionar. Luego de hacerlo, aparecera el siguiente mensaje:


Luego de completar este procedimiento, el menu ya no puede ser accedido, pero aun se encuentra presente en el dvd, ocupando algo de espacio. Para limpiar el dvd, quitando el menu recien eliminado, debera emplear FixVTS o VobBlanker, como lo indica el mensaje.

Vinculos:
  • PgcEdit

jueves, 28 de agosto de 2008

java: serialVersionUID

Serializacion y el serialVersionUID

El siguiente parrafo corresponde al Javadoc para la interface Serializable:

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:

 ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassException's during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members.

Uso del serialVersionUID


El uso mas importante que se le da a este dato de una clase es cuando se serializan/deserializan clases en un sistema distrubuido, donde el intercambio de objetos entre componentes remotos del sistema es algo comun. Existen varios motivos por los cuales generar el sUID estaticamente es necesario, aunque depende del caso.

Generacion dinamica del serialVersionUID

Lo esperable es que el contenedor de la aplicacion genere este sUID en caso de no encontrarlo en la clase a serializar. La generacion de este identificador afecta la performance del sistema ya que la clase debe ser inspeccionada.
Otro problema asociado a la generacion dinamica del sUID es que si la clase serializada fue compilada empleando un compilador o version de Java diferente a la usada para la clase que se encuentra en entorno remoto, entonces ocurria un error de compatibilidad. Esto se debe a que el bytecode generado por compiladores diferentes o version de Java diferentes es distinto.

Generacion estatica del serialVersionUID

La generacion estatica del sUID consiste en agregar en el codigo de la clase a serializar un dato static y long identificado con el nombre serialVersionUID. El valor asociado a este dato debe ser consistente con la composicion de la clase. Actualmente, entornos de desarrollo como Eclipse incluyen la funcionalidad necesaria para generar dicho valor.

Cambios en clases serializables

Cambios en la composicion de una clase que implementa la interfaz Serializable pueden o no generar una excepcion del tipo java.io.InvalidClassException.
Los cambios que no generan incompatibilidad para una clase durante el proceso de serializacion/deserializacion son:
  • Agregar un dato (miembro/atributo)
  • Cambiar el modificador de un dato de static a no-static
  • Cambiar el modificador de un dato de transient a no-transient
Los cambios que generar errores de compatibilidad son:
  • Eliminar un dato (miembro/atributo)
  • Cambiar el tipo de un dato primitivo
  • Convertir un dato a static
  • Convertir un dato a transient
  • Modificar la gerarquia de clases
Suprimir alertas

Una forma de evitar el warning por parte del compilador o en un entorno de desarrollo como Eclipse, es utilizar la siguiente anotacion a nivel de clase:
@SuppressWarnings("serial")
de la siguiente manera:
@SuppressWarnings("serial")
public class SomeClass {
...
}
Vinculos:

miércoles, 27 de agosto de 2008

esb: Ejemplo con Apache Synapse

Ejemplo de la Guia Rapida de Apache Synapse

Descargar la distribucion de Apache Synapse desde el siguiente vinculo.

Acceda al directorio donde se encuentra el web service de ejemplo SimpleStockQuoteService, incluido en la distribucion. A continuacion se muestra el contenido del web service:


Para realizar la compilacion, debera ejecutar los siguientes comandos:
$> cd $SYNAPSE_HOME/samples/axis2Server/src/SimpleStockQuoteService
$> ant
La variable de entorno $SYNAPSE_HOME puede estar o no definida, lo importante es tener en cuenta que hace referencia a la ruta de instalacion de Apache Synapse.

El resultado de la compilacion se muestra en la siguiente figura:


Luego de obtener una compilacion exitosa, podra iniciar el servidor de Axis2 que contiene el web service SimpleStockQuoteService. Observe en la siguiente figura el contenido del servidor de Axis2 provisto junto con la distribucion de Apache Synapse:


Para iniciar el servidor de Axis2, ejecute los siguiente comandos:
$> cd $SYNAPSE_HOME/samples/axis2Server
$> axis2server.bat
En caso de tratarse de un sistema Linux, debera ejecutar el script axis2server.sh.
Podra observar en la consola el resultado de la ejecucion del servidor Axis2 como se muestra en la siguiente figura:


La salida generada por el inicio del servidor de Axis2 es la siguiente:
"Starting Sample Axis2 Server ..."
Using AXIS2_HOME: C:\synapse-1.2\samples\axis2Server\
Using JAVA_HOME: c:\dev\jdk1.5.0_11
--> Wrapper Started as Console
Launching a JVM...

2008-08-27 17:26:35,650 [-] [WrapperSimpleAppMain] INFO SampleAxis2ServerManager
[SimpleAxisServer] Starting
[SimpleAxisServer] Using the Axis2 Repository :
C:\synapse-1.2\samples\axis2Server\repository
[SimpleAxisServer] Using the Axis2 Configuration File :
C:\synapse-1.2\samples\axis2Server\repository\conf\axis2.xml
...
2008-08-27 17:26:37,009 [-] [WrapperSimpleAppMain]
WARN MailTransportListener Error configuring the Mail transport for Service
Cannot find parameter : transport.mail.Address for service : SimpleStockQuoteService
...
2008-08-27 17:26:37,009 [-] [WrapperSimpleAppMain]
INFO SampleAxis2ServerManager [SimpleAxisServer] Started
Tambien puede verificar mediante un navegador que el servidor Axis2 se encuentra funcionando y que el web service de ejemplo fue publicado con exito. Acceda a http://localhost:9000/soap para verificarlo:


Ahora es momento de iniciar Synapse. Observe en la siguiente figura el contenido del directorio bin de Apache Synapse, donde se encuentran varios scripts de ejecucion:


Para iniciar Synapse, ejecute los siguientes comandos:
$> cd $SYNAPSE_HOME/bin
$> synapse.bat -sample 0
En caso de tratarse de un sistema Linux, debera ejecutar el script synapse.sh.

Los parametros -sample y 0 le indican a Synapse que utilice el archivo de configuracion de ejemplo llamado synapse_sample_0.xml ubicado en $SYNAPSE_HOME/repository/conf/sample. Este archivo de configuracion especifica logging de los mensajes.

Podra observar en la consola el resultado de la ejecucion de synapse como se muestra en la siguiente figura:


La salida generada por el inicio de Apache Synapse es la siguiente:
"Starting Synapse/Java ..."
Using SYNAPSE_HOME: C:\synapse-1.2\bin\.
Using JAVA_HOME: c:\dev\jdk1.5.0_11
--> Wrapper Started as Console
Launching a JVM...
...
2008-08-27 17:46:42,091 [10.135.117.158-SGNARBA20392101]
[WrapperSimpleAppMain] INFO ServerManager Ready for processing
Con el web service y Synapse ejecutando, es momento de utilizar un cliente de web service para efectuar alguna consulta al web service y verificar el logging del mensaje. A continuacion puede observar el contenido del cliente de Axis2 provisto junto con la distribucion de Apache Synapse:


Para iniciar el cliente de web service, ejecute ant empleando los argumentos que definen el web service a invocar, el metodo y sus parametros:
$> ant stockquote -Daddurl=http://localhost:9000/soap/SimpleStockQuoteService
-Dtrpurl=http://localhost:8280 -Dmode=quote -Dsymbol=IBM
Podra observar en la consola donde se ejecuta el cliente la siguiente salida:


Luego, si consulta la consola donde Synapse se esta ejecutando, podra verificar que el mensaje enviado al web service se encuentra en pantalla. El logging a funcionado.


Vinculos:

domingo, 24 de agosto de 2008

maven: Creacion de un repositorio local

Introduccion

Para crear un repositorio local es necesario:
  • Definir una ubicacion donde almacenar las dependencias
  • Agregar a la ubicacion definida las dependencias requeridas por Maven y los proyectos que constuye
  • Alterar la configuracion de Maven para que busque dependencias en el repositorio local
De los tres pasos anteriores, el que presenta la mayor complejidad es el segundo, ya que justamente es Maven el encargado de manejar las dependencias.

El repositorio central de Maven es muy pesado y hacer una descarga completa del mismo no es una buena opcion en tanto y en cuanto no se disponga de un buen enlace y espacio en disco.
Lo que si es posible es hacer una seleccion simple de las dependencias que seran necesarias.

Creando el repositorio local

Para

Vinculos:

maven: Creacion de proyecto Java

Creacion del projecto

Para crear un proyecto que luego sera construido por Maven 2, su sistema debera disponer del entorno Java 2 y la herramienta Maven 2 instalados.

Veamos que ocurre al ejecutar el comando Maven en un directorio arbitrario:



Esto se debe a que Maven no encuentra un proyecto definido en la ubicacion indicada.

Maven emplea arquetipos (archetypes) para determinar cual es la estructura del proyecto a construir y asi poder construirlo. Los proyectos creados mediante Maven se basan en arquetipos provistos por Maven o por el usuario.

Uno de los arquetipos provistos por Maven permite crear proyectos Java genericos. Para hacerlo debera ejecutar el comando mvn pasando como parametro el arquetipo, en otros argumentos. Entonces escriba por consola de comandos lo siguiente:
$ mvn arquetype:create -DgroupId=[gid] -DartifactId=[aid]
Observe en la siguiente figura la respuesta de Maven:


Maven intenta obtener el plugin llamado arquetype pero no lo encuentra en el repositorio de dependencias central, ya que, aparentemente, no puede acceder al sitio remoto definido en la configuracion. Este es el mensaje de error completo:
[INFO] Searching repository for plugin with prefix: 'archetype'.
[INFO] org.apache.maven.plugins: checking for updates from central
[WARNING] repository metadata for: 'org.apache.maven.plugins' could not be retrieved
from repository: central due to an error: Error transferring file
...
[INFO] Repository 'central' will be blacklisted
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
[INFO] The plugin 'org.apache.maven.plugins:maven-archetype-plugin' does not exist
or no valid version could be found
...

Si no dispone de acceso a repositorio central, debera configurar un mirror que contenga las dependencias que su proyecto requiere.

Configuracion de repositorio



Vinculos:

maven: Instalacion de Maven 2

Verifique que el entorno Java 2 se encuentra instalado en su sistema. Para esto intente por linea de comandos obtener la version de Java:


Ahora debera descargar Maven 2 desde el sitio de Maven. Una vez completada la descarga, extraiga la distribucion en la ruta que le sea mas comoda, por ejemplo C:\. Podra observar entonces los siguiente archivos y directorios:


Configure la variable de entorno "Path" para poder ejecutar Maven desde cualquier ubicacion en el sistema de archivos, accediendo a la ventana "Variable de entorno" a traves de las propiedades del sistema en el Panel de Control:


Seleccione la variable "Path" en el marco "Variables del sistema" y presione el boton "Modificar". En la ventana "Modificar la variable del sistema", agrega al final del valor en el campo "Valor de variable" la ruta al directorio bin de Maven:


Luego presione el boton "Aceptar" en todas las ventanas que abrio para efectuar este cambio.
Verifique que Maven es accesible desde una ubicacion cualquiera del sistema de archivos. Para esto intente por linea de comandos ejecutar Maven:


Maven emplea un directorio oculto en el directorio del usuario que lo ejecuta. Este directorio tiene por nombre .m2 y puede encontrarlo en C:\Documents and Settings\Nombre de Usuario. En particular, Maven buscara en este directorio la configuracion de usuario, que debera ser especificada en el archivo settings.xml.
Si Maven no encuentra un repositorio de dependencias definido, entonces intentara acceder a ibiblio a traves de la red.

Vinculos:

martes, 12 de agosto de 2008

eclipse: Error al ejecutar test de JUnit

Al intentar ejecutar un test de JUnit en Eclipse, aparece el siguiente mensaje de error:


Al revisar el log de Eclipse en el workspace activo, que es el archivo WORKSPACE_PATH/.metadata/.log, encontre la siguiente excepcion:
!ENTRY org.eclipse.debug.core 4 120 2008-08-12 11:57:27.717
!MESSAGE Exception occurred executing command line.
!STACK 0
java.io.IOException: CreateProcess: C:\dev\jdk1.5.0_11\bin\javaw.exe -classpath
"C:\dev\... BLA BLA BLA CLASSPATH LARGISIMOOOO; C:\dev\BLA BLA BLA\ME"
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.(ProcessImpl.java:81)
at java.lang.ProcessImpl.start(ProcessImpl.java:30)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:451)
at java.lang.Runtime.exec(Runtime.java:591)
at org.eclipse.debug.core.DebugPlugin.exec(DebugPlugin.java:744)
at org.eclipse.jdt.launching.AbstractVMRunner.exec(AbstractVMRunner.java:70)
at org.eclipse.jdt.internal.launching.StandardVMRunner.run(StandardVMRunner.java:241)
at org.eclipse.jdt.internal.junit.launcher.JUnitBaseLaunchConfiguration.launch(JUnitBaseLaunchConfiguration.java:103)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:639)
at org.eclipse.debug.internal.core.LaunchConfiguration.launch(LaunchConfiguration.java:565)
at org.eclipse.debug.internal.ui.DebugUIPlugin.buildAndLaunch(DebugUIPlugin.java:754)
at org.eclipse.debug.internal.ui.DebugUIPlugin$6.run(DebugUIPlugin.java:944)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:58)
El problema radica en que el classpath utilizado para crear el proceso contiene demasiados caracteres.

Para solucionar este problema es necesario "depurar" el classpath utilizado para ejecutar el test de JUnit. Acceda al menu "Run -> Run..." para abrir la ventana de dialogo correspondiente a la ejecucion de clases. En la cuadro de la izquierda busque el item "JUnit" y seleccione de la lista el test de JUnit para el cual va a modificar el classpath de ejecucion:


Luego active la solapa "Classpath" y expanda el item "User entries". Elimine de la lista de referencias aquellas que no sean requeridas por el test de JUnit que va a ejecutar. Finalmente presione el boton "Run" y esta vez el test de JUnit debera correr bien.

viernes, 8 de agosto de 2008

oo: Patrones

Que es un Patron?

Es conocida la existencia de los llamados "Patrones" por la gran mayoria de los involucrados en el desarrollo de software. Quien paso por alguna facultad, tuvo la necesidad de consultar el famoso libro "Design Patterns: Elements of Reusable Object-Oriented Software" de "The Gang of Four" (GoF) o escucho sobre POSA.

La definicion mas conocida de Patron dice que es aquella solucion establecida para un problema recurrente en un cierto contexto.

En el primer volumen de POSA, el conocido libro "Pattern-Oriented Software Architecture: A System of Patterns", incluye una definicion mas completa, que surge a partir de la definicion del termino "Patron" dada por Christopher Alexander:
"Cada patron es una regla de tres partes, la cual expresa una relacion entre un cierto contexto, un problema y una solucion.
Como elemento del mundo, cada patron es una relacion entre un cierto contexto, un cierto sistema de fuerzas que ocurren repetidamente en ese contexto, y una cierta configuracion espacial que permite que esas fuerzas se resuelvan entre si.
Como elemento del lenguage, un patron es una instruccion, la cual muestra como esta configuracion espacial puede ser usada, una y otra vez, para resolver un sistema de fuerzas, donde sea que el contexto lo permite.
Un patron es, en resumen, al mismo tiempo una cosa, la cual ocurre en el mundo, y una regla nos dice como recrear esa cosa, y cuando debemos crearla. Es a la vez, un proceso y una cosa: ambas una descripcion de algo vivo, y una descripcion del proceso que lo genera.
"
Ahora la definicion de Patron segun POSA:
"Un patron de software describe un problema de diseno recurrente que ocurre en contexto de diseno especificos, y presenta un esquema generico bien establecido para solucionarlo. El esquema de solucion se especifica mediante la descripcion de sus componentes constitutivos, sus responsabilidades y relaciones, y las formas en las cuales colaboran."
Se parece mucho a lo que ya conocemos, verdad?

Como se define un Patron?

Un Patron queda definido por un esquema compuesto por tres partes:
  • Contexto: es aquella situacion que lleva a un problema
    Debe describir todas aquellas situaciones en las cuales ocurre el problema. Esto resulta imposible, por lo que se espera que se una descripcion tan generica como sea posible o la enumeracion de las situaciones en las cuales el problema ocurre.

  • Problema: es aquel problema recurrente que ocurre en el contexto dado
  • Solucion: es la forma establecida que resuelve el problema
Categorias

Existen diversos tipos de patrones. Es posible agruparlos mediante las siguientes categorias:
  • Patrones de arquitectura
    • Estructura
    • Sistemas Distribuidos
    • Sistemas Interactivos
    • Sistemas Adaptables
  • Patrones de diseno
    • de Creacion
    • de Estructura
    • de Comportamiento
Patrones de Arquitectura

Los patrones de arquitectura mas conocidos son los presentados en POSA 1:
  • Estructura
    • Layers
    • Pipes and Filters
    • Blackboard
  • Sistemas Distribuidos
    • Broker
  • Sistemas Interactivos
    • Model-View-Controller
    • Presentation-Abstraction-Control
  • Sistemas Adaptables
    • Microkernel
    • Reflection
Patrones de diseno

Los patrones de diseno mas importantes son los presentados por GoF (aunque existen otros muy utiles presentados por Java EE y Martin Fowler):
  • Creacion
  • Estructura
  • Comportamiento
Vinculos:

jueves, 7 de agosto de 2008

spring: Integracion de codigo legacy

Spring framework provee dos atributos para la definicion de un bean, que son particularmente interesantes cuando hace uso de codigo legacy. Estos atributos son:
  • factory-method
  • factory-bean
El atributo factory-method permite especificar un metodo static de la clase que es utilizado por Spring para crear una instancia de la misma.
En el siguiente ejemplo se puede observar con claridad:



El atributo class especifica la clase del bean, y es dicha clase la cual contiene el metodo static que retorna una instancia de la misma.
public class ExampleBean
{
private static ExampleBean bean;

static
{
bean = new ExampleBean();
}

private ExampleBean() {}

public static ExampleBean create()
{
return bean;
}
}
Vinculos: