25 noviembre 2010

Spring Community Day 2010: Apoyemos a los niños del AAHH San Alvino

Spring Community Day 2010: Apoyemos a los niños del AAHH San Alvino: "

Con tu donación para el ingrso al Spring Community Day 2010 (S/10.00 o su equivalente en cualquiera de los siguientes productos: leche, azucar, chocolate, panetón) apoya a los niños del AAHH San Alvino en la Misión de Navidad 2010 organizada por la UPC.

Aquí está la carta formal de UPC a Spring Perú.

23 noviembre 2010

...se viene el Spring Community Day 2010 (27/11/2010)

La comunidad Spring Perú tiene el agrado de invitarlos al 3er Spring Community Day 2010. Este evento organizado y presentado por la comunidad tiene el objetivo de compartir conocimiento y experiencias sobre el uso de Spring Framework y proyectos de Spring Source.


Puedes ver fotos de las ediciones anteriores aquí.
Puedes participar y enterarte de la organización del evento siguiendo la lista de Spring Perú
Cuando
Fecha: Sábado 27 de noviembre de 2010
Hora: 09:00am - 07:00pm
Donde
Universidad Peruana de Ciencias Aplicadas
Prolongación Primavera 2390, Monterrico
Lima
Ingreso
Para el ingreso debes registrarte primero. Este año Spring Perú se une a la misión de Navidad de este año organizada por la UPC para tener la oportunidad de trascender llevando la alegría de la Navidad a 300 niños de extrema pobreza del A.A.H.H. San Alvino en el distrito de Independencia. 
Para hacer realidad  este sueño,  necesitamos contar con tu apoyo, invitándote a apadrinar a un niño(a) con la donación de  S/.10.00, que será recolectado por la UPC para entregarte las credenciales de ingreso para las conferencias. Gracias a tu colaboración, cada niño disfrutará de un día lleno de alegría porque llevaremos juguetes, juegos inflables, snacks para compartir y el espíritu de la Navidad hasta sus hogares.
Programa
El programa consta de 3 tracks en paralelo: track básico, track avanzado y el Open Space.
Track 1 (Aula Magna)
09:00 - 09:15 Ingreso
09:15 - 09:30 Bienvenida
09:30 - 10:30 Introducción a Spring Framework (Lennon Shimokawa)
10:30 - 11:00 Coffee break
11:00 - 12:00 Spring DAO (Jonathan Lara)
12:00 - 13:00 Spring Web MVC (Susan Inga)
13:00 - 14:30 Almuerzo
14:30 - 15:30 Spring ORM con Hibernate (José Luis Bugarin)
15:30 - 16:30 Spring AOP (Mayer Horna)
16:30 - 17:00 Coffee break
17:00 - 18:00 Spring ROO (José Diaz)
18:00 - 19:00 Panel de cierre y retrospectiva final 
Track 2 (Aula A24)
14:30 - 15:30 Spring Portlet MVC (José Luis Manrique)
15:30 - 16:30 Spring Security (Edson Chavez)
16:30 - 17:00 Coffee break
17:00 - 18:00 Spring Web Services (Carlos Gavidia)
Track 3 (Aula A25)
14:30 - 15:30 Spring Web Flow (Colin Fairless)
15:30 - 16:30 Spring BlazeDS con Flex (Ricárdo Ávila)
16:30 - 17:00 Coffee break
17:00 - 18:00 Spring.NET (Angel Nuñez)
Open Space (Aula A22, Aula A31)
14:30 - 18:00 Open Space

16 noviembre 2010

WebSphere Portal - Customizar mensaje "This portlet is unavailable"

Curioseando encontré que el jar "wp.ui.jar" contiene una serie de archivos de propiedades
que contienen casi todos los mensajes que encuentras en el portal.

Para encontrarlo debemos ir a la siguiente ruta:

/ui/wp.ui/shared/app/wp.ui.jar

09 noviembre 2010

WP615 - Configurar páginas de error (Customize error pages)

Esta fue la tarea de esta semana: ¿cómo personalizamos las páginas para errores 404?



Para tener una configuración decente debemos tomar en cuenta que ésta se debe realizar en tres ámbitos diferentes: la primera es a nivel de webserver, la segunda a nivel del contexto "wps" y la tercera a nivel del contexto "portal", cómo se muestra en la figura.

Para el webserver debemos contar con una carpeta en dicho servidor con las páginas e imágenes que se emplearán para mostrar el mensaje de error. Luego en el archivo httpd.conf, ubicamos la sección que configura estos mensajes de error y establecerlo de manera similar al ejemplo que pongo a continuación:


Luego, configuramos el portal, para ello seguimos las siguientes instrucciones
- Bajar el portal en cada nodo.
- Subir en cada nodo el servidor "server1"
./startServer.sh server1
- Ubicarse en el Deployment Manager y allí crear una carpeta temporal
mkdir /was/wps_expanded
- Acceder al directorio dmgr_profile_root/bin
- Exportar el ear wps
./wsadmin.sh -user wpsadmin -password -c '$AdminApp export wps /was/wps.ear'
- Expandir el ear
./EARExpander.sh -ear /was/wps.ear -operationDir /was/wps_expanded -operation expand
- Crear una carpeta llamada "error" dentro de la carpeta "wps.war"
mkdir /was/wps_expanded/wps.ear/wps.war/error/
- Copiar los archivos de páginas de error en dicha carpeta.

NOTA: Las urls de los enlaces en la página deben seguir el siguiente formato:
"/wps/portal/rimac/inicio"
y las imágenes "imagenes/logo_rimac_seg.gif"

- Asignar permisos 777 a la carpeta "error"
chmod 777 R /was/wps_expanded/wps.war/error/
- Agregar dentro del web.xml entre los tags y , este archivo se encuentra en la ruta /was/wps_expanded/wps.war/WEB-INF



NOTA: Las urls de los enlaces en la página deben seguir el siguiente formato:
"portal/rimac/inicio"
y las imágenes "error/imagenes/logo_rimac_seg.gif"

- Agregar dentro del web.xml antes de los demás filtros.

Se aplica los "filters" a los siguientes contextos:
/portal/*
/myportal/*
/contenthandler/*



- Eliminar el archivo ear previamente exportado a fin de que podamos generarlo nuevamente.
- Empaquetar el ear
./EARExpander.sh -ear /was/wps.ear -operationDir /was/wps_expanded -operation collapse
- Importar el ear
./wsadmin.sh -user wpsadmin -password  -c '$AdminApp install  /was/wps.ear {-update -appname wps}'
- Bajar "server1"
- Reiniciar cada nodo de "WebSphere_Portal"
- Copiar el jar "portal-apiconz-filter.jar" del filtro en la ruta PortalServer/shared/app en ambos nodos.

Para este jar seguí las instrucciones que encontré en: Web Content Management: Custom error pages. Esta guía también la pude aplicar al portal

08 septiembre 2010

Ágiles 2010: 3ras Jornadas Latinoamericanas sobre Metodologías Ágiles

Ágiles 2010 es una excelente oportunidad para encontrase con
profesionales de IT de la región, interesados en compartir sus
experiencias, debatir y capacitarse en temas relacionados con el
desarrollo de software a través del uso de metodologías ágiles.

Esta tercera edición, con sede en la ciudad de Lima, Perú, contará
con la presencia de especialistas locales e internacionales, quienes
compartirán su conocimiento durante los cuatro días que durará el
evento.

El programa incluye distintos tipos de actividades: presentaciones,
sesiones interactivas, talleres y espacios abiertos de debate.

Entre los invitados internacionales se encuentran los keynote
speakers Lee Devin y Joshua Kerievsky, que también estarán brindando
cursos durante el evento.

Agiles 2010

¡Inscríbete y se parte de Ágiles 2010!

13 agosto 2010

WP615 - Error tras la instalación JVMJ9VM011W

Tras la instalación del WP615 en CentOS  quise ejecutar el siguiente comando:

[root@localhost bin]# ./serverStatus.sh WebSphere_Portal
... y recibí el siguiente error:

JVMJ9VM011W Unable to load j9jit23: /was/IBM/WebSphere/AppServer/java/jre/bin/libj9jit23.so: cannot restore segment prot after reloc: Permission denied 
JVMJ9VM011W Unable to load jclscar_23: /was/IBM/WebSphere/AppServer/java/jre/bin/libjclscar_23.so: cannot restore segment prot after reloc: Permission denied 
Could not create the Java virtual machine.

Para arreglarlo ejecuté el siguiente comando con el usuario root del servidor:

[root@localhost bin]# setenforce 0 

10 agosto 2010

EJPSG0015E: Data Backend Problem

Hace poco realicé la instalación de un TDS 6.2 y lo integré a mi portal. Quise probar la creación de usuarios desde el portal, sin embargo he recibido el siguiente mensaje:

EJPSG0015E: Data Backend Problem com.ibm.websphere.wim.exception.WIMSystemException: CWWIM4520E The 'javax.naming.NoPermissionException: [LDAP: error code 50 - Insufficient Access Rights]; remaining name 'uid=apiconz,cn=temporal,o=rimac'; resolved object com.sun.jndi.ldap.LdapCtx@66326632' naming exception occurred during processing.
com.ibm.wps.util.DataBackendException: EJPSG0015E: Data Backend Problem com.ibm.websphere.wim.exception.WIMSystemException: CWWIM4520E The 'javax.naming.NoPermissionException: [LDAP: error code 50 - Insufficient Access Rights]; remaining name 'uid=apiconz,cn=temporal,o=rimac'; resolved object com.sun.jndi.ldap.LdapCtx@66326632' naming exception occurred during processing.
EJPSG0015E: Data Backend Problem com.ibm.websphere.wim.exception.WIMSystemException: CWWIM4520E The 'javax.naming.NoPermissionException: [LDAP: error code 50 - Insufficient Access Rights]; remaining name 'uid=apiconz,cn=temporal,o=rimac'; resolved object com.sun.jndi.ldap.LdapCtx@66326632' naming exception occurred during processing.
CWWIM4520E The 'javax.naming.NoPermissionException: [LDAP: error code 50 - Insufficient Access Rights]; remaining name 'uid=apiconz,cn=temporal,o=rimac'; resolved object com.sun.jndi.ldap.LdapCtx@66326632' naming exception occurred during processing.

Revisando un poco la configuración encontré que faltaban dos configuraciones:

Por un lado debía indicarle al portal en qué rama del TDS debía guardar los usuarios que se iban creando, para esto modifiqué el archivo wimconfig.xml

La configuración de este archivo apuntaba a la ruta del repositorio por defecto del portal (hasta este punto ya lo había eliminado):

    o=defaultWIMFileBasedRealm" name="PersonAccount">
      uid
    
    o=defaultWIMFileBasedRealm" name="Group">
      cn
    

Asi que lo que hice fue cambiar la ruta para que apunte a ramas existentes en mi TDS:

    ou=personas,o=apiconz" name="PersonAccount">
      uid
    
    ou=grupos,o=apiconz" name="Group">
      cn
    




Adicionalmente a esta configuración, requería darle al usuario con el que enlazamos al portal con el tds permisos para que pudiera escribir sobre dichas ramas.

Para esto, entramos a Directory Management > Manage Entries seleccionamos la rama sobre la que queremos que el usuario pueda escribir y seleccionamos la opción Edit ACL... del menú desplegable que se encuentra en la parte superior de la grilla.

En la pantalla que nos aparece a continuación seleccionamos la opción Filtered ACLs e ingresamos los campos que se nos presentan en el formulario.

Luego vamos a la opción Owners y agregamos a nuestro usuario de enlace como propietario de la rama correspondiente.


23 julio 2010

Servicio enfocado en el usuario

Estoy reciclando notas de mi anterior blog, espero que les sea de interés

En la mayoría de casos, los egresados de las carreras técnicas se centran mucho en el lado tecnológico. La tecnología, hoy en día, nos brinda una serie de herramientas que pueden aportar grandes beneficios a las empresas, y porqué no decirlo, a la humanidad.
Sin embargo, esta no sirve mucho si nuestro enfoque no va orientado a la prestación de servicios de calidad.

Al contrario de lo que muchos piensen, la calidad es determinada por nuestros clientes (o sea, quien pone el dinero) y los que se benefician de esto son nuestros usuarios (o en otras palabras, quienes recibirán el servicio a diario).

Una situación que se presenta con mucha frecuencia es la siguiente: el técnico, cree que la tecnología lo es el todo y menosprecia al usuario por su, posible, escasa compresión de la misma, lo que finalmente conlleva a la prestación de un servicio deficiente. Por el otro lado, el usuario aprecia que el servicio que recibe no satisface sus necesidad y esto recae en quejas hacia el personal que presta el servicio o en casos extremos, al rompimiento de relaciones entre el cliente y el prestador de servicios.

Para evitar este tipo de situaciones, es importante, centrar nuestros esfuerzos en entender qué es lo que usuario realmente requiere. En muchos casos el “asumir” cosas nos lleva a un análisis pobre de la situación y, por ende, a entregar un servicio o un producto deficiente.

Para aclarar la figura, sería como ponernos en el papel de un doctor. Tenemos a nuestro paciente, el cuál se queja de tener un problema. Simplemente con escucharle no podemos, buenamente, recetarle un medicamento. Como medicos tendríamos que conocer al paciente, saber que problemas ha tenido antes, auscultarlo o pedirle que se realice análisis antes de emitir un diagnóstico y recetar algo.

De forma similar, como profesionales de TI nuestro enfoque debe estar en saber que es lo que pueda estar ocurriendo en la organización, cuáles son los procesos, cuáles son las necesidades u oportunidades de mejorar las condiciones de labor de los usuarios. Y sobre todo, recordar que es el usuario, y no nosotros, quienes conocen el “know-how” del negocio.

El nivel de calidad del servicio lo establece el cliente y el servicio de calidad lo recibe el usuario.

18 julio 2010

Error Code: 1267 Illegal mix of collations

Hoy mientras trataba de ejecutar un select entre dos tablas, en mySQL, recibí el siguiente mensaje de error:
Error Code: 1267 Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (latin1_spanish_ci,IMPLICIT) for operation '=')
Para entender este error primero veamos en qué consiste un COLLATION, segun sqlinfo.net :
"A character set is a set of symbols and encodings. collation is a set of rules for comparing characters in a character set." 
 Ok, luego de ver esto es importante hacer notar que el proyecto que vengo trabajando, trabaja con una base de datos mysql gestionada originalmente mediante la herramienta phpAdmin, y esta emplea por defecto el collation "latin1_swedish_ci" para crear sus tablas. Por mi parte los scripts de las tablas que debía agregar los hice mediante mi herramienta mySQL Workbench con el collation "latin1_spanish_ci" por defecto.

El problema viene al momento de efectuar la comparación, dado que las tablas, ya existentes como las que agregué yo, poseen collations diferentes la base de datos no puede determinar que reglas de comparación empleará para operaciones que las involucren juntas. Por esta razón, para salvar este problema agregamos la clausula COLLATE 'nombre_del_collation' para decirle a la BD qué reglas emplear. A continuación, un pequeño ejemplo de cómo quedaría nuestra sentencia.

SELECT e.column_id INTO tmp_id FROM tabla1 e INNER JOIN tabla2 m ON e.column_id = m.column_foreign_id_1 INNER JOIN table3 p ON p.column_id = m.column_foreign_id_2 WHERE p.column_id = valor_de_comparacion COLLATE 'latin1_spanish_ci';

16 julio 2010

SECJ0373E: Cannot create credential for the user due to failed validation of the LTPA token.

Problem / Problema:
We have 2 environments... a cluster of WPS and an standalone WCM. After of change the configuration of realm to federated ldap repository, we tried to rename the wcm realm name to the name of portal realm, but the WCM not started correctly; we can to navigate on Admin Console but when we're trying to open the wcm portal, the server just show a error indicating that some portal services can't be started.
Tenemos dos ambientes... un cluster de WebSphere Portal y un Web Content Manager. Después de cambiar la configuración del realm para federated, tratamos de renombrar el realm del WCM con el nombre del realm del portal (para que funcione el Single Sign On), pero el WCM no inicia correctamente; podemos navegar en la Consola de Administración del WAS pero cuando tratamos de ingresar al portal, solo nos muestra un error indicando que algunos servicios del portal no pudieron ser iniciados.


Trace:

SECJ0373E: Cannot create credential for the user due to failed validation of the LTPA token. The exception is com.ibm.websphere.security.CustomRegistryException: The realm in the token: apiconzldap.apiconz.info:389 does not match the current realm: PortalWcmRealmFederated
at com.ibm.ws.security.ltpa.LTPAServerObject.getRelativeName(LTPAServerObject.java:1473)
at com.ibm.ws.security.ltpa.LTPAServerObject.getSecurityName(LTPAServerObject.java:1421)
at com.ibm.ws.security.ltpa.LTPAServerObject.validate(LTPAServerObject.java:1259)
at com.ibm.ws.security.server.lm.ltpaLoginModule.login(ltpaLoginModule.java:599)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:618)
at javax.security.auth.login.LoginContext.invoke(LoginContext.java:795)
at javax.security.auth.login.LoginContext.access$000(LoginContext.java:209)
at javax.security.auth.login.LoginContext$4.run(LoginContext.java:709)
at java.security.AccessController.doPrivileged(AccessController.java:246)
at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:706)
at javax.security.auth.login.LoginContext.login(LoginContext.java:603)
at com.ibm.ws.security.auth.JaasLoginHelper.jaas_login(JaasLoginHelper.java:289)
at com.ibm.ws.security.auth.ContextManagerImpl.login(ContextManagerImpl.java:2874)
at com.ibm.ws.security.auth.ContextManagerImpl.login(ContextManagerImpl.java:2737)
at com.ibm.ws.security.web.WebAuthenticator.validate(WebAuthenticator.java:1640)
at com.ibm.ws.security.web.WebAuthenticator.validateCookie(WebAuthenticator.java:599)
at com.ibm.ws.security.web.WebAuthenticator.handleSSO(WebAuthenticator.java:520)
at com.ibm.ws.security.web.WebAuthenticator.handleCustomLogin(WebAuthenticator.java:743)
at com.ibm.ws.security.web.WebAuthenticator.authenticate(WebAuthenticator.java:1497)
at com.ibm.ws.security.web.WebAuthenticator.authenticate(WebAuthenticator.java:1373)
at com.ibm.ws.security.web.WebCollaborator.authorize(WebCollaborator.java:670)
at com.ibm.ws.security.web.EJSWebCollaborator.preInvoke(EJSWebCollaborator.java:318)
at com.ibm.ws.webcontainer.webapp.WebAppSecurityCollaborator.preInvoke(WebAppSecurityCollaborator.java:141)
at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:486)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:90)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:751)
at com.ibm.ws.wswebcontainer.WebContainer.handleRequest(WebContainer.java:1478)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:125)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:458)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:387)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:267)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture$1.run(AsyncChannelFuture.java:205)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)


Diagnostic / Diagnostico:
We found that the old realm name is still in one of the Portal database tables. If we update the realm in the table the exception when the portal starts should be resolved.
Encontramos que el nombre antiguo del realm está aun en una de las tablas de la base de datos del Portal. Si actualizamos el real en la tabla la excepción cuando el porta se inicia debería ser resuelta.
Solution / Solución
1) Login into WCM database.
2) Backup data on RELEASE.VP_DESC table.
db2 connect to RELEASE
db2 "select * from RELEASE.VP_DESC" > RELEASE.VP_DESC.TXT
3) Make change of realm name on security option from WAS 
apiconzldap.apiconz.info:389 -> PortalWcmRealmFederated
4) Stop the portal.
./stopServer.sh WebSphere_Portal -username wpsbind -password password
5) Make update to table.
db2 "update RELEASE.VP_DESC set REALM='apiconzldap.apiconz.info:389' where RELEASE.VP_DESC.REALM='PortalWcmRealmFederated'";  
6) Start the portal.
1) Ingresar a base de datos del WCM.
2) Respaldar datos de la tabla RELEASE.VP_DESC
db2 connect to RELEASE
db2 "select * from RELEASE.VP_DESC" > RELEASE.VP_DESC.TXT
3) Realizar cambio de nombre de Realm en las opciones de Seguridad del WAS.
apiconzldap.apiconz.info:389 -> PortalWcmRealmFederated
4) Bajar el portal.
./stopServer.sh WebSphere_Portal -username wpsbind -password password
5) Realizar actualización de datos en la bd.
db2 "update RELEASE.VP_DESC set REALM='apiconzldap.apiconz.info:389' where RELEASE.VP_DESC.REALM='PortalWcmRealmFederated'";
6) Subir el portal

03 julio 2010

PRECONEISC - Presentacion sobre Integración Continua

El día de hoy participé como invitado en el evento PRE CONEISC en Cañete, tuve la oportunidad de participar como ponente sobre "El desarrollo potenciado con la Integración Continua"

28 junio 2010

WebSphere Portal 6.1.5 : Actualizando a 6.1.5.1

Productos instalados:
IBM WebSphere Portal Server 6.1.5
IBM WebSphere Application Server 6.1.0.27

1) Me bajé el fixpack para el WAS FP0000029 para subir mi WAS a la versión 6.1.0.29 (requerido por el Portal), también, el UpdateInstaller 7.0.
2) Tras instalar el UpdateInstaller y dado que estaba trabajando en consola escribí lo siguiente en la linea de comandos:

$ ./update.sh -options "responsefiles/install-1.txt" -silent

3) Una vez actualizado el WAS, pasé a actualizar el portal mediante el PortalUpdater con el siguiente comando:

$ ./updatePortal.sh -install -installDir "dir_portal_root" -fixpack -fixpackDir "dir_fixpack" -fixpackID WP_PTF_6104

4) Una vez que la instalación culmina podemos verificar la versión mediante WPVersion.sh, podremos ver que nuestro portal cuenta ya con el FeaturePack 6.1.5.1

24 junio 2010

WPS - Respaldar / Restaurar configuración

A medida que sigo conociendo un poco más acerca de la Administración del WebSphere Portal descubro que tiene ciertos utilitarios que pueden hacer menos riesgoso nuestro trabajo. Con los utilitarios "backupConfig.sh" y "restoreConfig.sh" podremos respaldar y restaurar la configuración del portal perteneciente a un perfil.

10 junio 2010

Instalación de subversion en Ubuntu

Normalmente he usado CVS como repositorio de código, sin embargo, me he animado a instalar subversion; asi que dada la ocasión me animé a grabar un video tutorial indicando cómo efectuar la instalación.


Instalación de SVN en Ubuntu from Armando Picon on Vimeo.

07 mayo 2010

Disparar y Avanzar

Interesante mensaje que me envió mi padre y que deseo compartir con ustedes.

Disparar y avanzar

Por Joel Spolsky
Traducido por Juan Lupion
Editado por Pablo A. Pinzón
6 de Enero, 2002



Hay veces en las que no me sale nada.

Fijo. Llego a la oficina, doy un par de vueltas, veo si hay correo cada diez segundos, navego por la red y tal vez haga algunas tareas tontas como pagar la factura de la American Express. Pero lo de volver a escribir código con fluidez no ocurre.

Tetris

Estas lagunas de improductividad por lo general duran uno o dos días, pero ha habido veces en mi carrera como desarrollador que me ha pasado semanas enteras sin ser capaz de hacer nada. Como se suele decir, no estás inspirado. No estás en lo que estás. No estás en ningún sitio.

Todos tenemos cambios de estado de ánimo. Para algunos, son suaves, pero en otras personas pueden ser más pronunciados, incluso patológicos. Y los periodos improductivos parecen estar relacionados con los estados de ánimo más abatidos.

Esto me recuerda a los investigadores que afirman que, básicamente, la gente no puede controlar lo que come, de manera que cualquier intento de hacer una dieta está condenado a ser efímero y siempre terminan rebotando hasta volver a su peso natural. Tal vez no puedo, como desarrollador de software, controlar cuándo soy productivo: simplemente he de asumir las épocas espesas con las épocas de rápido avance y esperar que, en término medio, pueda escribir suficientes líneas de código como para hacer que quieran contar con mis servicios.

Go read The Onion for a while.

Lo que me inquieta es que desde mi primer trabajo me he dado cuenta de que, como desarrollador, en término medio sólo puedo escribir código productivamente durante dos o tres horas al día. Cuando tuve una beca de verano en Microsoft, un compañero becario me dijo que en realidad sólo iba a trabajar de doce a cinco. Cinco horas (menos el almuerzo) y aún así su equipo lo veneraba porque aún se las apañaba para hacer mucho más que la media de los demás. Y yo creo que así ha de ser. Me siento un poco culpable cuando veo cómo los demás trabajan tanto y yo sólo tengo dos o tres horas de calidad al día y aún así siempre he sido uno de los miembros más productivos del equipo. Quizá por eso, cuando Peopleware y XP (Extreme Programming) insisten en eliminar las horas extras y las jornadas de 40 horas semanales lo hacen con la completa seguridad de que esto no implica una reducción en el rendimiento del equipo.

Pero los días que me preocupan no son en los que "sólo" trabajo dos o tres horas. Son aquellos días en los que no puedo rendirnada.

Le he dado muchas vueltas a esto. He tratado de recordar cuál ha sido la vez en mi carrera que más trabajo he sacado adelante. Probablemente fue cuando Microsoft me cambió a un nuevo y bonito despacho enmoquetado con grandes ventanas que dominaban un lindo patio empedrado, lleno de cerezos en flor. Todo latía. Durante meses trabajé sin parar, despachando la especificación detallada de Excel Basic: una montaña de papeles que abarcaban un gigantesco modelo de objetos y todo un entorno de programación. Literalmente: no podía parar. Cuando tuve que ir a Boston al MacWorld me llevé un portátil y documenté las clases de Windows sentado en una agradable terraza en el HBS [Harvard Business School].
Una vez que te pones manos a la obra no es tan difícil seguir a buen ritmo. Muchos de mis días transcurren de esta manera: (1) ir al trabajo (2) leer el correo, navegar por la red, etc. (3) decidir que voy a ir a almorzar antes de ponerme a trabajar (4) volver de la comida (5) leer el correo, navegar por la red, etc. (6) decidir por fin que debería empezar (7) leer el correo, navegar por la red, etc. (8) decidir otra vez que debería ponerme a trabajar (9) lanzar el maldito editor y (10) escribir código casi sin parar hasta que no me doy ni cuenta de que ya son las 7 y media de la tarde.

En alguna parte entre los pasos 8 y 9 parece haber un bug, porque no siempre puedo dar ese salto.

bike tripPara mí, ponerme manos a la obra es lo único difícil: un objeto en reposo tenderá a permanecer en reposo. Hay en mi cerebro algo que pesa muchísimo y es difícil hacer que alcance la velocidad de crucero; pero una vez que la alcanza no cuesta ningún trabajo hacer que siga. Como una bicicleta preparada para atravesar un país entero: cuando comienzas a pedalear en una bici con todo ese material es difícil de creer cuánto cuesta arrancar, pero luego es tan sencillo como ir con una bicicleta sin carga alguna.

Quizá sea esta la clave de la productividad: ponerse en marcha. Tal vez cuando la programación por parejas funciona es porque cuando organizas una sesión de programación en pareja con tu compañero, ambos os estáis forzando a poneros en marcha.

Joel in the ArmyCuando fui paracaidista en el ejército israelí un general nos dió un pequeño discurso acerca de la estrategia. En las batallas de infantería, según nos contó, sólo hay una única estrategia: Disparar y Avanzar. Uno se mueve hacia el enemigo mientras a la vez dispara sus armas. El fuego obliga al enemigo a agachar la cabeza de modo que no puede dispararte (eso es lo que quieren decir los soldados cuando gritan "¡cubridme!", que significa: "Dispárale al enemigo de forma que se tenga que esconder y no pueda dispararme mientras cruzo la calle". Y funciona). El avance te permite capturar territorio y acercarte a tu enemigo, donde es más probable que tus disparos den en el blanco. Si no avanzas, el enemigo decide lo que ocurre, lo cual no es bueno. Si no disparas el enemigo te disparará, teniendo un objetivo fácil.
Recordé esto durante mucho tiempo. Me di cuenta de que casi todas las estrategias militares, desde los combates aéreos a las maniobras navales a gran escala, están basadas en la idea de Disparar y Avanzar. Tardé otros quince años en darme cuenta de que el principio de Disparar y Avanzar es la forma en que se hacen las cosas en esta vida. Tienes que avanzar un poquito cada día. No importa si tu código está mal escrito y tiene errores y nadie lo quiere. Si avanzas, escribiendo código y arreglando los errores continuamente, el tiempo está de tu parte. Presta atención cuando la competencia te dispara. ¿No querrán mantenerte ocupado, reaccionando a sus boleas, de forma que no puedas avanzar?


Recordemos la historia de las estrategias de acceso a bases de datos que han surgido de Microsoft. ODBC, RDO, DAO, ADO, OLEDB, y ahora ADO.NET ¡Todas novísimas! ¿Acaso todas son imperativos tecnológicos? ¿O son el resultado de un grupo de diseño incompetente que necesita reinventar el acceso a base de datos cada año? (Es probable que, en realidad, sea esto último) Pero el resultado final es que únicamente se trata de fuego de cobertura. La competencia no tiene otra opción que perder todo su tiempo portando y manteniéndose al día, tiempo que no pueden dedicar a desarrollar nuevas prestaciones. Examinemos de cerca el panorama del software. Las compañías que funcionan son las que dependen menos de compañías grandes y no tienen que perder todos sus ciclos de desarrollo poniéndose al día, reimplementando y arreglando errores que sólo se manifiestan bajo Windows XP. Las compañías que se tambalean son las que pasan demasiado tiempo leyendo hojas de té para vaticinar el próximo movimiento de Microsoft. La gente se preocupa por .NET y decide re-escribir todo su código porque creen que tienen que hacerlo. Microsoft te dispara, y sólo es fuego de cobertura de forma que ellos puedan avanzar y tú no, porque así es como se juega a este juego, chaval. ¿Vas a añadir soporte para Hailstorm? ¿SOAP? ¿RDF? Lo vas a soportar porque tus clientes lo necesitan, o porque alguien te está disparando y te sientes obligado a responder? Los equipos comerciales de las grandes compañías, que conocen lo que es el fuego de cobertura, van a sus clientes y les dicen: "Vale, no tienes que comprarnos a nosotros. Cómprale al mejor vendedor. Pero asegúrate de que compras un producto que soporta (XML / SOAP / CDE /J2EE) porque si no estarás atrapado en el software propietario" Luego, cuando las compañías pequeñas intentan venderle algo a ese cliente, se encuentran con gerentes obedientes que repiten como cotorras: "¿Tienes J2EE?" Y lo único que hacen es perder todo el tiempo desarrollando con J2EE incluso aunque eso no te de más ventas, y no les da ninguna oportunidad para diferenciarse de los demás. Es una prestación de catálogo; la implementas porque necesitas el recuadro que dice que lo tienes, pero nadie la va a usar ni la necesita. Y es fuego de cobertura.


Para las compañías pequeñas como la mía disparar y avanzar significa dos cosas. Tienes que tener el tiempo de tu parte y tienes que avanzar cada día. Tarde o temprano ganarás. Lo único que logré hacer ayer fue mejorar un poquitín el esquema de colores de FogBUGZ. Eso está bien. Está mejorando continuamente. Cada día nuestro software es mejor y mejor y tenemos más y más clientes, eso es todo lo que nos importa. Hasta que seamos una compañía tan grande como Oracle, no tenemos que pensar en grandes estrategias. Únicamente hay que venir cada mañana y, de algún modo, arrancar el editor.

It's getting better all the time... o/~



Esté articulo apareció originalmente en Inglés con el nombre Fire and Motion  






01 mayo 2010

WPS y WCM - Exportar e Importar LTPA-Keys para Single Sign On (SSO)

En ocasiones es necesario implementar un ambiente SSO sobre diferentes celdas (Ej. Implementar SSO entre un cluster de WebSphere Portal Server y un nodo independiente de WebSphere Content Manager). Para efectuar esto es necesario contar con llaves LPTA iguales en ambos servidores.

Para efectuar esta operación es necesario que los hagamos a traves de la consola administrativa (para el cluster a través del Deployment Manager).

1. Para exportar las llaves LTPA desde una celda (cell) debemos ir a Security > Secure administration, applications, and infrastructure > Authentication mechanisms and expiration.

2. Llenar el formulario que se muestra a continuación:


y pulsamos en "Export keys". Las llaves LTPA se exportarán al directorio especificado. Debemos tomar en consideración que para importarlas luego necesitaremos conocer la contraseña con la que lo exportamos.

3. Copiamos el archivo exportado a la otra celda (tomar en cuenta que cada celda contiene ya un archivo "ltpa.jceks", NO DEBEMOS SOBREESCRIBIRLO.

4. Antes de proceder a importar el archivo. Debemos tomar nota del tamaño del archivo ltpa.jceks. El archivo está localizado en  /"websphere_root"/"dmgr"/config/cells/"cellname"/ltpa.jceks

5. Para importar el archivo con las llaves debemos ir a Security > Secure administration, applications, and infrastructure > Authentication mechanisms and expiration.

6. Llenamos el mismo formulario que muestro en la figura anterior y pulsamos "Import keys"

7. El tamaño del archivo ltpa.jceks deberá incrementarse.

8. Reiniciamos los servidores / nodos y listo!

17 marzo 2010

Agregar Certificado Digital Firmado en el Key Database (Notas)


En un ambiente de producción, por lo general, se emplean certificados firmados por terceros o sea por empresas certificadoras (CA). Dichas empresas proveen los Signer Certificates, certificados que establecen la confiabilidad de los certificados emitidos por las CA.  Por defecto cada key database que creamos contiene una lista ya establecida de ellos.

Cualquier certificado de alguna de las entidades incluidas en esta lista puede ser recibido y agregado al key database.

Cuando efectuamos una solicitud de certificado a una entidad que no se encuentra en esta lista; lo primero que debemos hacer, antes de pretender recibir el certificado, es agregar a dicha entidad en la lista. Para llevar a cabo esta operación debemos obtener un “certificado maestro”, el cual, generalmente, se encuentra en la página web de la entidad y es el que ‘certifica que la entidad es una entidad certificadora’.

En algunos casos la entidad podría contar con más de un certificado maestro, para esto podríamos decodificar el certificado que queremos agregar para determinar el tipo de certificado maestro que necesitamos.

Una vez que hemos conseguido agregar el certificado maestro al key database podremos proceder a la recepción del certificado que queremos agregar.

10 marzo 2010

Simplificando tareas con Maven...

En la consultora en la que estuve trabajando hace poco, tuvimos la oportunidad de emplear una herramienta que nos permitió ahorrar tiempo en la tarea de configuración de nuestros proyectos. Esta herramienta es Maven.

Maven es una herramienta para la gestión y configuración de proyectos Java. Una de sus fortalezas radica en un archivo llamado pom (Project Object Model); este archivito guarda los datos relacionados a la configuración y dependencias que empleará la aplicación.

Podemos encontrar que al crear un nuevo proyecto Maven automáticamente genera una estructura de source folders y paquetes que nos permite separar las clases que corresponden a la aplicación en sí de las que pertenecen a nuestras pruebas.

Sobre la gestión de las dependencias me encantó que podíamos determinar el scope de cada dependencia, por ejemplo, podía indicar que mi librería de log4j esté presente durante mis pruebas y que no esté presente al generar mi empaquetado final. También, encontramos que la descarga de dependencias declaradas se efectúa de manera automática a un repositorio local, lo cual nos permite centralizarlas y así evitar el ocupar espacio innecesario con multiples copias, cada una de ellas para un proyecto en particular.

Enlaces:
Apache Maven Project - Página del proyecto.

The Maven 2 POM demystified - Interesante artículo para comprender la importancia del archivo POM.

09 marzo 2010

¿Cómo funciona el coaching?

Visitando el blog de Francisco Alcaide Hernandez encontré el siguiente cortometraje que ilustra de forma muy didáctica cómo se lleva a cabo el coaching.

20 febrero 2010

Leyendo: Head First Design Pattern

Head First Design Patterns, es un libro que, de manera bastante amena, te introduce en el aprendizaje de los tan necesarios patrones de diseño. Este libro trae ejemplos prácticos e intenta contextualizar cada uno de los patrones con elementos que podemos encontrar en nuestra vida diara.

Es una lectura, en mi opinión, obligada para todos aquellos que recién empiezan a entrarle a este tema y que, al final de cuentas, potenciará y mejorará la calidad del código y soluciones que implementemos.

Para pedirlo puedes encontrarlos en Amazon.com