Gradle 和嵌套的非传递依赖项

PVo*_*Lan 5 android gradle build.gradle android-gradle-plugin

这是一个测试项目:点击

\n\n

我有一个测试 Gradle Android 项目,包含三个模块:applibrary_alibrary_bapp取决于library_a,则library_a取决于library_b

\n\n

构建.gradle(应用程序)

\n\n
dependencies {\n    ...\n    compile (project(":library_a")){\n        transitive = false;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

构建.gradle(library_a)

\n\n
dependencies {\n    ...\n    compile (project(":library_b")){\n        transitive = false;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

请注意,我设置是transitive = false因为我不希望从library_b以下位置访问类app

\n\n

每个模块只有一个类,代码非常简单:

\n\n

应用程序:

\n\n
public class MainActivity extends Activity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        //...\n        ClassA classA = new ClassA();\n        classA.doSomething();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

库_a:

\n\n
public class ClassA\n{\n    public void doSomething(){\n        Log.i("Test", "Done A!");\n\n        ClassB classB = new ClassB();\n        classB.doSomething();\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

库_b:

\n\n
public class ClassB\n{\n    public void doSomething(){\n        Log.i("Test", "Done B!");\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

好吧,问题是:我正在使用 gradlew 构建我的项目。Apk 已成功编译,但当我运行它时,出现 NoClassDefFoundError。

\n\n
I/Test\xef\xb9\x95 Done A!\nE/AndroidRuntime\xef\xb9\x95 FATAL EXCEPTION: main\n    java.lang.NoClassDefFoundError: ru.pvolan.library_b.ClassB\n            at ru.pvolan.somelibrary.ClassA.doSomething(ClassA.java:12)\n            ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果我transitive = true在两个 .gradle 文件中进行设置,它运行正常,但是,正如我上面提到的,我不希望依赖关系是可传递的,因为我不希望 ClassB 可以从 MainActivity 访问 - 只能从 ClassA 访问。

\n\n

我究竟做错了什么?

\n

Mar*_*ira 0

问题是这library_b是必需的依赖项。您不能简单地排除它,因为您需要它在运行时位于类路径上。为了强制执行代码约定,您实际上歪曲了实际的依赖关系,因此失去了利用 Gradle 等依赖关系管理系统的任何优势。如果您想强制执行类或包黑名单,我建议使用 PMD 等源分析工具。以下是将特定类列入黑名单的规则示例。

如果由于某种原因这是不可能的,您可以通过简单地添加library_bapp.

dependencies {
    runtime project(':library_b')
}
Run Code Online (Sandbox Code Playgroud)