Buscar en xnoccio
Archivos del sitio javahispano
Humor: Firma digital en una antigua máquina de escribir Oliveti
En nuestro esfuerzo por ser una plataforma de firma digital universal, nuestro departamento de I+D ha conseguiro ampliar aun más nuestra matriz de compatibilidad consiguiendo realizar una firma digital en una antígua Oliveti!.
El video no tiene desperdicio :p.
De esta forma junto con las plataforma ya soportadas Linux (Firefox, Chrome), MacOS (Safari, Firefox), Windows (Firefox,Chorme, IE 6. IE7, IE8), Android, iPhone, iPad; Ahora incorporamos soporte para Oliveti Linea 98!!
Viafirma ya disponible en el Apple Store y Android Market
El componente de Viafirma para Android/iPhone/iPad ya está disponible tanto en la App Store como el Android Market de forma totalmente gratuíta, de esta forma Viafirma se convierte en la primera plataforma en soportar la autenticación y firma digital en estos dispositivos!.
Disponible en App Store y Android Market cualquier país en Ingles, Frances y Español.
Una vez más, la plataforma amplía su Matriz de Compatibilidad, garantizando el principio de Neutralidad Tecnológica citada en la Ley 11/2007 de Acceso Electrónico de los Ciudadanos a los Servicios Públicos.
Formatos de firma disponibles desde iPad/iPhone/Android:
- XMLSignature
- XAdES-BES
- XAdES-EPES
- XAdES-T
- XAdES-C
- XAdES-XL
- XAdES-A
- CMS (Cryptographic Message Syntax)
- Facturae
- PDF-Signature
APIs y módulos disponibles para la integración de terceros:
- Java
- .Net
- Php
- Pyton
- Drupal
- Joomla
- Django
Para ofrecer servicios a estos dispositivos puedes puedes instalar Viafirma en tus instalaciones sobre:
- Websphere
- Weblogic
- Tomcat 5, Tomcat 6
- GlassFish v3
O si lo prefieres puedes utilizar directamente nuestro servicio “on demand” y ofrecer a tus clientes autenticación y firma digital de una forma muy sencilla y económica.
Autoridades de certificación soportadas por la plataforma:
- Firma Profesional
- Camerfirma (Cámara de Comercio)
- Ancert (Agencia Notarial de Certificación)
- Izenpe (Gobierno Vasco)
- ACA (Autoridad de Certificación de la Abogacía)
- ANF AC (Asociación Nacional de Fabricantes)
- Avansi (primera CA autorizada en la República Dominicana)
- Cámara de Comercio y Producción de Santo Domingo (República Dominicana)
- Firma Digital (Sistema Nacional de Certificación Digital de Costa Rica)
- SINPE (Sistema Interbancario de Negociación y Pago Electrónico) – Costa Rica
- DNIe * no disponible para iPhone/iPad/Android
- FNMT (Fábrica Nacional de Moneda y Timbre) * requiere convenio con la FNMT
Más información en bubiloop:Viafirma Mobile App
Artículos relacionados:
http://www.xnoccio.com/1247-firma-digital-movil-en-ipad_iphone_firma_electronica/
http://www.xnoccio.com/1201-android-y-mi-certificado-digital/
Hudson: Nuestro compañero
Os dejamos las estadísticas de uso de nuestra herramienta de integración continua preferida!
Hace más de 2 años que usamos Hudson como herramienta en todos nuestros proyectos de desarrollo, y en poco tiempo pasó a convertirse en un pilar central de nuestro entorno de desarrollo.
Tras estos dos años, estos son los datos:
| Proyectos gestionados (Jobs configurados) | 192 |
| Proyectos en Activo: | 52 *(usados en los últimos 20 días) |
| Numero total de compilaciones realizadas | 6442 |
| Despliegues automáticos al servidor de desarrollo | 4127 (sobre nuestros 5 entornos) |
| Media de operaciones diarias: | 12 |
La instalación es la por defecto sobre Linux, junto a un Slave que utilizamos puntualmente para las test sobre Windows.
Respecto a los plugins, aunque le hemos dado una oportunidad a practicamente todos, estos son los más utilizados:
- SVNCopyPlugin (Plugin desarrollado internamente por Viavansi para la sincronización con el SVN del cliente tras despliegues exitosos)
- Hudson SCP Publisher Plugin (desarrollado internamente para publicar en nuestro sistema de descargas )
- ChuckNorris Plugin
- SubversionTaggin Plugin
- Disk Usage Plugin
- Seleniumhq Plugin
- Sonar Plugin
- Dependency Analyzer
- Backup Plugin
- Deploy Plugin
- SCP Plugin
- Jabber Plugin
Algunos artículos relacionados:
Introducción a Hudson: http://www.xnoccio.com/362-hudson-parte-1-introduccion/
Introducción al desarrollo de Plugins: http://www.xnoccio.com/464-hudson-parte-2-crea-tus-propios-plugins/
Comparatíva: http://www.xnoccio.com/368-eligiendo-nuestro-entorno-de-integracion-continua-i/
y conclusiones http://www.xnoccio.com/372-conclusiones-finales-eligiendo-nuestro-entorno-de-integracion-continua-v/
Android y mi certificado digital
La nueva versión de Viafirma 3.0, proporciona como principal novedad el soporte para autenticación y firma digital desde dispositivos móviles como Android, iPhone o iPad.
De esta forma Viafirma se convierte en la primera plataforma de autenticación y firma digital con soporte completo para Android, iPhone o iPad.
A continuación vamos a mostraros un ejemplo de autenticación digital utilizando Viafirma desde Android.
En los próximos días iremos ofreciendo ejemplos de autenticación y firma desde los diferentes dispositivos móviles ya soportados.
¿Qué implica esto?
Pues que las entidades que opten por utilizar Viafirma podrán ofrecer servicios de autenticación y firma digital a sus usuarios móviles. Imagina por ejemplo acceder a tu banco mediante autenticación digital desde tu Android!
¿Cuándo estará disponible?
Ya está disponible para clientes corporativos y en unos días estará disponible en el Google Market de forma gratuita.
13-07-10
Disponibles ya los clientes para iPad y iPhone.
http://www.xnoccio.com/1247-firma-digital-movil-en-ipad_iphone_firma_electronica/
Plataforma de autenticación y firma digital sobre WebLogic
La nueva versión de Viafirma, coincidiendo con su instalación en dos importantes entidades bancarias, ofrece soporte oficial para Oracle WebLogic 11. De esta forma, junto con las plataformas ya soportadas por Viafirma (Tomcat 5, Tomcat 6, Websphere, etc…), ahora se incluye:
- Oracle Fusion Middleware 11 / Weblogic 11g.
- Oracle Enterprise Pack for Eclipse
- Sun JVM 5, Sun JVM 6
- SO: Linux, Windows Server
El proceso de instalación es muy sencillo, por lo que siguiendo los pasos del manual de instalación de Viafirma para Weblogic podremos disponer de sus servicios de autenticación (DNIe o cualquier otro certificado digital) y firma digital (XAdES, PAdES, CMS, CAdES, facturae, firma en lotes,…) desplegados sobre Weblogic .
UsernameToken en Jax-ws (1/2)
El objetivo de este artículo es mostrar como usar UsernameToken según la especificación Web Services Security UsernameToken Profile 1.0. El artículo consiera que el lector ya tiene experiencia en Jax-ws y se centra sólo en la configuración del mecanismo de seguridad para publicar y consumir servicios que requieran la identificación del solicitante con usuario y password haciendo uso de Jax-ws.
Dependencias requeridas
Aunque las dependencias necesarias están incluidas en algunos servidores de aplicaciones, si lo deseamos podemos o bien bajar la implementación de referencia directamente desde su web:
https://jax-ws-commons.dev.java.net y https://jax-ws.dev.java.net
O definir la dependencia en caso de que el proyecto sea Maven.
Definir un nuevo manejador JAX-WS
En primer lugar indicaremos sobre la clase que implementa el WS el handlerchain.xml que define el manejador de seguridad mediante la anotación @HandlerChain.
@HandlerChain(file = "handlerchain.xml")
@WebService(serviceName = "IcmsWSAPIService", targetNamespace = "http://www.juntadeandalucia.es/icms", name = "IcmsWSAPIClient", portName = "IcmsWSAPIPort", endpointInterface = "es.juntadeandalucia.icms.IcmsPublisherClient")
public class IcmsPublisherWSImpl implements IcmsPublisher {..}
A continuación indicaremos en el fichero handlerchain.xml el nombre de la clase que implementa en manejador de seguridad.
Implementar un manejador para WSS
Se necesitará una clase que implemente SOAPHandler que haciendo uso de XWSSProcessor se encargue de procesar los mensajes SOAP con los header WSSE. Un ejemplo de esta clase podría ser:
/**
* Web Services Security UsernameToken Profile 1.0
*
*/
public class SecurityHandler implements SOAPHandler<SOAPMessageContext> {
XWSSProcessor securityProcessor = null;
/**
* Build the Security Handler
*/
public SecurityHandler() {
try {
// Creamos el procesador SOAP para WSS
final InputStream input = this.getClass().getResourceAsStream("/user-pass-authenticate-server.xml");
final XWSSProcessorFactory factory = XWSSProcessorFactory.newInstance();
securityProcessor = factory.createProcessorForSecurityConfiguration(input, new SecurityEnvironmentHandler());
input.close();
} catch (final Exception e) {
logger.error("No se puede inicializar El Handler", e);
}
}
/**
* Recuperamos el bloque header.
*/
public Set<QName> getHeaders() {
final QName securityHeader = new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity- secext-1.0.xsd", "Security", "wsse");
final HashSet<QName> headers = new HashSet<QName>();
headers.add(securityHeader);
return headers;
}
public boolean handleFault(final SOAPMessageContext messageContext) {
return true;
}
public boolean handleMessage(final SOAPMessageContext messageContext) {
final SOAPMessage message = messageContext.getMessage();
try {
// Contexto WSS
final ProcessingContext context = securityProcessor.createProcessingContext(message);
context.setSOAPMessage(message);
SOAPMessage verifiedMsg = null;
verifiedMsg = securityProcessor.verifyInboundMessage(context);
// Obtenemos el usuario y pass indicado en la request
String username = null;
String pass = null;
final Subject subject = SubjectAccessor.getRequesterSubject(context);
final Set<Principal> principals = subject.getPrincipals();
if (!principals.isEmpty()) {
final Principal principal = principals.iterator().next();
// Obtenemos en CN: CN=userName
username = StringUtils.substringAfterLast(principal.getName(), "=");
}
final Set<Object> publicCredentials = subject.getPublicCredentials();
if (!publicCredentials.isEmpty()) {
pass = (String) publicCredentials.iterator().next();
}
// Verificamos el comportamiento user y pass
validateUser(username, pass);
messageContext.setMessage(verifiedMsg);
} catch (final XWSSecurityException e) {
logger.error("WSS validation problem. ", e);
throw SecurableSoapMessage.newSOAPFaultException("WS validation problem.", e);
}
return true;
}
/** Validación específica de la aplicación.
* @param username
* @param pass
* @throws XWSSecurityException
*/
private void validateUser(final String username, final String pass) throws XWSSecurityException {
// Verificación específica de la aplicación.
//throw new XWSSecurityException("Invalid user." + username);
}
public void close(final MessageContext messageContext) {
}
private static Logger logger = Logger.getLogger(SecurityHandler.class);
}
Esta clase será la encargada de procesar todos los mensajes, verificando que todos son válidos y contienen un usuario y pass correcto. Un ejemplo de un mensaje válido WSS sería:
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" S:mustUnderstand="1">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="XWSSGID-1255949753848350309586">
<wsse:Username>usuario</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">****</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">9w+YwOatF9l1/otioQ75d5Yr</wsse:Nonce>
<wsu:Created>2009-10-19T10:55:54.418Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</S:Header>
<S:Body>
<ns2:ping xmlns:ns2="http://www.juntadeandalucia.es/icms" xmlns:ns3="http://www.juntadeandalucia.es/icms/data">
<ns2:request>test</ns2:request>
</ns2:ping>
</S:Body>
</S:Envelope>
Próximamente cómo crear un cliente Jax-ws que consuma servicios securizados con UsernameToken.
Creando una aplicación web basada en OSGI con Eclipse
A continuación se describen los pasos básicos a dar para crear una aplicación web que en lugar de ser desplegada sobre la típica pila JEE, sea desplegada como un componente más dentro de un contenedor OSGi.
Para ello se mostrará como construir con Eclipse un bundle OSGi que haciendo uso de Jetty nos permita correr un servlet sobre Equinox.
- Crear el proyecto base
En primer lugar, necesitaremos crear un plugin, indicando que es de tipo OSGI (implementación Equinox).
- Definición de las dependencias
Una vez que tengamos el proyecto creado, necesitaremos declarar las dependencias que necesitará nuestro módulo para poder funcionar como un servidor de aplicaciones. Las dependencias serán como mínimo:
- javax.servlet
- org.eclipse.equinox.http.jetty
- org.eclipse.equinox.http.servlet
- org.mortbay.jetty.server
- org.eclipse.equinox.http.registry
- Construcción del servlet de ejemplo
Una vez tengamos declaradas los módulos dependientes, Eclipse se encarga de actualizar nuestro classpath y ya podremos programar nuestro primer servlet sin problemas de compilación.
/** * Osgi Example Servlet. * */
public class HolaMundoOsgiServlet extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Petición al Servlet OSGi");
resp.getWriter().append("Respuesta desde un Servlet Osgi");
}}
Como podemos ver, se trata de un servlet normal, que debería ser mapeado en el web.xml y desplegado dentro de un contenedor de servlets.
- Activación del servlet
A diferencia del modelo tradicional (definido por la especificación JEE), la activación del servlet no requiere ningún web.xml. En su lugar, definiremos (al igual que cualquier otro servicio OSGI) un nuevo punto de extensión de nuestra aplicación. Para ello accederemos a la pestaña “Extension” y añadiremos la extensión “org.eclipse.equinox.http.registry.servlet” a nuestro módulo. Con esto le hemos indicado a OSGi que nuestro módulo hace uso del contenedor de Servlet.
El siguiente paso será indicar la clase que implementa el nuevo servlet y el mapeo, para ello simplemente definiremos la propiedad alias y class del nuevo servlet asociado a la extensión creada previamente.
Con esto ya tenemos nuestra primera aplicación web OSGi.
- Probando nuestra aplicación.
Para probar la aplicación sólo es necesario ejecutar el proyecto (Run As…>OSGi Framework) y acceder con el navegador a http://localhost:8080/exampleSi todo ha funcionado correctamente, en consola deberemos ver algo como lo siguiente:
Persistence bundle started.
Activado módulo OSGi: Ejemplo OSGI!!
Activado Servlet OSGiProviderTracker: New service detected...
ProviderTracker: Added service org.eclipse.persistence.jpa.osgi.PersistenceProviderOSGi
Petición al Servlet OSGi
Aunque aquí sólo se muestra un ejemplo muy básico, OSGI ya nos ha demostrado ser de mucha utilidad en proyectos reales muy complejos.
Por fin un estándar con el que entretejer nuestras aplicaciones.
Recientemente se ha liberado la primera versión estable de Weld, la implementación de referencia de Web Beans (Java Context and Dependenty Injection - JSR 299). Y aunque puede parecer una liberación cualquiera, en este caso estamos ante un evento realmente importante para el mundillo Java.
¿Por qué es importante esta liberación?
- Por fin tenemos un estándar Java para la inyección, publicación, localización y búsqueda de componentes.
- Promete una mejor orquestación entre componentes JEE, evitando los típicos problemas de interoperabilidad entre Beans Spring, componentes Seam, Wicket, JSF, EL, etc..)
- Un remplazo estándar a las diferentes soluciones de inyección e IoC como Spring IoC, el prometedor Google Guice o el muy utilizado por nosotros Jboss Seam annotations.
- Fin del infierno XML, definiendo un mecanismo estándar independiente de ficheros de definición XML, que junto con JSF 2.0, Servlet 3.0, JPA, Jax-ws, etc… simplifican el desarrollo JEE.
¿Consecuencias para la industria a medio plazo?
- Es demasiado pronto para saberlo, pero…
¿Quizás el fin de la guerra de frameworks se inyección?…. (Google Guice vs Spring vs Jboss Seam). Consiguiendo un efecto similar al que consiguió JPA/JDO estandarizando el acceso a datos. - Por fin una especificación JEE con la que construir aplicaciones complejas de forma sencilla.
- En un momento en el que muchas organizaciones están intentando estandarizar sus desarrollos, llegando incluso a restringir o imponer las tecnologías utilizadas, la preselección de implementaciones como Spring IoC o Seam carecerá de sentido. Siendo mucho más coherente la recomendación de estándares en lugar de restringir la evolución natural de la tecnología y la sana competición entre sus diferentes implementaciones.
¿Consecuencia para nosotros?
- Ninguna…. Gracias a nuestra apuesta por Jboss Seam (desde hace ya unos años), esta especificación se encontraba ya en nuestra hoja de ruta antes incluso de que fuese un Draft, por lo que para nosotros será suficiente con una mínima adaptación al estándar.
- La implementación es estable, la especificación muy bien pensada, y en las pruebas que hemos realizado con la beta, ha demostrado que consigue simplificar los desarrollos y hacer más comprensible el “oscuro arte de la inyección de componentes”.
- En breve empezaremos a usarla en algún proyecto piloto (que pueda asumir el riesgo de I+D asociado), analizaremos en detalle los posibles problemas que puedan surgir, y si todo se comporta como promete a mediados de 2010 empezaremos a usar la nueva especificación en nuestros proyectos Java.
¿Defectos?
- Llega demasiado tarde. Otros frameworks llevan, aunque de una forma mucho menos limpia, ofreciendo algo similar desde hace ya mucho tiempo.
- Todavía no conocemos sus defectos. Y eso es un gran problema ya que hasta que no conozcamos sus problemáticas asociadas no será seguro su uso en proyectos de envergadura.
- Esperemos que en la huida del infierno de los ficheros de configuración XML, no nos metamos en las tinieblas del uso de inyección e IoC para todo. Ya que una aplicación con una gran cantidad de componentes, comportamientos o atributos que dependen de la inyección hace muy complicada la comprensión de su funcionamiento.
En definitiva, todo indica que estamos antes una de las piezas clave del próximo JEE 6.
Guía de migración de proyectos Java a Maven
Objetivos
El objetivo de este artículo es servir de guía básica para la migración manual de proyectos Java no Maven a entorno Maven. Pensado y dirigido especialmente a personas con poca experiencia previa en Maven, pero con algún conocimiento previo.
Preparación del proyecto
Como es obvio, para migrar un proyecto Java a Maven, deberemos disponer de sus fuentes y todas las librerías dependientes.
Ya que vamos a realizar modificación estructurales importantes en el proyecto, conviene asegurarnos de que los fuentes no están conectados a ningún sistema de control de versiones como Subversion. Para realizar esto, podemos o bien eliminar manualmente todos los directorios .svn de nuestro proyecto o bien desde Eclipse desconectar el proyecto.
Si lo vamos a realizar de forma manual, debemos asegurarnos de eliminar todos los directorios .svn (o .CVS si el proyecto a migrar estuviese conectado a un CVS) A modo de ejemplo, en Linux podemos ejecutar el siguiente comando desde el directorio del proyecto para eliminar todas las referencias a carpetas ‘.svn’:
rm -rf `find . -type d -name .svn`
Será mucho más sencillo hacerlo de forma automática desde Eclipse. Para desconectar el proyecto, teniéndolo seleccionado pulsaremos sobre el botón derecho del ratón: Team -> Disconnect.
Adaptación del proyecto
Aunque la estructura por defecto Maven puede ser modificada, es muy recomendable adaptar la organización del proyecto a migrar a la estructura por defecto más generalizada:
Para hacer esta modificación de la estructura hay que tener especial cuidado en algunos aspecto o convenciones Maven:
- Los ficheros de recursos: Maven hace una distinción entre los ficheros de clases java y los ficheros de recursos .properties y XML’s y, de hecho, salvo que le digamos lo contrario, no hará ningún tratamiento de los ficheros no java que se encuentren en el directorio src/main/java. Por este motivo, tendremos que localizar todos los ficheros de recursos (properties, XML’s) que se encuentran en el directorio java y moverlos al directorio resources (src/main/resources).
- Eliminar la carpeta classes. Es muy común que proyectos no Maven tengan en su carpeta WEB-INF/classes los compilados del proyecto. Esta situación no sólo no es recomendable sino que puede producir problemas, por lo que los eliminaremos confiando en Maven para su generación cuando sea necesario.
Definir el pom.xml del proyecto
Una vez que la estructura del proyecto se ha adaptado a la filosofía Maven, el siguiente paso es definir el pom.xml del proyecto.
Partiremos de un fichero pom.xml básico. Este fichero de origen no tiene dependencias; durante el proceso lo adaptaremos y posteriormente iremos refinando la configuración hasta alcanzar una “mavenización” completa del proyecto.
Una vez colocado el pom.xml en el raíz de la aplicación, lo modificamos indicando el nombre del proyecto y la información básica relativa a los desarrolladores, organización y repositorio de dependencias utilizado.
Antes de continuar y añadir las dependencias, podemos hacer una comprobación previa y verificar que efectivamente nuestro IDE, en este caso Eclipse, reconoce correctamente la nueva estructura del proyecto.
Para ello nos vamos a la consola y en el directorio en el que se encuentra nuestro proyecto ejecutamos la siguiente orden:
mvn clean eclipse:eclipse
(Requiere disponer de Maven correctamente instalado en la máquina).
Si la configuración del entorno es correcta, obtendremos una salida similar a esta:
[INFO] Scanning for projects... [INFO] Searching repository for plugin with prefix: 'eclipse'. [INFO] ------------------------------------------------------------------------ [INFO] Building ejemplo [INFO] task-segment: [clean, eclipse:eclipse] [INFO] ------------------------------------------------------------------------ [INFO] [clean:clean] [INFO] Deleting file set: /home/felix/workspaces/ejemplo/target (included: [**], excluded: []) [INFO] Preparing eclipse:eclipse [INFO] No goals needed for project - skipping [INFO] [eclipse:eclipse] [INFO] Adding support for WTP version 1.5. [INFO] Using source status cache: /home/felix/workspaces/ejemplo/target/mvn-eclipse-cache.properties [INFO] File /home/felix/workspaces/ejemplo/.project already exists. Additional settings will be preserved, run mvn eclipse:clean if you want old settings to be removed. [INFO] Wrote Eclipse project for "ejemplo" to /home/felix/workspaces/ejemplo. [INFO] Sources for some artifacts are not available. Please run the same goal with the -DdownloadSources=true parameter in order to check remote repositories for sources. List of artifacts without a source archive: o javax.servlet:servlet-api:2.4 o javax.servlet.jsp:jsp-api:2.1 o junit:junit:3.8.1 [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------ [INFO] Total time: 4 seconds [INFO] Finished at: Wed Sep 3 11:54:28 CET 2008 [INFO] Final Memory: 10M/80M [INFO] ------------------------------------------------------------------------
Nos vamos a Eclipse, refrescamos el proyecto (F5 teniendo seleccionado el proyecto) y comprobamos que la nueva estructura es correcta.
Ahora que hemos comprobado que eclipse ha reconocido la nueva estructura, el siguiente paso es definir en nuestro pom.xml las dependencias. Para hacer esto eliminamos todos los .jar que se encuentran en el directorio /WEB-INF/lib y nos quedamos con una copia de ellos para posteriormente ir resolviendo las dependencias del proyecto original. Una recomendación es cortar la carpeta /WEB-INF/lib a otra ruta de nuestro disco.
Resolución de dependencias
Esta es la fase más delicada del proceso, ya que debemos asegurarnos de que todas las dependencias del proyecto quedan correctamente declaradas en el fichero pom.xml. Para realizar esta tarea es recomendadle utilizar alguna aplicación web que nos ayude a la localización de las librerías, como por ejemplo MvnRepository o MvnBrowser (recomendada), en la que podremos buscar cada uno de nuestros jar y encontrar la definición en el pom.xml que debemos utilizar.
Gracias a esta web, una vez que tengamos localizada la dependencia, solo tendremos que copiar el bloque POM Dependency a nuestro fichero pom.xml.
Iremos repitiendo este proceso de forma iterativa para todos nuestras librerías .jar y añadiendo la definición de la dependencia a nuestra zona de dependencies, con ciertas salvedades y consideraciones que introducimos a continuación.
Consideraciones especiales
Hay ocasiones en las que determinar la definición de la dependencia en nuestro pom.xml puede no ser una tarea trivial. Se comentan a continuación los mecanismos de actuación recomendados según diversas casuísticas:
-
No se indica la versión de la librería en el nombre del fichero.
Por ejemplo, podemos encontrarnos una librería llamada axis-ant.jar, por lo que tendremos que averiguar previamente la versión de la librería de cara a definir la dependencia en el fichero pom.xml. Para esto suele ser muy efectivo descomprimir la librería y consultar el fichero /META-INF/MANIFEST.MF. A modo de ejemplo, en dicha librería mencionada observaríamos una linea similar a la siguiente: “Implementation-Version: 1.2.1 2243 June 14 2005″. Una vez que conozcamos la versión podremos realizar la búsqueda de la forma usual. , 1.1.1.1. Sabemos que la librería fue generada por maven, pero no conocemos su definición.
No conocemos el groupId, artifactId, etc. Podemos descomprimir el .jar y acceder al fichero pom.xml que se encuentra en /META-INF/maven para comprobar el groupId, artifactId y versión de la dependencia.
-
Dependencias especiales JEE.
Algunos jars, como por ejemplo servlet.jar, son aportados por el contenedor de aplicaciones, por lo que tendremos que definirlas marcándolas como provided. Esto le indica a Maven que estas librerías pueden ser utilizadas en tiempo de compilación, pero no serán agregadas al empaquetado final. Para declarar una dependencia de esta forma incorporaremos en nuestro pom.xml un código como este:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
-
Librerías ya consideradas en las dependencias transitivas
Muchas de las dependencias dependen a su vez de otras librerías, por lo que Maven añadirá de forma transitiva nuevas librerías a nuestro proyecto. En estos casos no necesitamos definir estas nuevas dependencias transitivas en nuestro pom.xml. Como ejemplo, supongamos que un proyecto depende de estas librerías:
- xalan-2-6.0.jar
- xercesImpl
- xml-apis
Al buscar la librería xalan-2-6.0.jar, observamos que la librería depende a su vez de las otras dos librerías. Por ello, para este ejemplo bastaría con declarar la dependencia a xalan-2-6.0.jar en nuestro pom.xml. 
-
Conflictos entre librerías
En ocasiones nos podemos encontrar con que dos librerías tengan en sus dependencias a una misma tercera librería, pero de distinta versión. Ello haría que maven incluyese en nuestro Classpath 2 versiones de una misma librería, originando conflictos por duplicado de clases. En ese caso debe declararse en la dependencia de una de ellas una directiva para excluir la descarga de la librería conflictiva.
Por ejemplo, en un proyecto deseamos utilizar la librería siguiente:
<artifactId>jaxws-api</artifactId> <groupId>javax.xml.ws</groupId> <version>2.1-1</version>
Y tenemos dependencia a com.sun.xml.ws / jaxws-rt, esta librería se trae como dependencia transitiva otra versión de la librería mencionada anteriormente. Declaramos una exclusión para evitarlo:
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.1.4</version>
<exclusions>
<exclusion>
<artifactId>jaxws-api</artifactId>
<groupId>javax.xml.ws</groupId>
</exclusion>
</exclusions>
</dependency>
-
Tenemos una librería que se encuentra en los repositorios, pero no hemos podido averiguar el número de versión.
En esta situación, si la librería no parece problemática, podríamos optar por elegir la última versión de la dependencia. En el caso de que consideremos que la versión que utiliza el proyecto puede originar problemas, lo mejor es añadir esta librería manualmente a nuestro repositorio (como si fuese una librería específica del proyecto), según se explica en el próximo punto.
-
La librería es específica del proyecto.
En estos casos tendremos que subir la dependencia a nuestro repositorio de librerías y, para evitar conflictos posteriores, se recomienda que sea subida con el mismo groupId de nuestro proyecto. Supongamos que migrando un proyecto nos topamos con librería example1.jar que no se encuentra en ningún repositorio público. En este caso la subimos a nuestro repositorio por ejemplo con la siguiente definición:
<dependency>
<groupId>com.viavansi.examples</groupId>
<artifactId>example1</artifactId>
<version>0.0.1</version>
</dependency>
En la siguiente figura vemos cómo desplegamos una librería a Artifactory:
Comprobación de dependencias
Una vez que hayamos finalizado este proceso de definición de todas las dependencias en nuestro pom.xml, ejecutaremos en consola mvn dependency:tree (situados en el directorio donde se encuentre el fichero pom.xml del proyecto) para comprobar que las dependencias que se han incorporado al proyecto son las correctas. Este paso de verificación es muy importante en las migraciones de este tipo de proyectos, ya que es muy posible que alguna dependencia transitiva genere problemas. Como ejemplo, podemos observar la siguiente salida en la que comprobamos que no hay dependencias transitivas que entren en conflicto con alguna de nuestras librerías:
[INFO] [dependency:tree]
[INFO] com.viavansi.examples.examples1:war:0.0.1
[INFO] +- junit:junit:jar:3.8.1:test
[INFO] +- javax.servlet.jsp:jsp-api:jar:2.1:provided
[INFO] +- javax.servlet:servlet-api:jar:2.4:provided (scope not updated to compile)
[INFO] +- javax.activation:activation:jar:1.1:compile
[INFO] +- avalon-framework:avalon-framework-impl:jar:4.1.5:compile
[INFO] +- axis:axis-ant:jar:1.2.1:compile
[INFO] +- axis:axis:jar:1.2.1:compile
[INFO] +- javax.mail:mail:jar:1.3.1:compile
[INFO] +- commons-beanutils:commons-beanutils:jar:1.6:compile
[INFO] +- commons-codec:commons-codec:jar:1.3:compile
[INFO] +- commons-collections:commons-collections:jar:3.2:compile
[INFO] +- commons-dbcp:commons-dbcp:jar:1.2.2:compile
[INFO] +- commons-digester:commons-digester:jar:1.6:compile
[INFO] | - xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] +- commons-discovery:commons-discovery:jar:0.2:compile
[INFO] +- commons-httpclient:commons-httpclient:jar:3.1:compile
[INFO] +- commons-io:commons-io:jar:1.3.1:compile
[INFO] +- commons-lang:commons-lang:jar:2.2:compile
[INFO] +- commons-logging:commons-logging:jar:1.1:compile
[INFO] | +- logkit:logkit:jar:1.0.1:compile
[INFO] | - avalon-framework:avalon-framework:jar:4.1.3:compile
[INFO] +- commons-pool:commons-pool:jar:1.3:compile
[INFO] +- displaytag:displaytag:jar:1.1:compile
[INFO] +- displaytag:displaytag-export-poi:jar:1.1:compile
[INFO] +- dom4j:dom4j:jar:1.6.1:compile
[INFO] +- org.extremecomponents:extremecomponents:jar:1.0.1:compile
[INFO] +- com.lowagie:itext:jar:1.4.8:compile
[INFO] +- oro:oro:jar:2.0.7:compile
[INFO] +- javax.xml:jaxrpc-api:jar:1.1:compile
[INFO] +- javax.servlet:jstl:jar:1.1.2:compile
[INFO] +- log4j:log4j:jar:1.2.8:compile
[INFO] +- com.oracle:ojdbc14:jar:9.0.2.0.0:compile
[INFO] +- poi:poi:jar:2.5.1-final-20040804:compile
[INFO] +- javax.xml.soap:saaj-api:jar:1.2:compile
[INFO] +- org.springframework:spring:jar:2.0.5:compile
[INFO] +- taglibs:standard:jar:1.1.2:compile
[INFO] +- struts:struts:jar:1.2.9:compile
[INFO] | +- commons-fileupload:commons-fileupload:jar:1.0:compile
[INFO] | +- commons-validator:commons-validator:jar:1.1.4:compile
[INFO] | - antlr:antlr:jar:2.7.2:compile
[INFO] +- wsdl4j:wsdl4j:jar:1.5.1:compile
[INFO] +- wss4j:wss4j:jar:1.5.0:compile
[INFO] +- xalan:xalan:jar:2.6.0:compile
[INFO] +- org.apache.xmlgraphics:xmlgraphics-commons:jar:1.2:compile
[INFO] +- xml-security:xmlsec:jar:1.2.1:compile
[INFO] +- org.directwebremoting:dwr:jar:2.0.3:compile
[INFO] +- com.viavansi:plantilla-client:jar:0.0.13:compile
[INFO] +- net.sourceforge.barbecue:barbecue:jar:1.5-beta1:compile
En caso de detectar librerías duplicadas a causa de las dependencias transitivas, deberemos proceder a definir las exclusiones necesarias en las dependencias afectadas, según se indicó anteriormente.
Redmine y Subversion (https): no actualiza las revisiones
Hola a todos,
supongo que todos conoceis la fabulosa funcionalidad que tiene Redmine respecto al acceso a un sistema de control de versiones de código fuente, como el caso que nos ocupa: Subversion. Permite consultar las diferentes revisiones, mostrando los distintos comentarios de cada revisión, permite acceder a la estructura en árbol de directorios, etc…
En la situación que os quiero comentar teníamos una instalación de Redmine totalmente funcional, con la conexión a Subversion funcionando a las mil maravillas, vía https. Sin embargo de un día para otro dentro de la pestaña “Repositorio” del proyecto dejamos de ver la estructura de carpetas y ya no se actualizan la información acerca de las sucesivas revisiones que se iban generando en el repositorio, pero sí se veían otras revisiones anteriores.
El primer paso fue mirar en el log de Redmine y se comprobó que se estaba generando un error bastante “inquietante”:
Error parsing svn output: #<REXML::ParseException: No close tag for /lists/list>
…./jruby/lib/ruby/1.8/rexml/parsers/treeparser.rb:27:in `parse’
…./jruby/lib/ruby/1.8/rexml/document.rb:204:in `build’
………………….
………………….
Tras esto, nos conectamos con un cliente subversion y comprobamos que el repositorio estaba totalmente operativo y las revisiones se estaban generando correctamente (incluso con los respectivos comentarios): ¿qué podrá estar pasando? (si quereis ir directo a la solución sólo id al final del post xD)
Como suele ser muy habitual investigamos acerca de la conexión https que se establece con Subversión, ya que en este caso Subversion se sirve vía https. Pues bien, nos dimos cuenta que el certificado del servidor (el que sirve Subversion) estaba caducado: ¡¡ Eureka !!
Para solucionar esto simplemente actualizamos el certificado del servidor Subversion y volvimos a intentar de nuevo consultar la pestaña Repositorio de Redmine, pero no… sigue el mismo problema, no se actualizan las revisiones.
Tras poner nuestras neuronas a trabajar nos dimos cuenta que no habíamos introducido el nuevo certificado como “confiable” para Redmine… muy bien, pero ¿cómo hacer esto? Para explicar esto voy a comentar cómo Redmine se conecta con Subversion y obtiene toda esa metainformación que muestra (esto lo podemos ver en el código fuente de Subversion.rb correspondiente al adaptador de Subversion que tiene Redmine):
Redmine no hace más que ejecutar la orden “svn –xml list <url_repositorio>” y esto devuelve (o debería) un XML con toda la información, algo tan simple como eso ¿cómo puede dar problemas?
Nos disponemos a ejecutar esa misma orden de forma manual desde la máquina donde tenemos instalado Subversion y ¡sorpresa!: no nos retorna un XML correcto. A continuación, ejecutamos un simple comando de listado “svn list <url_repositorio>” y obtenemos un mensaje de aviso, preguntándonos si deseamos rechazar / aceptar de forma permanente o temporal el certificado de https://servidorSubversion . Por supuesto lo aceptamos de forma permanente (pulsando ‘P’) y a continuación nos pidela contraseña del usuario logado en el sistema y usuario/contraseña de acceso a Subversion.
A partir de ahí todo debería funcionar, pero no: hay un pequeño detalle más. Debemos repetir el paso anterior ejecutando el comando “svn”con el mismo usuario que hace correr el servicio de Redmine. Parece que el cliente svn tiene un almacen de certificados “confiables” distinto para cada usuario que lo ejecuta.
Una vez hecho todo esto nuestro Redmine se conecta perfectamente con Subversion y obtiene toda la información actualizada.
SOLUCION.- A continuación os resumo la solución con un par de pasos que se deben seguir, espero que os resulten útiles.
- Ejecutar por consola el comando “svn list <url_subversion>” en la máquina en que corre Redmine y con el mismo usuario que hace correr el servicio.
- En el diálogo que se muestra: aceptar el certificado como confiable de manera permanente (‘P’) e introducir los uusuarios/contraseñas que se solicitan.
- Ejecutar por consola el comando “svn –xml list <url_subversion>” y comprobar ahora que sí nos devuelve un XML con todos los metadatos.
- Comprobar que Redmine nos muestra ahora los datos correctos.
Versión de Redmine utilizada: Redmine 0.8.0.stable
Personalmente creo que este tipo de “errores” se deberían reportar de forma automática por parte de Redmine (mostrando una información más intuitiva) y es de esperar que en futuras versiones tomen en cuenta todos las numerosas incidencias que podeis ver en el bugtracker del proyecto Redmine respecto a este error.
Un Saludo a todos.
Namaste y buena suerte.











