miércoles, 12 de enero de 2011

Maven 3.0.2 disponible

Hoy se libero la version de mantenimiento 3.0.2 de Apache Maven. A continuacion la lista de cambios:


Release Notes - Maven 2 & 3 - Version 3.0.2

Bug

  • [MNG-4840] - Prerequisites is not working on m3
  • [MNG-4913] - [regression] User properties override equally named POM properties of transitive dependencies
  • [MNG-4915] - Versions in pom.xml are not checked for invalid characters
  • [MNG-4918] - MavenProject#clone() doubles active profiles
  • [MNG-4919] - Plugin execution contributed by lifecycle mapping gets lost when same goal is bound multiple times
  • [MNG-4923] - [regression] java.lang.ClassNotFoundException: org.apache.maven.artifact.ArtifactStatus
  • [MNG-4925] - Mismanagement of container lookup realm can cause type incompatibilities for plugins looking up components by string
  • [MNG-4933] - With a resource directory as . maven raise an java.lang.StringIndexOutOfBoundsException:217
  • [MNG-4941] - PluginDescriptorBuilder doesn't populate expression/default-value fields for mojo parameters
  • [MNG-4952] - [regression] RELEASE field of repository metadata is not updated upon repeated deployments
  • [MNG-4955] - [regression] Outdated remote snapshots are preferred over locally installed snapshots
  • [MNG-4960] - [regression] Make-like reactor mode does not build selected project when resuming from one of its prerequisites
  • [MNG-4966] - Preserve double slashes in the scm connection url - identifies absolute repository paths for mercurial

Improvement

  • [MNG-4912] - Use of raw type should be Comparable<ArtifactVersion>
  • [MNG-4916] - Poor ProjectBuilder.build performance for projects with unresolvable extension plugins
  • [MNG-4922] - ExecutionEvent give on the exception encountered (when having mojoFailed)
  • [MNG-4926] - ExecutionEvent give on the exception encountered (when having projectFailed , forkedProjectFailed)
  • [MNG-4944] - Include JRE vendor in version info
  • [MNG-4950] - Javadoc improvements to DefaultSettingsWriter/Reader
  • [MNG-4953] - Issue a warning when a system-scope dependency refers to the project basedir

New Feature

  • [MNG-4936] - Allow to better monitor and adjust a Maven build during CI
  • [MNG-4937] - Allow the platform scripts to avoid loading mavenrc content

Task

  • [MNG-4945] - Remove mergeId from public POM
  • [MNG-4957] - Emit validation warning when project version uses irregular SNAPSHOT version string
  • [MNG-4959] - Update default plugin versions

--
Francisco Herrera

jueves, 18 de noviembre de 2010

Sonar 2.4 disponible

Ya fue liberada la versión 2.4 de Sonar, la excelente herramienta open source para análisis de código fuente. Entre las mejoras están soporte para actualización de plugins desde la misma herramienta (Update Center) y un nuevo diseño del dashboard basado en widgets el cual permite seleccionar el layout y los widgets a mostrar. Para ver la lista completa de cambios y descargar la versión deben ir a la siguiente pagina.

miércoles, 10 de noviembre de 2010

Servicios REST con Spring - Usando RestTemplate

Después de haber visto unos demos bien interesante del soporte que le da Spring al tema de servicios web en SpringOne 2GX 2010,  decidí hacer una prueba para ver si de verdad es tan sencillo. La primera prueba es tratar de consumir algún servicio REST usando RestTemplate. Como el nombre lo indica, esta clase es una implementación del patrón template orientada a procesar servicios REST, ya Spring nos tiene acostumbrados con este mecanismo con clases como JDBTemplate o JMSTemplate.
Para poder arrancar el demo lo primero es conseguir o implementar un servicio REST de tal forma de poder consumirlo. En mi caso voy a aprovechar que tengo instalado Sonatype Nexus el cual se encarga de exponer algunos servicios. La documentación de los servicios de nexus es casi inexistente al momento pero buscando por internet encontre algunos uri. Para las pruebas voy a usar el que retorna el estado de la instancia.

http://your.company.com/nexus/service/local/status

El cual devuelve un xml con la siguiente estructura (el xml es mas extenso, solo deje la parte que me interesa)

<status>
  <data>
 <appName>Sonatype Nexus Maven Repository Manager</appName>
 <formattedAppName>Sonatype Nexus&trade; Open Source Edition, Version: 1.8.0</formattedAppName>
 <version>1.8.0</version>
 <apiVersion>1.8.0</apiVersion>
 <editionLong>Open Source</editionLong>
 <editionShort>OSS</editionShort>
 <state>STARTED</state>
 <operationMode>STANDALONE</operationMode>
 <initializedAt>2010-10-26 12:28:06.732 EDT</initializedAt>
 <startedAt>2010-10-26 12:28:17.334 EDT</startedAt>
 <lastConfigChange>2010-10-26 12:28:17.334 EDT</lastConfigChange>
 <firstStart>false</firstStart>
 <instanceUpgraded>false</instanceUpgraded>
 <configurationUpgraded>false</configurationUpgraded>
  </data>
</status>

Antes de escribir cualquier clase creo el pom.xml de maven con las dependencias respectivas

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>neptuno.demo.spring</groupId>
 <artifactId>demo-spring-rest</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>jar</packaging>
 <name>demo-spring-rest</name>
 <url>http://maven.apache.org</url>
 <build>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.3.2</version>
    <configuration>
     <source>1.5</source>
     <target>1.5</target>
    </configuration>
   </plugin>
  </plugins>
 </build>
 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
  <org.logback.version>0.9.26</org.logback.version>
 </properties>
 <dependencies>
  <!-- Dependencias para Rest Template -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${org.springframework.version}</version>
  </dependency>
  <dependency>
   <groupId>org.springframework.ws</groupId>
   <artifactId>spring-xml</artifactId>
   <version>1.5.9</version>
  </dependency>
  <!-- Dependencias para pruebas unitarias -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-test</artifactId>
   <version>${org.springframework.version}</version>
   <scope>test</scope>
  </dependency>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>4.8.2</version>
   <scope>test</scope>
  </dependency>
  <!-- Dependencias para logging -->
  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-api</artifactId>
   <version>1.6.1</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-core</artifactId>
   <version>${org.logback.version}</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>${org.logback.version}</version>
  </dependency>
 </dependencies>
</project>

El siguiente paso es crear un bean con la representación del xml

public class NexusStatus {

 private String appName;
 private String formattedAppName;
 private String version;
 private String apiVersion;
 private String editionLong;
 private String editionShort;
 private String state;
 private String operationMode;
 private String initializedAt;
 private String startedAt;
 private String lastConfigChange;

  // Generar todos los getters y setter

 @Override
 public String toString() {
  StringBuilder builder = new StringBuilder();
  builder.append("NexusStatus [appName=");
  builder.append(appName);
  builder.append(", formattedAppName=");
  builder.append(formattedAppName);
  builder.append(", version=");
  builder.append(version);
  builder.append(", apiVersion=");
  builder.append(apiVersion);
  builder.append(", editionLong=");
  builder.append(editionLong);
  builder.append(", editionShort=");
  builder.append(editionShort);
  builder.append(", state=");
  builder.append(state);
  builder.append(", operationMode=");
  builder.append(operationMode);
  builder.append(", initializedAt=");
  builder.append(initializedAt);
  builder.append(", startedAt=");
  builder.append(startedAt);
  builder.append(", lastConfigChange=");
  builder.append(lastConfigChange);
  builder.append("]");
  return builder.toString();
 }
}

Como en todas las aplicaciones de Spring, el archivo de configuración es el que se encarga de hacer la mayoría de la magia. Para este ejemplo el archivo de spring lo denomine nexus-spring.xml y esta ubicado en la carpeta resources

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

 <context:component-scan base-package="neptuno.demo.spring.rest" />

 <bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
  <property name="messageConverters">
   <list>
    <bean
     class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
   </list>
  </property>
 </bean>

 <bean id="xpathTemplate" class="org.springframework.xml.xpath.Jaxp13XPathTemplate" />

 <bean id="nexusStatusNodeMapper" class="neptuno.demo.spring.rest.NexusStatusNodeMapper" />

</beans>

En este archivo se definen 3 bean y se agrega una instruccion especial para Spring

  • La entrada component-scan apunta al paquete que debe ser evaluado por Spring para buscar clases con anotaciones. 
  • restTemplate es una instancia de Spring RestTemplate indicando que el convertidor del cuerpo del mensaje es la clase SourceHttpMessageConverter.  Esta clase convierte entre request/response http y javax.xml.transform.Source, de esta forma se puede recibir la respuesta de Nexus y procesarla como xml.
  • xpathTemplate es usado para convertir entre Source y el bean NexusStatus, en este caso usando JAXP 1.3
  • nexusStatusNodeMapper implementa org.springframework.xml.xpath.NodeMapper. Es similar al row mapper de JDBCTemplate y se usa para convertir un nodo del xml al objeto NexusStatus
La clase que se encarga de utilizar toda la definición anterior es la siguiente

/**
 * 
 */
package neptuno.demo.spring.rest;

import javax.xml.transform.Source;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.xml.xpath.Jaxp13XPathTemplate;
import org.springframework.xml.xpath.NodeMapper;

@Component("nexusRestAccess")
public class NexusRestAccess {

 private static Logger logger = LoggerFactory
   .getLogger(NexusRestAccess.class);

 @Autowired
 private RestTemplate restTemplate;

 @Autowired
 private Jaxp13XPathTemplate xpathTemplate;

 @Autowired
 private NodeMapper nexusStatusNodeMapper;

 /**
  * Obtiene el estado de la instancia de Nexus
  * 
  * @return
  */
 public NexusStatus getNexusStatus() {
  Source source = restTemplate.getForObject(
    "http://my.company.com/nexus/service/local/status",
    Source.class);
  return (NexusStatus) xpathTemplate.evaluateAsObject("//data", source,
    nexusStatusNodeMapper);
 }

 public static void main(String[] args) {
  ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
    "/nexus-spring.xml");
  NexusRestAccess demo = applicationContext.getBean("nexusRestAccess",
    NexusRestAccess.class);
  NexusStatus status = demo.getNexusStatus();
  logger.info(status.toString());
 }
}


Como ven la clase usa anotaciones para indicarle a Spring que debe inyectar. La linea

Source source = restTemplate.getForObject(
   "http://my.company.com/nexus/service/local/status",
   Source.class);

invoca el servicio remoto y devuelve el resultado en un objeto tipo Source. Después se utiliza xpathTemplate para convertirlo a NexusSource. Uno de los parametros de xpathTemplate es el mapper definido en el archivo de Spring. El código de la clase es el siguiente


/**
 * 
 */
package neptuno.demo.spring.rest;

import org.springframework.xml.xpath.NodeMapper;
import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class NexusStatusNodeMapper implements NodeMapper {

 /**
  * (non-JSDoc)
  * 
  * @see org.springframework.xml.xpath.NodeMapper#mapNode(org.w3c.dom.Node,
  *      int)
  */
 @Override
 public Object mapNode(Node node, int i) throws DOMException {
  NexusStatus newStatus = new NexusStatus();
  NodeList children = node.getChildNodes();
  for (int j = 0; j < children.getLength(); j++) {
   Node n = children.item(j);
   if ("appName".equals(n.getNodeName())) {
    newStatus.setAppName(n.getTextContent());
   } else if ("version".equals(n.getNodeName())) {
    newStatus.setVersion(n.getTextContent());
   } else if ("formattedAppName".equals(n.getNodeName())) {
    newStatus.setFormattedAppName(n.getTextContent());
   } else if ("apiVersion".equals(n.getNodeName())) {
    newStatus.setApiVersion(n.getTextContent());
   } else if ("state".equals(n.getNodeName())) {
    newStatus.setState(n.getTextContent());
   } else if ("editionLong".equals(n.getNodeName())) {
    newStatus.setEditionLong(n.getTextContent());
   } else if ("editionShort".equals(n.getNodeName())) {
    newStatus.setEditionShort(n.getTextContent());
   } else if ("operationMode".equals(n.getNodeName())) {
    newStatus.setOperationMode(n.getTextContent());
   } else if ("initializedAt".equals(n.getNodeName())) {
    newStatus.setInitializedAt(n.getTextContent());
   } else if ("startedAt".equals(n.getNodeName())) {
    newStatus.setStartedAt(n.getTextContent());
   } else if ("lastConfigChange".equals(n.getNodeName())) {
    newStatus.setLastConfigChange(n.getTextContent());
   }
  }
  return newStatus;
 }

}


Por ultimo ejecutamos el metodo main() de la clase NexusRestAccess la cual invoca el servicio y muestra por consola el objeto NexusStatus


Nov 10, 2010 3:56:13 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1add2dd: startup date [Wed Nov 10 15:56:13 EST 2010]; root of context hierarchy
Nov 10, 2010 3:56:13 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [nexus-spring.xml]
Nov 10, 2010 3:56:16 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1bc82e7: defining beans [nexusRestAccess,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,restTemplate,xpathTemplate,nexusStatusNodeMapper]; root of factory hierarchy

15:56:19.798 [main] INFO  n.demo.spring.rest.NexusRestAccess - NexusStatus [appName=Sonatype Nexus Maven Repository Manager, formattedAppName=Sonatype Nexus&trade; Open Source Edition, Version: 1.8.0, version=1.8.0, apiVersion=1.8.0, editionLong=Open Source, editionShort=OSS, state=STARTED, operationMode=STANDALONE, initializedAt=2010-10-26 12:28:06.732 EDT, startedAt=2010-10-26 12:28:17.334 EDT, lastConfigChange=2010-10-26 12:28:17.334 EDT]


También podemos agregar una pequeña prueba unitaria para probar el código
package neptuno.demo.spring.rest;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

@ContextConfiguration(locations = { "/nexus-spring.xml" })
public class NexusRestAccessTest extends AbstractJUnit4SpringContextTests {

 private NexusRestAccess demo;

 @Before
 public void setup() {
  demo = applicationContext.getBean("nexusRestAccess",
    NexusRestAccess.class);
 }

 @Test
 public void testNexusStatus() {
  NexusStatus status = demo.getNexusStatus();
  Assert.assertNotNull(status);
  Assert.assertTrue(status.getAppName().indexOf("Sonatype") >= 0);
 }

}

Como ven es bien sencillo consumir servicios REST usando Spring RestTemplate. Esta clase no solo soporta consultas (GET) sino también los otros métodos (PUT, DELETE, POST, etc). Para mas informaición revisen la documentación.

jueves, 21 de octubre de 2010

Opera 11 alpha introcude extensiones

Hoy Opera libero la versión 11 alpha de su browser para desktops la cual introduce mas opciones de personalización de las que ya existen (Widgets, Unite, etc.). En este caso se agrego soporte a extensiones las cuales, segun opera, son estándar y se podrían usar en cualquier browser. Adicionalmente se sigue agregando soporte a HTML5, introduciendo websockets, y por ultimo se mejoro el performance actualizando el motor Presto a la versión 2.6.37.

Para probar esta versión usen este enlace.

jueves, 14 de octubre de 2010

Sonar 2.3 disponible

Ya esta disponible la versión 2.3 de Sonar. Para descargarlo usen este enlace. Es bueno que revisen las notas de actualización asi como la matriz de compatibilidad de los plugins.



Release Notes - Sonar - Version 2.3

Bug

  • [SONAR-343] - When a rule is removed from the repository, it should be remove from the DB as well
  • [SONAR-440] - Warning when some rules are not imported from a checkstyle and/or PMD configuration file(s)
  • [SONAR-942] - Export rules configuration fails when quality profile name contains the '.' character
  • [SONAR-1073] - Column "RULE_FAILURES"."MESSAGE" is too short (maximum : 500)
  • [SONAR-1137] - When no rule engine exist on a language, all other rules are shown on the screen
  • [SONAR-1315] - Automatically filter Findbugs violations and Code coverage metrics on classes without sources
  • [SONAR-1342] - The pluginKey associated to an active rule can be wrong
  • [SONAR-1480] - No way to export Findbugs rules in a XML file and then to reimport this file to create a new Quality profile
  • [SONAR-1549] - The Sonar profile creation form doesn't allow to import checkstyle,pmd and Findbugs conf files when several langages are defined
  • [SONAR-1637] - Getting "Java inner classes are not supported" Sonar error when analyzing Cobertura report
  • [SONAR-1638] - Warning while parsing enums
  • [SONAR-1644] - A protected method from a class A which is only used by classes extended A are badly considered as dead code.
  • [SONAR-1654] - Export rules in rules engine exports everything (Java, PHP, VB...) when you select any in plugins
  • [SONAR-1666] - Some Findbugs violations are missing in the Sonar web interface
  • [SONAR-1685] - The maven plugin fails if the property sonar.host.url ends with a slash
  • [SONAR-1687] - Filters fail when three criteria are defined
  • [SONAR-1689] - Sorting on alerts does not work anymore
  • [SONAR-1693] - Server-side extensions can not use external dependencies
  • [SONAR-1697] - XML default property values are not correctly displayed in the Settings pages
  • [SONAR-1702] - NoClassDefFoundError when using sonar-ws-client with Commons HttpClient 4.0
  • [SONAR-1712] - Fail to delete a filter if embedded database
  • [SONAR-1715] - Web Services Java Client lib : socket timeout not set
  • [SONAR-1721] - Checkstyle violation is reported for MethodParamPad since Sonar seems to be missing option in rule
  • [SONAR-1727] - Warning when aggregating empty distributions
  • [SONAR-1736] - Description of the Checkstyle "Visibility Modifier" rule is error prone
  • [SONAR-1738] - NPE in EmbeddedDatabaseFactorywhen using JNDI datasource
  • [SONAR-1751] - The method org.sonar.gwt.Utils.getPageWidth() returns 0 in IE6
  • [SONAR-1753] - Time Machine chart is not secured
  • [SONAR-1758] - Unit test EventUnmarshallerTest on ws-client module can fail according to the timezone of the machine
  • [SONAR-1767] - Violations do not show when using id instead of kee in violation drilldown to reference rule
  • [SONAR-1768] - Import of Checkstyle configuration with "message" element fails
  • [SONAR-1774] - AbstractTokenizer does not add token entries
  • [SONAR-1793] - Wrong URL construction in ViolationQuery, when depth parameter used
  • [SONAR-1802] - Can't import FindBugs profile when some rules are duplicated in the findbugs.xml configuration file
  • [SONAR-1805] - The PMD rule CloneMethodMustImplementCloneable is badly configured in the Sonar Way quality profile (and so not activated in this default profile)
  • [SONAR-1812] - The declaration @BelongsTo(classes=GeneratesViolations.class) does not work
  • [SONAR-1813] - If the method DecoratorContext.getViolations() is called by a decorator before the ViolationsDecorator, all violations saved between those two decorators are lost
  • [SONAR-1833] - treemap ignores fractional part of metrics
  • [SONAR-1843] - The webservice /api/properties fails when requested format is XML

Improvement

  • [SONAR-236] - Checkstyle implementation only allows one check per Checkstyle class
  • [SONAR-555] - Permalink on Time Machine charts
  • [SONAR-736] - Reuse findbugs reports
  • [SONAR-964] - Multiple Regexp hard to distinguish
  • [SONAR-990] - Add an option to activate/deactivate all the selected rules of the profile admin console
  • [SONAR-1024] - Improve the rules search engine by displaying the number of results for not selected rule level (Inactive rule)
  • [SONAR-1290] - Improve SQL requests on the Q profiles page
  • [SONAR-1328] - Ability to personalize the CheckStyle SuppressionCommentFilter and SuppressWithNearbyCommentFilter modules
  • [SONAR-1404] - Allow to rename quality profile
  • [SONAR-1534] - Activation of all the default FindBugs rules
  • [SONAR-1557] - Findbugs should not analyzed *.jar files stored in the target/classes directory
  • [SONAR-1607] - Missing FindBugs rules
  • [SONAR-1634] - Defining a new metric with existing key results in confusing message
  • [SONAR-1641] - Exclude certain member variables (esp. logger instances) from the LCOM4 calculation
  • [SONAR-1665] - Upgrade to Commons DBCP 2.3
  • [SONAR-1669] - Add info about JDBC driver in the System Info page
  • [SONAR-1670] - Upgrade the MySql driver from version 5.1.6 to 5.1.13
  • [SONAR-1674] - Log user agent in Jetty logs
  • [SONAR-1698] - Remove the "Translation" Checkstyle rule as it works only on property files
  • [SONAR-1701] - API: search profile rules by config key
  • [SONAR-1706] - Depreciate sonar.reuseExistingRulesConfiguration
  • [SONAR-1745] - Add URL parameters to time machine charts
  • [SONAR-1747] - Add the ability to instantiate a new KeywordColorizer with a regular expression
  • [SONAR-1749] - MavenPlugin api, offer way to build nested xml-elements
  • [SONAR-1757] - Improve the error log message when a "javax.persistence.NonUniqueResultException" is thrown
  • [SONAR-1761] - Missing example in the ConstructorCallsOverridableMethod PMD rule description
  • [SONAR-1763] - Optional generation of the Checkstyle XML report
  • [SONAR-1776] - Add a page "Permalinks" to the profile console
  • [SONAR-1778] - Missing description for some system plugins
  • [SONAR-1780] - An exception should be thrown in case when two Sonar plugins try to use the same key
  • [SONAR-1781] - The use of org.sonar.api.batch.AbstractSourceImporter is error prone when importing Unit Test source code
  • [SONAR-1798] - Ability to register a number of points to a rule violation
  • [SONAR-1814] - New extension point : factory of extensions
  • [SONAR-1822] - Add the property 'sonar.skipTendencies' to skip calculation of measure tendencies

New Feature

  • [SONAR-738] - Honor Checkstyle Suppressions XML Document
  • [SONAR-1229] - Export/Import a given Sonar quality profile
  • [SONAR-1709] - Add static resources to plugins
  • [SONAR-1766] - Create a new PMD XPath rule and let user duplicate this rule as often as necessary

viernes, 8 de octubre de 2010

Maven 3 disponible!!!!

Hoy fue liberado por Sonatype la versión 3.0 de Maven.  Para descargarlo usen este enlace. La gente de Sonatype indica que los proyectos usando versión 2 deberían funcionar sin problemas con la 3 pero es bueno revisar la tabla de compatibilidad para estar seguros. La tabla esta en este enlace.

C:\>mvn -version
Apache Maven 3.0 (r1004208; 2010-10-04 07:50:56-0400)
Java version: 1.6.0_14
Java home: C:\Program Files\Java\jdk1.6.0_14\jre
Default locale: en_US, platform encoding: Cp1252
OS name: "windows xp" version: "5.1" arch: "x86" Family: "windows"

jueves, 19 de agosto de 2010

Revisando el arbol de dependecias de un proyecto con Maven

Para ver el árbol de dependencias de un proyecto usando maven solo debemos usar el plugin dependency y ejecutar el comando

mvn dependency:tree

Ejemplo:



Si usan Eclipse y tienen el plugin m2eclipse pueden también ver el árbol  así como el gráfico de dependencias