我在一个由大约40名开发人员组成的团队中工作,我不希望任何开发人员使用某些特定的API(精确地说是java.sun.Base64)供任何开发人员使用,而是让他们使用替代方案sun API作为其专有。
是否有maven的插件,通过这些插件,在pom.xml中指定受限制的包,如果在代码中的任何地方使用任何这些包,构建将会中断?
或者有更优雅的方法吗?
由于
答案 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中使用的依赖项。