2011-09-19 9 views
8

Trabajo en un equipo de alrededor de 40 desarrolladores, y no quiero que ningún desarrollador use alguna API específica (java.sun.Base64 para ser precisos) para ser utilizada por cualquiera de los desarrolladores y más bien les hacen usar alternativas a la API solar como su propiedad.Plugin de Maven para restringir la utilización de paquetes específicos

¿Hay algún complemento para maven, mediante el cual, especificando los paquetes restringidos en el pom.xml, la compilación se romperá si alguno de esos paquetes se utiliza en algún lugar del código?

¿O hay una manera más elegante de hacer esto?

Gracias

Respuesta

8

desea definir una regla de arquitectura para su proyecto, que es mejor cumplir por análisis de código fuente.

Sonar ahora tiene la capacidad de especificar such rules y mostrar violaciones en el tablero de calidad del proyecto. Si quieres que la construcción se rompa, esto también se puede hacer habilitando el complemento Build breaker de Sonar.

Sonar es realmente fácil de configurar y se integra en su proceso de construcción Maven con cero cambio en su POM.

+0

Esta es una solución realmente agradable ... – Neeraj

1

No estoy al tanto de un plugin de Maven para hacer esto, pero me imagino que podría hacer con aspectos similares (y, por tanto, utilizar el plugin de Maven/Aspectj). Aspectj tiene la construcción declare error que puede ser útil. Esto puede generar un error si detecta un corte de punto que usa sus clases prohibidas.

también http://www.eclipse.org/aspectj/doc/released/progguide/semantics-declare.html#warnings-and-errors

Una limitación de este enfoque es que es un análisis estático y por lo tanto no será capaz de atrapar cualquier invocación 'inteligente' de la clase/paquete de lista de negro.

+0

¿Por qué sería útil utilizar aspectos para esto? Esto se puede capturar en tiempo de compilación/compilación y listo. –

1

Puede verificar qué clases están cargadas en su cargador de clases y generar un error si encuentra algo de java.sun.Base64.

Esto parece funcionar: http://www.javaworld.com/javaworld/javaqa/2003-07/02-qa-0725-classsrc2.html

+0

¿No será esto en tiempo de ejecución? – Neeraj

+0

Sí, esto es solo una solución para su problema. – iuiz

+0

Esto parece una solución, pero preferiría uno que no permita que la compilación se ejecute en absoluto en caso de que se utilicen clases restringidas. – Neeraj

0

Esta sugerencia es lo opuesto a "elegante"; es un kluge total: podría ser lo suficientemente simple como para escribir algo para poner en la fase de creación de las fuentes de proceso ... podría (por ejemplo) reemplazar cualquier caso de "sun.Base64" con algún texto (Java no válido) indicando el problema Esto causaría que la construcción fallara al menos.

1

Aquí hay un código de regla de prueba de concepto para PMD/Maven PMD plugin. (Las clases restringidas estén codificadas en el constructor, pero es posible que sea configurable a través de propiedades.)

import java.util.Collections; 
import java.util.LinkedList; 
import java.util.List; 

import net.sourceforge.pmd.AbstractJavaRule; 
import net.sourceforge.pmd.ast.ASTClassOrInterfaceType; 
import net.sourceforge.pmd.ast.ASTName; 
import net.sourceforge.pmd.ast.SimpleJavaNode; 

public class PackageRestrictionRule extends AbstractJavaRule { 

    private final List<String> disallowedPackages; 

    public PackageRestrictionRule() { 
     final List<String> disallowedPackages = new LinkedList<String>(); 
     disallowedPackages.add("org.apache."); 
     this.disallowedPackages = Collections 
       .unmodifiableList(disallowedPackages); 
    } 

    @Override 
    public Object visit(final ASTClassOrInterfaceType node, 
      final Object data) { 
     checkPackage(node, data); 
     return super.visit(node, data); 
    } 

    @Override 
    public Object visit(final ASTName node, final Object data) { 
     checkPackage(node, data); 
     return super.visit(node, data); 
    } 

    private void checkPackage(final SimpleJavaNode node, 
      final Object data) { 
     final String image = node.getImage(); 
     if (isDisallowedPackage(image)) { 
      addViolationWithMessage(data, node, 
        "Disallowed class or package: " + image); 
     } 
    } 

    private boolean isDisallowedPackage(final String packageName) { 
     for (final String disallowedPackageName : disallowedPackages) { 
      if (packageName.startsWith(disallowedPackageName)) { 
       return true; 
      } 
     } 
     return false; 
    } 
} 

Crear un nuevo proyecto Maven para ello, y utilizar este proyecto como una dependencia del plugin PMD en su proyecto:

<plugin> 
    <groupId>org.apache.maven.plugins</groupId> 
    <artifactId>maven-pmd-plugin</artifactId> 
    <version>2.5</version> 
    <configuration> 
     <targetJdk>1.6</targetJdk> 
     <rulesets> 
      <ruleset>packagerestrictionrule.xml</ruleset> 
     </rulesets> 
    </configuration> 
    <dependencies> 
     <dependency> 
      <groupId>...</groupId> 
      <artifactId>PackageRestrictionRule</artifactId> 
      <version>0.0.1-SNAPSHOT</version> 
     </dependency> 
    </dependencies> 
</plugin> 

Además, el complemento PMD necesita un archivo XML de conjunto de reglas adecuado para la clase de regla. Hay un ejemplo en el sitio web de PMD: http://pmd.sourceforge.net/howtowritearule.html. Simplemente colóquelo en la carpeta src/main/resources en su proyecto PackageRestrictionRule y el complemento lo encontrará en classpath.

+0

esta es también una solución inteligente, pero el sonar internamente usa PMD para generar las clases de PMD para mí, supongo. (O al menos dice que usa herramientas PMD, así que supongo que hace eso para arquitectura rulesets) – Neeraj

6

mirada a this:

<plugin> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>macker-maven-plugin</artifactId> 
     <version>1.0.0-SNAPSHOT</version> 
     <executions> 
      <execution> 
      <phase>compile</phase> 
      <goals> 
       <goal>macker</goal> 
      </goals> 
      </execution> 
     </executions>  
     </plugin> 

donde se define la regla de no permitir la importación de java.lang.System

<?xml version="1.0"?> 
<macker>  
    <ruleset name="Testing rules"> 
     <pattern name="mypackage" class="org.codehaus.mojo.**" /> 
     <access-rule> 
      <message>System out is bad. Use logging instead.</message> 
      <deny> 
       <to> 
        <include class="java.lang.System" /> 
       </to> 
      </deny> 
      <!--allow> 
       <from pattern="blah" /> 
      </allow--> 
     </access-rule> 
    </ruleset> 
</macker> 
+1

Enlace roto a partir de 2015-06-17. Esto funciona: https://innig.net/macker/guide/basic.html – Gorkamorka

+0

Parece que hay un fork más actualizado aquí: https://github.com/andrena/macker-maven-plugin – seanf

6

Aquí es plug-in que escribí para fines similares.

detalles se pueden ver aquí: https://github.com/yamanyar/restrict-maven-plugin/wiki

restringir todo el acceso desde com.ya * a * java.util.regex

<restriction>com.ya* to java.util.regex.*</restriction> 

restringir todo el acceso desde com.ya * (excepto com.. yamanyar.core. ) a java.util.regex.,

<restriction>com.ya*,!com.yamanyar.core.* to java.util.regex.*</restriction> 

restringir todo el acceso desde com.ya * (excepto com.yamanyar.core. ) y com.abc.Test a java.util.regex.

<restriction>com.ya*,com.abc.Test,!com.yamanyar.core.* to java.util.regex.*</restriction>

restringir todo el acceso desde com.ya * (excepto com.yamanyar.core. ) y com.abc.Test a java.util.regex. (excepto java.util.regex.Matcher) <restriction>com.ya*,com.abc.Test,!com.yamanyar.core.* to java.util.regex.*,!java.util.regex.Matcher</restriction>

restringir todo el acceso desde com.ya * (excepto com.yamanyar.core. ) y com.abc.Test a java.util.regex. (excepto java.util.regex.Matcher); y también restringir com.ya * (excepto com.yamanyar.core. ) a java.io.PrintStre .print *()

<restriction>com.ya*,com.abc.Test,!com.yamanyar.core.* to java.util.regex.*,!java.util.regex.Matcher</restriction> 
<restriction>com.ya*,!com.yamanyar.core* to java.io.PrintStre*.print*()</restriction> 
0

Una opción simple puede ser el uso de un 'padre' para definir POM todas las jarras de terceros con versiones en la sección 'Dependency Management' y utilícelas en poms para niños. Aunque este modelo no niega el uso de un contenedor en particular, el PM o el arquitecto tendrán una manera fácil de administrar las dependencias. Una vez hecho esto, podemos simplemente decirles a los desarrolladores que usen solo las dependencias usadas en el pom padre.

Cuestiones relacionadas