2011-09-19 72 views
8

我在一个由大约40位开发人员组成的团队中工作,我不希望任何开发人员使用某些特定的API(准确地说是java.sun.Base64)以供任何开发人员,而是让他们使用sun API的替代品作为其专有的。Maven插件限制使用的特定软件包

是否有任何maven插件,通过它,在pom.xml中指定受限制的包,如果任何这些包在代码中的任何位置被使用,构建将会中断?

还是有更优雅的方式来做到这一点?

感谢

回答

8

你要定义为您的项目,这是最好的源代码分析执行建筑规则。

Sonar现在有能力指定such rules并在项目的质量仪表板上显示违规。如果你想让构建破坏,可以额外使用Sonar的Build breaker插件。

Sonar非常易于安装和集成到您的Maven构建过程中,而无需更改您的POM。

+0

这是一个非常不错的解决方案... – Neeraj

1

我不知道Maven插件来做到这一点,但我想你可以做相似之处(因此使用Maven/AspectJ的插件)。 Aspectj有declare error构造,可能有用。如果它检测到使用禁止类的切入点,则会引发错误。

而且,这种方法的http://www.eclipse.org/aspectj/doc/released/progguide/semantics-declare.html#warnings-and-errors

一个限制是它是一个静态的分析,因此将无法赶上你的类/包黑名单中的任何“聪明”的调用。

+0

为什么使用这个方面有所帮助?这可以在构建/编译时捕获并完成。 –

1

您可以检查在您的类加载器中加载了哪些类,并在发现java.sun.Base64中的某些内容时引发错误。

这似乎工作:http://www.javaworld.com/javaworld/javaqa/2003-07/02-qa-0725-classsrc2.html

+0

不会在运行时? – Neeraj

+0

是的,这只是解决您的问题的一种解决方法。 – iuiz

+0

这看起来像是一个解决方案,但我更喜欢一个不允许构建完成的应用程序,因为根本就没有受限制的类。 – Neeraj

0

这个建议与“优雅”相反;它是一个彻头彻尾的概念:它可能足够简单,可以编写一些东西放入构建的流程源代码阶段......您可以(例如)用一些(无效的Java)文本替换“sun.Base64”的任何情况表明问题。这会导致构建至少失败。

1

下面是PMD/Maven PMD plugin的概念验证规则代码。 (受限制类硬编码在构造函数中,但它可以使配置的通过性能。)

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; 
    } 
} 

为它创建一个新的Maven项目,并以此项目为PMD插件的依赖您的项目:

<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> 

此外,PMD插件需要适用于规则类的规则集XML文件。 PMD网站上有一个例子:http://pmd.sourceforge.net/howtowritearule.html。只需将它放到PackageRestrictionRule项目的src/main/resources文件夹中,插件就可以在类路径中找到它。

+0

这也是一个聪明的解决方案,但是声纳内部使用PMD为我生成PMD类(或者至少它说它使用PMD工具,所以我猜测它适用于建筑规则集) – Neeraj

6

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> 

其中规则规定不允许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

链接截至2015-06-17断开。这工作:https://innig.net/macker/guide/basic.html – Gorkamorka

+0

这里似乎有一个更新的叉:https://github.com/andrena/macker-maven-plugin – seanf

6

进口这里是插件我写了类似的目的。

详细信息可以在这里看到:https://github.com/yamanyar/restrict-maven-plugin/wiki

限制从com.ya *所有访问的java.util.regex *

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

限制从com.ya *所有访问(除融为一体。 yamanyar.core。)转换为java.util.regex。

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

限制从com.ya *所有访问(除com.yamanyar.core。)和com.abc.Test到java.util.regex中。

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

限制从com.ya *所有访问(除com.yamanyar.core。)和com.abc.Test到java.util.regex中。(除java.util.regex.Matcher中)<restriction>com.ya*,com.abc.Test,!com.yamanyar.core.* to java.util.regex.*,!java.util.regex.Matcher</restriction>

限制从com.ya *所有访问(除com.yamanyar.core。)和com.abc.Test到java.util.regex中。(java.util.regex.Matcher除外);并且还限制com.ya *(除com.yamanyar.core。)至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

一个简单的选项可以是使用一个 '父' POM,以限定所有你的第三方罐子在“依赖管理”部分有版本,并在孩子的生活中使用它们。尽管这个模型并不否认特定jar的使用,但PM或架构师将有一个简单的方法来管理依赖关系。一旦完成,我们可以简单地告诉开发人员只使用父pom中使用的依赖关系。