Otro foro, pero con enfoque social media

Algo que siempre me ha causado gracia es la cantidad de foros para candidatos iguales pero con patrocinadores y marcas diferentes, siempre me pregunte si lo hacian para que los candidatos dejaran de hacer campaña y ensuciar las calles mientras se creaban prime times para los patrocinadores. Tal ves hubiera sido lo mejor . . .

Dejando eso a un lado, además de los foros ya tradicionales, ultimamente han salido foros especializados y que se tornan más interesantes, uno que me llamo la atención desde el inicio fue el foro organizado por estudiantes de la UFM donde la particularidad es que esta enfocado no solo a ser televisado, sino a ser transmitido por redes sociales y generar más participación al menos de la población con acceso a internet.

¿Como? pues en lugar de cobrar la entrada, invitarion a varios twitteros, blogueros, lideres de grupos en internet, facebookeros(, gpluseros asi se dice?)  para que ellos pudieran difundir esa información de primera mano por medio de sus redes sociales, si en teoría son lideres y los sigue mucha gente, automáticamente el mensaje llega más lejos (creo que entro como bloguero porque como twittero no dan ni un len por mi perfil y en identi.ca me va digamos que mejor).

El evento esta dividido en dos foros, uno para candidatos a alcalde en la ciudad capital y otro para presidentes.

El primero se llevara acabo el Martes, 19 de julio de 2011 de 6 a 8 pm, y la actividad pueden seguirla por los siguientes medios:


Ingenieria en Sistemas en la USAC (parte 3 – el fin)

Luego de dos años en los cuales la casa editorial del Abismo de Tux realizara una extensa investigación respecto a las cuatro preguntas más votadas via sms:

  • ¿donde esta mi queso?
  • ¿en donde quedan los laboratorios de sistemas?
  • ¿a quien se le ocurrió que abrir compiladores 2 en vacaciones era una buena idea?
  • ¿algun dia dara clases el ingeniero de gerenciales?

Estábamos listos para ser un blog del top 100 mundial, pero de pronto optamos por un post un poco más humilde, util y hecho para humanos (a diferencia de los de Java que no todos entienden) con el tema: ¿Que se necesita graduarse de Ingeniero en Sistemas en la USAC?.

El despues del cierre:

En este punto He-man solo es un canchito que usa tirantes para que no se le caiga el calzoncillo y el estudiante se siente como el verdadero «Master of the Universe», sin embargo empieza un proceso tan largo frente al cual la emisión del DPI es eficiente. El verdadero problema inicia con la primera piedra en el tortuoso camino que separa a un Ingeniero Infieri (pseudoingeniero con hueva de tesis) de un Ingeniero Colegiado, piedra que segun mis calculos tiene un volumen de 2cG (2 cagadas de Godzilla), el examen privado.

También puedo agregar que si uno no se siente preparado para el examen privado porque quiere experiencia (trabajando de gratis) o por mariquita (mariquita de cobarde no de gay para que no me tiren hordas de protestas con banderas de arcoiris) hay opción de graduarse con EPS.

Si el estudiante elige privado las fechas de examen privado se acaban más rapido que bolsa solidaria en colonia clasemediera wannabe y dependiendo la fecha el estudiante es recibido con un trollface y la frase «ya no hay fechas pero trata de venir temprano en enero» o «hay fechas para dentro de tres meses».  Esto motivo el primer y ultimo año sabatico de mi vida, del cual comento al final.

El privado en si no es un proceso muy complicado, el estudiante solo necesita una laptop, una amiga, traida, agarre, o una amiga de la traida que es un agarre para que le proporcione alimentos los tres dias que dura el examen (siempre esta la opción de salir a comprar comida), y el estudiante se enfrenta a un problema interesante: Resolver un caso de negocios por medio de software y responder 10 preguntas de las cuales 5 probablemente tengan muy poco o nada que ver con el problema original.

Al igual que todo en la universidad siempre se presentan las leyes de Murphy, en mi caso me examine la semana de huelga de dolores mientras Juan Chapin contaba chistes por el altavoz. El examen inicia un dia lunes y si todo sale bien el dia jueves el estudiante presenta su solución. Si por el contrario le toca una terna interesante, el estudiante estara un sabado despues de una declaratoria de huelga iniciando el examen a las 9 de la noche, donde el unico baño son los jardines del T3 y la unica compañia son 3 nerds donde uno de ellos le da play a su musica sinfonica y de orquesta para uno de esos momentos bizarros de la vida.

La tesis:

Aunque muchos argumentan que la tesis no tiene razón de ser, en cualquier país desarrollado para conseguir un grado académico no solo basta con clases, sino que se consigue a base de clases+una investigación. Si en teoría el estudiante es un potencial Ingeniero, el realizar una investigación de un tema que domina no es un problema mayor, ademas esto ayuda a la universidad a seguir en el ranking y poderlo usar como tema en fiestas familiares frente a los primos que emigraron porque no pasaron del examen de admisión y argumentan que la USAC era muy chafa para ellos.

Si por el contrario el estudiante no confía en sus capacidades o ya se quiere graduar siempre esta la opción de hacer una tesis con nivel de dificultad plaza sesamo que incluya las frases «nueva era»,  «lenguaje de programación» y termine con la frase «en el ambito Guatemalteco» (no es una regla general pero he visto muchos casos que lo sustentan).

En mi caso decidi divertirme un poco y el post respecto a mi tesis esta en otra sección de este blog,  al terminar la tesis senti cierto alivio porque ya habia terminado mi año sabatico, el problema es que hasta este punto el proceso apenas empieza. Chapu escribio una queja al respecto, yo lo dejo como una advertencia, el proceso va mas o menos así:

  • Estudiante: Eeeeh! termine mi tesis, mundo ahi te voy! (entusiasmo: 1000)
  • Murphychica de información: Viera que su tesis tiene este y este problema de formato por favor cámbielo (entusiasmo: 999)
  • Murphychica de información jornada vespertina): Viera que usted tenia bien su tesis, la de la mañana esta loca (entusiasmo: 700)
  • . . . repetir hasta el cansancio
  • Primera revisión por los verdaderos encargados de ligüistica (2 semanas a un mes despues): Lo que le indico la murphychica de la jornada matutina esta mal, lo que le indico la murphychica de la tarde tambien, en resumen perdio casi un més por gusto 😀 (entusiasmo: 0)

Hasta este punto si el estudiante tiene dinero se pregunta porque no se inscribio Universidad donde solo le hubieran dicho que pasara a caja y se examinara aparentando una ideologia religiosa o politica como una verdad absoluta para graduarse, no los culpo yo tambien lo pensé. Pero continuemos . . .

  • Primera lectura: Tienes errores en varias de tus paginas por favor cambialas (entusiasmo: -100)
  • Segunda lectura: Te señalamos ciertos errores pero solo es un rastreo tenias que buscar errores similares en toda la tesis (haberlo sabido antes) (entusiasmo: -infinito lambda)
  • . . .

De aqui en adelante a opinion personal muchos de los cambios son razonables y habiendo pasado solo por dos revisiones de este tipo puedo decir que deberiamos eliminar a las murphychicas y darles paletas para que las tesis salgan más rapido. Una vez llena la ficha de firmas donde hay que ser las sombra de los ingenieros y perseguirlos como si conocieran la ruta hacia el dorado. Estamos listos para el examen publico \o/.

Comentario personal

A partir del cierre cada quien agarra su rumbo, consiguen trabajos, regresan a sus pueblos, se quedan calvos, cambian los ideales, son opciones personales y muchas veces solo se vuelven a encontrar a los compañeros en grupos de tecnología, en el trabajo y al menos en mi caso el primer tema de conversación ha sido el universal  «¿que purrun andas haciendo?» .

En mi caso inicie sin querer un año sabatico, al cual lo declare asi al quinto mes, trate de retomar un poco mi vida, trabaje para despilfarrar el dinero de 3 meses para comprar una PC en 20 minutos, me di un par de gustos en comidas que no me habia podido dar, seguí comprando juegos que durante toda mi vida me han hecho enviciarme, comprobé que los trabajos freelance son tan variables y se pueden ganar $1000 en una semana y pasar otras 4 sin ganar ni un centavo, viaje por Guatemala en plan garra, conocí muchos lugares gracias al Software Libre, por fin compartí tiempo con mi viejo y pudimos recorrer el area rural como en los viejos tiempos. Hasta el momento la época más feliz de mi vida.

En estos momentos ando rendido al sistema, pero para no perder el estilo, trabajo con Software Libre, puedo llegar en Jeans a trabajar y se sintió bien ganarle el puesto a personas graduadas y de otras casas de estudios aunque mi intención era ir a pasear y ver que sucedía en las entrevistas de trabajo (gracias a Dios por eso), sentí por fin que todo esto valio la pena. En resumen en la USAC nadie se preocupa por el estudiante más que el mismo, todo funciona como un anaquel abierto, el conocimiento esta ahí y cada quien decide que parte toma y en que se involucra.

Solo me queda decir gracias por todo USAC, solo se necesitaron huevos y una computadora.

Configuración JDBC Progress v9+Glassfish sobre Windows

Variables de entorno :

-DLC: Directorio de instalación de progress

-JDK_HOME: Directorio de instalación de Java

-PATH: PATH=%PATH%;%DLC%\bin;%JDK_HOME%\bin

-GLASSFISH_HOME=Directorio de instalación de glassfish

Bibliotecas nativas:

Luego de instalar progress y configurar las variables de entorno hay que preparar el sistema operativo para efectuar una conexión via JDBC, a diferencia de otros drivers de JDBC autonomos, el driver de Progress se auxilia de bibliotecas nativas del sistema, las bibliotecas se encuentran en el directorio %DLC%\bin y son:

JdbcProgress.dll

procli92.dll

Estos archivos se deben copiar a la maquina CLIENTE dentro del directorio Windows\System32 para que esten a disposición de la JVM. Son dependientes de arquitectura y de sistema operativo. Tambien hay disponibles bibliotecas como archivos .so para *nix pero lastimosamente el servidor de prueba estaba en Windows.

Además para configurar un origen de datos en Glassfish estos mismos archivos .dll se tienen que copiar en %GLASSFISH_HOME%\lib

Configuración del pool JDBC:

Los drivers JDBC de progress se encuentran dentro de %DLC%\java, solo es necesario copiar los archivos jdbc.jar y progress.jar, al classpath de nuestro DOMINIO en glassfish, por ejemplo para dominio 1 seria:

%GLASSFISH_HOME%\domains\domain 1\lib

Estos drivers no funcionaran si no estan configuradas las .dll de manera adecuada y solo lanzaran una excepcion.

Configuración del pool de conexiones:

El estandar JDBC 2.0 describe dos tipos de drivers, drivers simples e implementaciones de DataSource para creación de pool de conexiones, la clase correcta para el pool de conexiones con progress es:

com.progress.sql.jdbcx.datasource.JdbcProgressDataSource

Esta clase implemente la interfaz javax.sql.ConnectionPoolDataSource, despues de crear un pool sin una plantilla especifica (sin seleccionar ningun DBMS en el asistente), se deben establecer las siguientes “Propiedades Adicionales” en el pool de conexiones:

User: Usuario que inicia el servicio en windows

Password: Password del usuario

DatabaseName: Nombre de la base de datos

ServerName: Dirección del servidor

PortNumber: Puerto de la base de datos

URL: jdbc:jdbcprogress:T:<servername>:<portnumber>:<databasename>

Ejecución remota desde Android con remote launcher y demonios Java en Linux

Hace tiempo tuve un control físico para xbmc y queria replicar eso mediante Android para lo cual encontre un cliente. El inconveniente que tenia con xbmc era el levantarme de mi cama para ejecutar el control en Android y asi fue como encontre Remote Launcher.

Remote Launcher es una especie de control para ordenar la ejecución de aplicaciones desde el smartphone, el cual solo necesita una contraparte en el servidor, tiene dos modos de ejecución un modo de ejecución gráfico y otro desde la terminal, la parte del servidor esta escrita en java.

Luego de un par de pruebas y de seguir los pasos de la configuración que hay en la pagina, ya podia ejecutar xbmc desde mi teléfono y podía controlarlo con el control de xbmc, sin embargo el problema ahora era ejecutar remote launcher en mi pc -_-, aunque mi primera opción fue agregarlo como programa al iniciar Gnome, perdia el poder de controlar la pc con pasarme a Fluxbox (mi otro escritorio) y mi solución final fue integrar Remote Launcher a los servicios del sistema en Gentoo.

Preeliminares

Aunque cada distribución tiene su propio sistema de arranque, la mayoria al final ejecutan una utilidad del sistema llamada start-stop-daemon (Debian y Gentoo por ejemplo) que como su nombre lo indica se encarga de gestionar la ejecución del programa en cuestión como un demonio y no como una aplicación normal. En mi caso la configuración que funciono fue la siguiente:

  • Configurar un nuevo servicio para ejecutar el .jar de Remote Launcher  Server como si se tratara de un servicio de sistema, en mi caso un nuevo servicio para openrc en Funtoo.
  • Agregar un lanzador para xbmc con la salvedad que la aplicación tiene que abrirse en la pantalla principal 0 de mi xserver (la pantalla por defecto para la mayoría de los usuarios).

Convertir un .jar en un servicio del sistema

Al utilizar start-stop-daemon su funcionamiento por defecto es verificar si el proceso ya se encuentra en la tabla de procesos en ejecución a nivel de sistema (para cualquier usuario), si utilizaramos este metodo con java start-stop-daemon verificaria si esta en ejecución /usr/bin/java y automaticamente detendria todas las instancias de maquina virtual que esten en ejecución asi que descarte este metodo.

El instalador de remote launcher, genera un script en /usr/bin/remote-launcher-server con el comando largo de java para la ejecución del programa, script que NO debe ser utilizado para crear el servicio porque al ejecutar el script el sistema genera un pid por la ejecución del script y otro pid para la ejecución de la maquina virtual de java, otra opción descartada.

La solución final entonces es basarme en el script para ejecutar el jar de remote launcher y convertirlo a un comando de start-stop-daemon:

start-stop-daemon –start –background –user tuxtor –make-pidfile –pidfile /var/run/remote-launcher-server/remote-launcher-server.pid  –exec /usr/bin/java — -jar «/usr/share/remotelauncherserver/Remote Launcher.jar» /usr/share/remotelauncherserver/ -d

Las opciones que utilice las explico a continuación:

–start – no necesita explicación o si?

–background – envía el proceso a ejecutarse a background, sin esta opcion mi script de inicio esperaria una señal del ejecutable para decir que esta listo para aceptar conexiones, señal que nunca existiria porque remote launcher no esta programado para eso

–user tuxtor – le indico que ejecute el comando con mi usuario, esto para mantener aislado el demonio de remote launcher y para que remote launcher lance los programas con mi usuario regular

— make-pidfile – workarround para que start-stop-daemon genere un archivo con el numero de pid del proceso de remote launcher

— pidfile – ruta en donde se generara el archivo con el numero de pid, no es necesario que el archivo exista PERO la ruta completa si debe de existir

— exec /usr/bin/java – el comando a ejecutar sera la maquina virtual de java

— «-jar . . .» las opciones de ejecución de remote launcher, le indico cual es el archivo .jar a ejecutar, el classpath y por ultimo la opción -d que hace que remote launcher inicie solo en linea de comandos.

Por ultimo para hacer que el servicio se detenga volvemos a utilizar start-stop-daemon, para lo cual usamos la opcion stop y le indicamos en donde se encuentra el archivo con el pid del proceso.

start-stop-daemon –stop –pidfile /var/run/remote-launcher-server/remote-launcher-server.pid

Especifico para Gentoo

En Gentoo el script completo a ubicar en init.d seria el siguiente, ademas de ejecutar el comando anterior me aseguro que la carpeta de destino del pidfile no genere problema. Como opción adicional hice parametrizable la dirección de destino del pidfile, la cual agrego como una variable en un nuevo archivo dentro de /etc/conf.d/ en mi caso se llama remote-launcher-server.

/etc/init.d/remote-launch-server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/sbin/runscript
# Android remote launcher server init script
# Distributed under the terms of the GNU General Public License v3
 
depend() {
need net
}
 
start() {
ebegin "Starting remote-launcher-server"
 
if [ ! -e /var/run/remote-launcher-server ] ; then
mkdir -p /var/run/remote-launcher-server
chown tuxtor:users /var/run/remote-launcher-server
fi
 
start-stop-daemon --start --background --user tuxtor --make-pidfile --pidfile ${REMOTE_LAUNCHER_SERVER_PIDFILE} \
--exec /usr/bin/java -- -jar "/usr/share/remotelauncherserver/Remote Launcher.jar" /usr/share/remotelauncherserver/ -d
eend $?
}
 
stop() {
ebegin "Stopping remote-launcher-server"
start-stop-daemon --stop --pidfile "${REMOTE_LAUNCHER_SERVER_PIDFILE}"
eend $?
}

/etc/conf.d/remote-launch-server

REMOTE_LAUNCHER_SERVER_PIDFILE=»/var/run/remote-launcher-server/remote-launcher-server.pid»

Agregar un lanzador para xbmc (o cualquier otro programa con GUI) con remote launcher server ejecutandose como servicio

Remote launcher server utiliza el archivo .remotelauncherserver dentro de la carpeta /home del usuario, en mi caso tuxtor. Aunque remote launcher server ya se encuentra ejecutandose bajo mis credenciales el siguiente inconveniente a resolver es que no se puede ejecutar un programa desde una terminal no grafica, hay que forzar la ejecución en la pantalla principal del X Server, esto se hace mediante la variable de entorno DISPLAY.

Por ejemplo un lanzador tradicional en el archivo de configuración de remote launcher server seria asi:

Xbmc
Xbox Media Center (Yes Xbox)
/usr/bin/xbmc

Asi que como paso adicional hay que generar un script con la variable de entorno DISPLAY apuntando a la pantalla principal, más o menos como el siguiente:

1
2
3
#!/bin/bash
export DISPLAY=:0.0
/usr/bin/xbmc

Lo ubicamos donde nos conventa (en mi caso /opt/xbmc_disp0) lo hacemos ejecutable (chmod +x /opt/xbmc_disp0) y reescribimos el lanzador.

Xbmc
Xbox Media Center (Yes Xbox)
/opt/xbmc_disp0

Y al conectarnos desde android deberiamos ver algo como esto:

 

Autenticación nativa de Trac y Svn en hosting compartido de Dreamhost

Dreamhost y sus famosos one-click instal son el reemplazo perfecto a los scripts fantastico que conocemos en todos los proveedores de hosting. Hace un año Trac no estaba disponible entre sus one-click install y después de hacer un par de hacks y workarrounds logre instalar mi propio sitio con Trac en mi cuenta de Dreamhost, sin embargo es un proceso un tanto doloroso a nivel de dificultad.

Recientemente Dreamhost añadio la posibilidad de instalar Trac con la salvedad que no podemos usar la autenticación de Trac como tal y en su lugar solo podemos vincularlo al archivo .passwd de nuestro repositorio y solo podremos restringir el acceso al sitio y no definir los niveles de autenticación de trac.

Si no saben de que hablo arriba pueden leer otros post 😀

Continue reading →

Netbeans 7 y Keyring de GNOME 3

Netbeans tiene una característica bastante útil para almacenar nuestras contraseñas de muchos servicios como:

  • Team server
  • Issue tracking
  • Respositorios de codigo
  • Conexiones a bases de datos

Para los que utilizamos Netbeans en sistemas GNU/Linux el almacenamiento de estas contraseñas por defecto se hace via keyring del sistema (kwallet para los que usan kde y gnome-keyring para los que usamos gnome).

Sin embargo con la nueva versión de Gnome, al intentar acceder a cualquier servicio con contraseña via keyring se obtiene el siguiente error de dbus:

arguments to dbus_message_iter_append_basic() were incorrect, assertion «*bool_p == 0 || *bool_p == 1»

Aunque aun no tengo una explicación clara para este error, solo estoy seguro que en Gnome 2 todo funcionaba sin inconvenientes :D. Mi solución temporal es deshabilitarlo y utilizar el keyring básico incluido en Netbeans.

Para deshabilitar la integración con el keyring del sistema podemos agregar la opción -J-Dnetbeans.keyring.no.native=true al parametro netbeans_default_options, si utilizamos el instalador binario de netbeans este archivo se encontrara en ~/netbeans-7.0/etc.

Por ejemplo en mi sistema el valor final de la variable es el siguiente:

netbeans_default_options=»-J-Dcom.sun.aas.installRoot=\»/home/tuxtor/glassfish-v2.1\» -J-client -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=384m -J-Dapple.laf.useScreenMenuBar=true -J-Dapple.awt.graphics.UseQuartz=true -J-Dsun.java2d.noddraw=true -J-Dnetbeans.keyring.no.native=true»

Una vez establecida esta opción obtendremos el siguiente administrador de contraseñas. Espero que la proxima versión de netbeans ya sea totalmente compatible con Gnome 3 :D.

Gmaps4jsf integrado en icefaces y con carga dinamica de Google API key

Recientemente tuve que integrar todas las tecnologías descritas en el titulo y aunque icefaces dispone de su propio control para Google maps, es en cierta forma limitado. La gracia de Java es que no hay o no debería haber vendor lock-in  y pude utilizar Gmaps4jsf sin problemas. Cada proyecto tiene una documentación bastante descriptiva para su uso asi que me centrare en definir algunas particularidades del caso.

Integración con paginas jsp bajo xml estricto

Para los que aun no lo sepan al escribir paginas jsp tenemos dos estilos de creación:

  • JSP Tradicionales: Ideales para scriptlets y lógica escrita en la pagina .jsp (php style le dicen algunos)
  • JSP XHTML: Estas solo permiten xml estricto, se utilizan en conjunto con backing beans y restringen al programador para que no escriba lógica en el archivo .jsp

La documentación de gmaps4jsf indica que para integrar el control a nuestra aplicación jsf basta con agregar el siguiente taglib:

<%@ taglib uri="http://code.google.com/p/gmaps4jsf/" prefix="m" %>

Sin embargo esto no se puede utilizar con paginas jsp escritas en xml estricto. ¿Solución?, traducir el tag a la siguiente estructura equivalente, esto es útil cuando nuestro generador de paginas (como el difunto plugin visual de icefaces en netbeans) genera paginas en xml estricto

<jsp:root version="2.1"
...
xmlns:m="http://code.google.com/p/gmaps4jsf/"
>

Integración con icefaces

Para que el control se integre bien en el ciclo de vida de los componentes de icefaces hay que utilizar el siguiente atributo propio de Gmaps4jsf  «renderOnWindowLoad», si no se utiliza este atributo el mapa no sera renderizado adecuadamente.

Ejemplo:

<m:map width="1000px" height="740px" zoom="16" type="G_HYBRID_MAP " renderOnWindowLoad="false">
....

Carga dinamica de la clave de Google api key

Aunque la documentación del control de icefaces indica que se debe establecer la clave en una sección del archivo web.xml y la documentacion de Gmaps4jsf indica que debe hacerse incluyendo el tag de script al inicio de la pagina podemos hacer algo más interesante, establecer la clave desde un backing bean. Para esto icefaces cuenta un mecanismo para acceder al contexto de javascript de nuestra pagina actual denominado JavascriptContext (logico no?).

Asi pues para cargar de manera dinamica la clave sin añadir ningun tag a nuestra pagina jsf se utilizaria un codigo similar al siguiente:

String googleAPIKey="seqwerui1298qrioyiuywopiuwrqepowqclaveDEEjempl0";
 
JavascriptContext.includeLib("http://maps.google.com/maps?file=api&amp;v=2&amp;key="+googleAPIKey, FacesContext.getCurrentInstance());

Con esto podemos cargar la clave sin necesidad de escribirla directamente en la pagina jsp

Y por ultimo TADA!! tenemos nuestro mapa (convenientemente ubicado en alguna región no determinada):

 

 

¿Los servidores DNS que uso son decentes?

Hace casi 6 meses iniciamos la comunidad java Guatemala

Hace casi 3 meses alguien de la comunidad amablemente adquirio el dominio guate-jug.org.

Hace casi 2 meses este dominio se apunto hacia un nuevo servidor el cual es un procedimiento de rutina y regularmente no requiere más de 72 horas para que todos los dns tengan la nueva ip lista y fresca.

Hace un mes despues de detectar un problema con la actualizacion de DNS en un ISP con servidores DNS mediocres (telgua) hicimos de todo hasta cambiar de registrador de dominio.

Y el dia de hoy las cosas estan asi:

Google:

$ nslookup guate-jug.org 8.8.8.8
Server:        8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
Name:    guate-jug.org
Address: 173.236.29.66

$ nslookup guate-jug.org 8.8.4.4
Server:        8.8.4.4
Address:    8.8.4.4#53

Non-authoritative answer:
Name:    guate-jug.org
Address: 173.236.29.66

Opendns:

$ nslookup guate-jug.org 208.67.222.222
Server:        208.67.222.222
Address:    208.67.222.222#53

Non-authoritative answer:
Name:    guate-jug.org
Address: 173.236.29.66

$ nslookup guate-jug.org 208.67.220.220
Server:        208.67.220.220
Address:    208.67.220.220#53

Non-authoritative answer:
Name:    guate-jug.org
Address: 173.236.29.66

Pero si vamos por los locales:

Tigo:

$ nslookup guate-jug.org 200.49.161.131
Server:        200.49.161.131
Address:    200.49.161.131#53

Non-authoritative answer:
Name:    guate-jug.org
Address: 67.23.226.35

Telgua:

$ nslookup guate-jug.org ns.telgua.com.gt
Server:        ns.telgua.com.gt
Address:    216.230.128.33#53

** server can’t find guate-jug.org: REFUSED

$ nslookup guate-jug.org ns.comtech.net.gt
Server:        ns.comtech.net.gt
Address:    216.230.128.32#53

** server can’t find guate-jug.org: REFUSED

Y si puede parecer engreido que me queje tanto, pero despues de que todos dicen que es porque configure mal wordpress ¬¬, mientras yo con el uso de google dns he podido ver la pagina siempre. Tengo el derecho de quejarme que los tecnicos certificados CCNA/CCNP/CCNAlgo se dignen a optimizar el funcionamiento de sus servidores DNS o se rindan y preconfiguren en sus routers servidores DNS de verdad. Si hacen pruebas en los ISP locales a veces si resuelve la direccion . . . solo que a la IP equivocada.

Se aceptan donaciones para un guate-jug.net :/

Validando propiedades nulas de un objeto en Java

Todo programador java sabe que los tipos primitivos tienen un valor por defecto y los objetos por defecto tienen valor nulo (si no lo sabias ponte a estudiar).

A veces es necesario validar estos objetos para realizar operaciones sobre ellos y asegurarnos que nuestro usuario no reciba un magico nullPointerException. El metodo más rapido seria validar una a una las propiedades o la opción que me gusta, preguntarle a nuestro objeto que propiedades tiene y luego utilizar los metodos propios del objeto con Java Reflection.

Java Reflection es un API poco conocida por programadores principiantes, sin embargo es la unica salida en programas que requieren la habilidad de examinar un objeto en tiempo de ejecución. Si no han leido acerca de esto no se preocupen el Java Tutorial lo califica como avanzado.

Todos los detalles acerca de reflection se encuentra en el Java Tutorial sin embargo la clase que utilizo para validar nulos es la siguiente:

public class NullValidator {
 
    public static Object validarCampos(Object pObjeto) {
        Object objeto = pObjeto;
        Method metodos[] = pObjeto.getClass().getMethods();
        for (int i = 0; i < metodos.length; i++) {
            Method metodo = metodos[i];
            //Si es un metodo get o is lo utilizo con su equivalente set
            if ((metodo.getName().substring(0, 3).equalsIgnoreCase("get") || metodo.getName().substring(0, 2).equalsIgnoreCase("is")) && !metodo.getName().equals("getClass")) {
                String methodNameSet = "";
                if(metodo.getName().substring(0, 3).equalsIgnoreCase("get")){
                    methodNameSet = metodo.getName().replaceFirst("get", "set");
                }else{
                    methodNameSet = methodNameSet.replaceFirst("is", "set");
                }
                try {
                    Method metodoSet = pObjeto.getClass().getMethod(methodNameSet, metodo.getReturnType());
                    if (metodoSet != null) {
                        //Datos numericos
                        //Si es byte
                        if (metodo.getReturnType().equals(java.lang.Byte.class)) {
                            Byte valor = (Byte)metodo.invoke(pObjeto, new Object[0]);
                            if(valor==null){
                                metodoSet.invoke(pObjeto, 0);
                            }
                        }
                        //Si es bigDecimal
                        if (metodo.getReturnType().equals(java.math.BigDecimal.class)) {
                            BigDecimal valor = (BigDecimal)metodo.invoke(pObjeto, new Object[0]);
                            if(valor==null){
                                metodoSet.invoke(pObjeto, new BigDecimal(0));
                            }
                        }
                        // Si es Double
                        if (metodo.getReturnType().equals(java.lang.Double.class)) {
                            Double valor = (Double)metodo.invoke(pObjeto, new Object[0]);
                            if(valor==null){
                                metodoSet.invoke(pObjeto, new Double(0));
                            }
                        }
                        //Si es un string
                        if (metodo.getReturnType().equals(java.lang.String.class)) {
                            String valor = (String)metodo.invoke(pObjeto, new Object[0]);
                            if(valor==null){
                                metodoSet.invoke(pObjeto, "");
                            }
                        }
                        //Si es una lista
                        if (metodo.getReturnType().equals(java.util.List.class)) {
                            List objetosList = (List)metodo.invoke(pObjeto, new Object[0]);
                            for(Object objetoFromList:objetosList){
                                NullValidator.validarCampos(objetoFromList);
                            }
                        }
                        //Si es date
                        if (metodo.getReturnType().equals(java.util.Date.class)) {
                            Date valor = (Date)metodo.invoke(pObjeto, new Object[0]);
                            if(valor==null){
                                metodoSet.invoke(pObjeto, new Date());
                            }
                        }
                        //Si es primitivo
                        if (metodo.getReturnType().isPrimitive()) {
                            //los primitivos no permiten null
                        }
                    }
                } catch (Exception e) {
                }
            }
        }
        return objeto;
    }
 
}

¿Como funciona?

  1. Primero capturo los metodos que tiene el objeto
  2. Luego si es un metodo get procedo a utilizar su equivalente is o set
  3. Por ultimo compruebo el tipo de dato y si es nulo, si es nulo procedo a darle un valor inicial

Luego basta con invocar el metodo validarCampos (porque además es estatico) y listo nuestro objeto sera validado contra valores nulos.

 

Cyanogenmod 7 y Google Apps para paises con market restringido

El día de hoy se publicaron los primeros release candidate de mi ROM preferido para smartphones Android, esta vez con un cambio de versión mayor acorde al cambio de ROM base. Los nuevos ROMS del proyecto cyanogenmod de ahora en adelante estarán basados en Android Gingerbread.

Dejando a un lado los bombos y platillos, siguiendo mi tradición gentoosera bleeding edge procedi a instalar un release candidate :P.

Los pasos detallados para una instalación nueva se encuentran en la wiki del proyecto. Y para los usuarios actuales de cyanogenmod ya esta disponible la actualizacion desde el ROM manager.

En mi caso ya era usuario de cyanogenmod la instalación fue transparente, solo actualice ClockworkMod, luego el correspondiente backup y despues de descargar la imagen del ROM todo fue bien a excepcion de un inconveniente: Instalación aplicaciones de google

El problema es que aunque las aplicaciones de Google sean descargadas mediante el instalador del Rom Manager, necesitan ser instaladas via Android Market pero solo son visibles para usuarios de tiendas de aplicaciónes «premium» (con aplicaciones de pago)

Solucion 1 (Sin ejecutar el Android Market):

Si despues de instalar aun no han ejecutado el android market deben cargar por medio de sideload la aplicacion Market Enabler y obtener un perfil de cualquier pais con un Android Market «premium».

Por ejemplo si busco gmail con el Market normal de Guatemala obtengo:

Y despues de la ejecucion del Market Enabler:

Solucion 2 (Ya habiendo ejecutado el Android Market):

Si ya han ejecutado el Android Market y el instalador no pudo encontrar las Google Apps el procedimiento es descargarlas, instalarlas nuevamente via ROM Manager en la opcion «Install ROM From SD Card» y podemos buscar de nuevo las google apps en el Market e instalarlas sin problema

¿Que pasa si unicamente las busco en el Android Market?

En mi caso todas las aplicaciones descargadas (Gmail por ejemplo) no funcionaron hasta instalar el ROM descrito anteriormente.

Y con esto soy un usuario feliz de Cyanogenmod en mi nexus one :).