繁体   English   中英

如何在我的文件系统上添加一个 java gradle 项目作为对另一个本地项目的依赖?

[英]How do I add a java gradle project on my file system as a dependency to another local project?

我有依赖于 project1 的 project2。 它们在我的文件系统上彼此相邻。

当我尝试构建 project2(成功构建 project1 之后)时,出现错误:

Could not determine the dependencies of task ':app:distTar'.
> Could not resolve all task dependencies for configuration ':app:runtimeClasspath'.
   > Could not resolve project :project1.
     Required by:
         project :app
      > No matching configuration of project :project1 was found. The consumer was configured to find a runtime of a library compatible with Java 11, packaged as a jar, preferably optimized for standard JVMs, and its dependencies declared externally but:
          - None of the consumable configurations have attributes.

Project2 将依赖项添加到 project1 如下...

build.gradle

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java application project to get you started.
 * For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
 * User Manual available at https://docs.gradle.org/7.2/userguide/building_java_projects.html
 */

plugins {
    // Apply the application plugin to add support for building a CLI application in Java.
    id 'application'
}

repositories {
    // Use Maven Central for resolving dependencies.
    mavenCentral()
}

dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13.2'

    // This dependency is used by the application.
    implementation 'com.google.guava:guava:30.1.1-jre'

    implementation project(':project1')
    implementation files('../../project1/lib/build/libs/lib.jar')
}

application {
    // Define the main class for the application.
    mainClass = 'project2.App'
}

设置.gradle

rootProject.name = 'project2'
include('app')

include   ':project1'
project(':project1').projectDir = new File(settingsDir, '../project1')

project1 的来源...

/*
 * This Java source file was generated by the Gradle 'init' task.
 */
package project1;

public class Library {
    public boolean someLibraryMethod() {
        return true;
    }
}

project2 的来源

/*
 * This Java source file was generated by the Gradle 'init' task.
 */
package project2;

import project1.*;

public class App {
    public String getGreeting() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        System.out.println(new App().getGreeting());
        bool someBool = Library.someLibraryMethod();
    }
}

两个项目的完整文件夹结构。 虽然看起来project2 在project1 下,但复制粘贴的output 看起来就是这样,它们确实是兄弟文件夹。

── project1
│   ├── gradle
│   │   └── wrapper
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── lib
│   │   ├── bin
│   │   │   ├── main
│   │   │   │   └── project1
│   │   │   │       └── Library.class
│   │   │   └── test
│   │   │       └── project1
│   │   │           └── LibraryTest.class
│   │   ├── build

│   │   │   ├── libs
│   │   │   │   └── lib.jar

│   │   ├── build.gradle
│   │   └── src
│   │       ├── main
│   │       │   ├── java
│   │       │   │   └── project1
│   │       │   │       └── Library.java
│   │       │   └── resources
│   │       └── test
│   │           ├── java
│   │           │   └── project1
│   │           │       └── LibraryTest.java
│   │           └── resources
│   └── settings.gradle
└── project2
    ├── app
    │   ├── build.gradle
    │   └── src
    │       ├── main
    │       │   ├── java
    │       │   │   └── project2
    │       │   │       └── App.java
    │       │   └── resources
    │       └── test
    │           ├── java
    │           │   └── project2
    │           │       └── AppTest.java
    │           └── resources
    ├── gradle
    │   └── wrapper
    │       ├── gradle-wrapper.jar
    │       └── gradle-wrapper.properties
    ├── gradlew
    ├── gradlew.bat
    └── settings.gradle

69个目录,37个文件

首先,您必须确定这是多项目构建还是复合构建

  • 如果这两个项目高度耦合(即同一概念项目的两个模块),那么您应该使用多项目构建。

    我没有在此答案中包含多项目构建的示例。

  • 如果这两个项目彼此相对独立,但一个项目像任何其他依赖项一样依赖另一个项目,那么您可以考虑复合构建。

    下面是一个复合构建的示例。


示例组合构建

至少有两种方法可以将一个构建包含在另一个构建中。

  1. 在命令行上使用--include-build

  2. settings.gradle[.kts]中使用includeBuildinclude ;用于多项目构建)。

    • 有一个这样的版本,您可以在其中创建一个“伪”父项目,其唯一目的是定义一个仅包含所需“真实”构建的settings.gradle[.kts]文件。 这样一来,您就不必使用 --include --include-build或修改一个或多个“真实”项目的 Gradle 文件。 这里

此示例使用--include-build 我还使用了 Kotlin DSL,但如果您愿意的话,转换为 Groovy DSL 应该不会太困难。

我的示例没有声明任何repositories ,但这并不意味着您不能这样做。 如果您并不总是想包含一个构建,但仍想使用该其他构建的已发布二进制文件(或者,当然,如果您有其他依赖项),则可能需要这样做。 这是关于依赖项如何在复合构建中工作的注释:

包含的构建通过依赖替换与其他构建交互。 如果组合中的任何构建具有可以由包含的构建满足的依赖性,那么该依赖性将被包含构建的项目依赖性所取代。 由于依赖于依赖替换,复合构建可能会强制在组合任务执行图时更早地解析配置。 这会对整体构建性能产生负面影响,因为这些配置不是并行解析的

项目一

这是“项目 1”的来源,它依赖于“项目 2”。

设置.gradle.kts

rootProject.name = "project1"

build.gradle.kts :

plugins {
    application
}

group = "sample.project1"
version = "1.0"

application {
    mainClass.set("sample.project1.Main")
}

dependencies {
    implementation("sample.project2:project2:1.0")
}

主要.java

package sample.project1;

import sample.project2.Greeter;

public class Main {
    
    public static void main(String[] args) {
        Greeter.greet();
    }
}

项目2

这是“项目 2”的来源。

设置.gradle.kts

rootProject.name = "project2"

build.gradle.kts :

plugins {
    `java-library`
}

group = "sample.project2"
version = "1.0"

问候语.java

package sample.project2;

public class Greeter {
    
    public static void greet() {
        System.out.println("Hello, this is a composite build!");
    }
}

项目结构

这是两个项目的布局(它们在同级目录中):

...\DEMO
├───project1
│   │   build.gradle.kts
│   │   gradlew
│   │   gradlew.bat
│   │   settings.gradle.kts
│   │
│   ├───gradle
│   │   └───wrapper
│   │           gradle-wrapper.jar
│   │           gradle-wrapper.properties
│   │
│   └───src
│       └───main
│           └───java
│               └───sample
│                   └───project1
│                           Main.java
│
└───project2
    │   build.gradle.kts
    │   gradlew
    │   gradlew.bat
    │   settings.gradle.kts
    │
    ├───gradle
    │   └───wrapper
    │           gradle-wrapper.jar
    │           gradle-wrapper.properties
    │
    └───src
        └───main
            └───java
                └───sample
                    └───project2
                            Greeter.java

运行项目 1

这是在包含项目 2 的同时运行项目 1 的示例:

...\demo\project1> .\gradlew run --include-build ..\project2

> Task :run
Hello, this is a composite build!

如何修改代码

鉴于您似乎想要一个复合构建,您需要进行一些更改。 例如,声明对包含构建的依赖看起来就像声明对任何其他外部工件的依赖(即,它使用 Maven 坐标):

dependencies {
    // Use JUnit test framework.
    testImplementation 'junit:junit:4.13.2'

    // This dependency is used by the application.
    implementation 'com.google.guava:guava:30.1.1-jre'

    // REPLACE WITH REAL groupID, artifactID, AND version
    implementation 'com.example:project1:1.0'
}

然后项目 2 的settings.gradle文件应该如下所示:

rootProject.name = 'project2'

或者,如果您不想使用--include-build

rootProject.name = 'project2'

includeBuild '../project1'

使目录project1project2都是模块,一个应用程序和一个库模块。 文件gradlegradlewgradlew.batsettings.gradle需要向上移动一级。 根项目需要它自己的build.gradle settings.gradle中包含模块很简单:

include ':project1'
include ':project2'

然后可以依赖模块:project1中的模块:project2

dependencies {
    testImplementation project(':project2')
    api project(':project2')
}

该库也可以发布到默认的本地存储库mavenLocal() 除非发布源代码 package 到 Maven(例如lib-sources.jar ),否则使用两个模块进行调试通常更容易。 库模块仍然可以做成一个 Git 子模块。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM