Maven插件限制使用的特定软件包
我在一个由大约40位开发人员组成的团队中工作,我不希望任何开发人员使用某些特定的API(准确地说是java.sun.Base64)以供任何开发人员,而是让他们使用sun API的替代品作为其专有的。Maven插件限制使用的特定软件包
是否有任何maven插件,通过它,在pom.xml中指定受限制的包,如果任何这些包在代码中的任何位置被使用,构建将会中断?
还是有更优雅的方式来做到这一点?
感谢
你要定义为您的项目,这是最好的源代码分析执行建筑规则。
Sonar现在有能力指定such rules并在项目的质量仪表板上显示违规。如果你想让构建破坏,可以额外使用Sonar的Build breaker插件。
Sonar非常易于安装和集成到您的Maven构建过程中,而无需更改您的POM。
我不知道Maven插件来做到这一点,但我想你可以做相似之处(因此使用Maven/AspectJ的插件)。 Aspectj有declare error构造,可能有用。如果它检测到使用禁止类的切入点,则会引发错误。
而且,这种方法的http://www.eclipse.org/aspectj/doc/released/progguide/semantics-declare.html#warnings-and-errors
一个限制是它是一个静态的分析,因此将无法赶上你的类/包黑名单中的任何“聪明”的调用。
为什么使用这个方面有所帮助?这可以在构建/编译时捕获并完成。 –
您可以检查在您的类加载器中加载了哪些类,并在发现java.sun.Base64中的某些内容时引发错误。
这似乎工作:http://www.javaworld.com/javaworld/javaqa/2003-07/02-qa-0725-classsrc2.html
这个建议与“优雅”相反;它是一个彻头彻尾的概念:它可能足够简单,可以编写一些东西放入构建的流程源代码阶段......您可以(例如)用一些(无效的Java)文本替换“sun.Base64”的任何情况表明问题。这会导致构建至少失败。
下面是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文件夹中,插件就可以在类路径中找到它。
这也是一个聪明的解决方案,但是声纳内部使用PMD为我生成PMD类(或者至少它说它使用PMD工具,所以我猜测它适用于建筑规则集) – Neeraj
看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>
链接截至2015-06-17断开。这工作:https://innig.net/macker/guide/basic.html – Gorkamorka
这里似乎有一个更新的叉:https://github.com/andrena/macker-maven-plugin – seanf
进口这里是插件我写了类似的目的。
详细信息可以在这里看到: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>
一个简单的选项可以是使用一个 '父' POM,以限定所有你的第三方罐子在“依赖管理”部分有版本,并在孩子的生活中使用它们。尽管这个模型并不否认特定jar的使用,但PM或架构师将有一个简单的方法来管理依赖关系。一旦完成,我们可以简单地告诉开发人员只使用父pom中使用的依赖关系。
这是一个非常不错的解决方案... – Neeraj