Maven插件限制使用特定包

时间:2011-09-19 07:39:58

标签: java maven maven-plugin maven-3

我在一个由大约40名开发人员组成的团队中工作,我不希望任何开发人员使用某些特定的API(精确地说是java.sun.Base64)供任何开发人员使用,而是让他们使用替代方案sun API作为其专有。

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

或者有更优雅的方法吗?

由于

8 个答案:

答案 0 :(得分:8)

您希望为项目定义架构规则,最好通过源代码分析来强制执行。

Sonar现在可以指定such rules并在项目质量信息中心上显示违规行为。如果您希望构建中断,可以另外启用Sonar的Build breaker插件。

Sonar非常容易设置并集成到您的Maven构建过程中,而对您的POM零更改。

答案 1 :(得分:7)

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

答案 2 :(得分:6)

这是我为类似目的而写的插件。

详情可见:https://github.com/yamanyar/restrict-maven-plugin/wiki

限制从com.ya *到java.util.regex。*

的所有访问权限
<restriction>com.ya* to java.util.regex.*</restriction>

将com.ya *(com.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>

答案 3 :(得分:1)

我不知道有一个Maven插件可以做到这一点,但我想你可以用方面做类似的事情(因此使用Maven / Aspectj插件)。 Aspectj具有可能有用的declare error结构。如果它检测到使用禁用类的切入点,则会引发错误。

另外http://www.eclipse.org/aspectj/doc/released/progguide/semantics-declare.html#warnings-and-errors

这种方法的一个限制是静态分析,因此无法捕获您的类/包黑名单的任何“聪明”调用。

答案 4 :(得分:1)

您可以检查类加载器中加载了哪些类,如果从java.sun.Base64中找到某些内容,则会引发错误。

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

答案 5 :(得分: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文件夹中,插件就会在类路径中找到它。

答案 6 :(得分:0)

这个建议与“优雅”相反;它是一个完全的kluge:它可能很简单,可以在构建的进程源阶段编写一些内容......你可以(例如)用一些(无效的Java)文本替换“sun.Base64”的任何情况表明问题。这会导致构建至少失败。

答案 7 :(得分:0)

一个简单的选择可以是使用父母&#39; pom用于定义所有第三方罐子,其版本为“依赖管理”。部分并在儿童poms中使用它们。尽管这个模型并没有否定特定jar的使用,但PM或架构师将有一种简单的方法来管理依赖关系。完成后,我们可以简单地告诉开发人员只使用父pom中使用的依赖项。