Analíza la calidad de tu código Java con Sonar 2.0

2 Comments

Sonar es un proyecto OpenSource de codehaus.org para analizar la calidad tu código en Java con diferentes tipos de métricas, solo funciona con proyectos construidos con Maven2.

Para descargar el proyecto http://sonar.codehaus.org/downloads/

La Instalación es bien sencilla, primero debes descomprimir el ZIP que descargaste y modificar el archivo sonar.properties:

#---------------------------------------------------------
# WEB
# THESE SETTINGS ARE USED ONLY IN STANDALONE MODE. IGNORED WHEN THE WAR IS DEPLOYED ON A JEE SERVER.
#---------------------------------------------------------
# Listen host/port and context path (for example / or /sonar). Default values are 0.0.0.0:9000/
#sonar.web.host:                           0.0.0.0
sonar.web.port:                           8080
#sonar.web.context:                        /

La primera propiedad se refiere al IP donde tienes instalado el sonar, el segundo el puerto y la tercera propiedad el contexto en tomcat o jboss, si estamos trabajando con virtualhost no creo que haga falta que pongas un contexto.

#----- MySQL 5.x/6.x
# Comment the embedded database and uncomment the following lines to use MySQL
sonar.jdbc.url:                                      jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8
sonar.jdbc.driverClassName:                   com.mysql.jdbc.Driver
sonar.jdbc.validationQuery:                     select 1
 
#----- Global database settings
sonar.jdbc.username:                              sonar
sonar.jdbc.password:                              sonar
sonar.jdbc.maxActive:                             10
sonar.jdbc.maxIdle:                                 5
sonar.jdbc.minIdle:                                  2
sonar.jdbc.maxWait:                                5000
sonar.jdbc.minEvictableIdleTimeMillis:        600000
sonar.jdbc.timeBetweenEvictionRunsMillis:   30000

En mi caso decidi conectarlo con MySQL aunque por defecto unsa una base de datos local en Derby, debes comentar las lineas de derby y descomentar la base de datos que tu eligas, hay buen menú donde elegir, y tal vez modificar datos como el usuario y la contraseña de conexión a la bd.

Llega la hora de crear el war, en la carpeta war, corres el comando build-war.sh y publicas en tu contenedor web para java el proyecto.

El tercer paso y mas importante es la configuracion en settings.xml en Maven2, en tu repositorio local.

  <profile>
        <id>sonar</id>
        <activation>
                <activeByDefault>true</activeByDefault>
        </activation>
                <properties>
                <sonar.jdbc.url>jdbc:mysql://localhost:3306/sonar</sonar.jdbc.url>
                <sonar.jdbc.driver>com.mysql.jdbc.Driver</sonar.jdbc.driver>
                <sonar.jdbc.username>sonar</sonar.jdbc.username>
                <sonar.jdbc.password>password</sonar.jdbc.password>
                <sonar.host.url>http://tudominio:8080</sonar.host.url>
                </properties>
        </profile>
  </profiles>

Esta sección se agrega en la parte de PROFILES en settings.xml en Maven2. Con esto lograremos que nuestro proyecto pueda publicarse en Sonar.

Ahora, la parte mas sencilla, navegas al path de tu proyecto y corres el comando siguiente,

         mvn sonar:sonar

y el resto es pan comido, en este proceso Sonar analizara tu código y creará las métricas en el portal. Algo como lo siguiente.
http://nemo.sonarsource.org/

Problemas entre Spring 3.0 y Spring Web Flow 2.0.8

1 Comment

Hace unos dias intentando integrar Spring Security 3.0 con Spring Web Flow en su última version 2.0.9 al día de hoy, como en el ejemplo siguiente.

   <bean id="securityFlowExecutionListener" class="org.springframework.webflow.security.SecurityFlowExecutionListener" />
 
   <webflow:flow-executor id="flowExecutor" flow-registry="flowRegistry">
        <webflow:flow-execution-listeners>
            <webflow:listener ref="securityFlowExecutionListener" />
        </webflow:flow-execution-listeners>
    </webflow:flow-executor>

Esta configuracion en Web Flow basicamente lo que hace es que podamos restringir ciertas vistas o flujos enteros en base a Roles con Spring Security

 <secured attributes="ROLE_USER"/>
 
<view-state id="main">
        <on-render>
            <render fragments="zona3"/>
        </on-render>
        <transition on="paso1" to="reviewHotels">
              <secured attributes="ROLE_EDITOR"/>
             <evaluate expression="bean.metodo1()" />
             <render fragments="zona1"/>
        </transition>
        <transition on="paso2" >
              <secured attributes="ROLE_ADMIN"/>
             <evaluate expression="bean.metodo2() />
             <render fragments="zona1"/>
        </transition>
    </view-state>

y obtenia este error al compilar.

Caused by: java.lang.ClassNotFoundException: org.springframework.security.vote.AffirmativeBased
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233)
... 65 more

Pero parece no tener solución por ahora salvo que tu apliques el parche publicado en JIRA hace unos dias.

Aunque hoy mismo publicaron que el parche saldria hasta la versión Spring Web Flow 2.1 y no en la 2.0.9 como hace 48 horas estaba publicado.

https://jira.springsource.org/browse/SWF/fixforversion/11441

En pocas palabras, a esperar.

Configurando Spring Security 3.0 y actualizando con Maven

1 Comment

Vamos con algo sencillo el día de hoy. Ante la llegada hace unos meses ya de Spring Security 3.0 y con estupendas novedades y sus cambios.

Si ya has migrado te habrás dado cuenta que muchos de los nombres de los paquetes han cambiado.

import org.springframework.security.Authentication;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.context.SecurityContextImpl;
import org.springframework.security.providers.openid.OpenIDAuthenticationStatus;
import org.springframework.security.providers.openid.OpenIDAuthenticationToken;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UserDetailsService;

antes se llamaban

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.openid.OpenIDAuthenticationStatus;
import org.springframework.security.openid.OpenIDAuthenticationToken;

No solo estas clases han cambiado, en mi migración de hace unos dias me encontre que con el 70% de las clases que usaba habian sido cambiadas, fue todo un dolor de cabeza al principio.

Nota: no te olvides de agregar los filtros en el web.xml eso no ha cambiado para nada en la 3.0.

Actualizando con Maven

Yo ahora mismo estoy trabajando con la versión 3.0.2.RELEASE y es bastante estable aunque tiene un bug con la integración en Spring Web Flow.

El uso de propiedades en Maven es muy recomendable, si mañana quieres actualizar a otra versión es mucho mas comodo cambiar en un solo lugar, existen muchos otros JAR disponibles en Spring Security como (CAS, ASL o Spring Web) que tambien puedes agregar como dependencia, segun tus necesidades.

 
 <properties>
    <spring.security.version>3.0.2.RELEASE</spring.security.version>
 </properties>
 
<dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-config</artifactId>
      <version>${spring.security.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-core</artifactId>
      <version>${spring.security.version}</version>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-ldap</artifactId>
      <version>${spring.security.version}</version>
    </dependency>
  <dependency>
    <groupId>org.springframework.security</groupId>
    <artifactId>spring-security-openid</artifactId>
    <version>${spring.security.version}</version>
    <scope>compile</scope>
  </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-taglibs</artifactId>
      <version>${spring.security.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.security</groupId>
      <artifactId>spring-security-web</artifactId>
      <version>${spring.security.version}</version>
</dependency>

Otra cosa que debes modificar o agregar si es una nueva configuración es en los namespaces.

 
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.0.xsd">
</beans>

Configuración Mínima

Spring Security 3.0 nos permite desde una configuración sencilla hasta las mas completas, según la documentacion esto es lo mínimo que necesitas.
En este caso se podria llamar una versión amateur de la configuración real con beans en Spring Security, ellos nos ofrecen este una version resumida de la configuracion, siendo la mínima lo siguiente

 
<http auto-config='true'>
  <intercept-url pattern="/**" access="ROLE_USER" />
</http>

Y pudiendose extender a algo mas complejo (complejo dentro de la sencille) como:

  <security:http auto-config="false"
                 entry-point-ref="authenticationEntryPoint"
                 access-decision-manager-ref="voteAccessDecisionManager" >
    <security:intercept-url pattern="/**" access="ENCUESTAME_ANONYMOUS" />
    <security:intercept-url pattern="/admon/**/*" access="ENCUESTAME_ADMIN" />
    <security:intercept-url pattern="/tweet/" access="ENCUESTAME_ANONYMOUS" />
    <security:intercept-url pattern="/" access="ENCUESTAME_ANONYMOUS" />
    <security:intercept-url pattern="/**/*.xhtml" filters="none" />
    <security:intercept-url pattern="/**/*.css"  filters="none" />
    <security:intercept-url pattern="/images/**" filters="none" />
    <security:intercept-url pattern="/js/**" filters="none" />
    <security:remember-me key="12345" services-alias="_rememberMeServices" />
    <security:anonymous key="12345" />
    <security:logout logout-success-url="/index.html" logout-url="/logout"/>
    <security:custom-filter position="FORM_LOGIN_FILTER" ref="authenticationFilter" />
    <security:custom-filter position="ANONYMOUS_FILTER"  ref="anonymousAuthFilter" />
  </security:http>

Para aprender algo más sobre los multiples filtros que ofrece Spring Security en versiones anteriores, en este mismo blog postee algunos artículos.