有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在共享相互依赖关系的同时合并源集

我想发布一个包含两个不同API版本的库,其中两个版本下面都使用相同的核心代码。我尝试了着色/阴影,但在获得正确的可见性方面遇到了困难(我想对API用户隐藏核心代码)。因此,我希望通过使用不同的源代码集和配置来实现我的目标:

sourceSets {
    // the `main` source set acts as the common code base for `api` and `api2`

    api {
        java {
            srcDir 'src/api/java'
            // Includes classes from `main`:
            compileClasspath += sourceSets.main.output
            runtimeClasspath += sourceSets.main.output
        }
    }
    api2 {
        java {
            srcDir 'src/api2/java'
            // Includes classes from `main`:
            compileClasspath += sourceSets.main.output
            runtimeClasspath += sourceSets.main.output
        }
    }
}

configurations {
    common {
        canBeResolved = true
        canBeConsumed = false
    }

    // These art the configurations used both for being consumed with `project(...)` or published:
    exposedApi {
        canBeResolved = true
        canBeConsumed = true
        extendsFrom common
    }
    exposedApi2 {
        canBeResolved = true
        canBeConsumed = true
        extendsFrom common
    }
}

task apiJar(type: Jar) {
    group = 'build'
    from configurations.exposedApi
    baseName = 'api'
}

task api2Jar(type: Jar) {
    group = 'build'
    from configurations.exposedApi2
    baseName = 'api2'
}

publishing {
    publications {
        api(MavenPublication) {
            artifact apiJar
            artifactId 'mylib-api'
        }
        api2(MavenPublication) {
            artifact api2Jar
            artifactId 'mylib-api2'
        }

    }
}

dependencies {
    common sourceSets.main.output
    exposedApi sourceSets.api.output
    exposedApi2 sourceSets.api2.output
}

如果我想使用这些API中的一个,我可以很容易地使用project(path: ':mylib', configuration: 'exposedApi2')或使用一个已发布的Maven工件,并且工作得很好

但只要我将main源集中的类更改为internal以实现main代码的正确封装,API代码就不会再编译了:

Cannot access 'SomeClassInMain': it is internal in '' (<-- yes, it really shows nothing in the '')

我还尝试将源集合并为一个,因此从技术上讲,不再存在main源集:

sourceSets {
    api {
        java {
            srcDirs('src/api/java', 'src/main/java')
        }
    }
    api2 {
        java {
            srcDirs('src/api2/java', 'src/main/java')
        }
    }
}

现在一切正常,没有编译错误,从API到main的调用按预期工作,main中的类甚至具有internal可见性。但不幸的是,IntelliJ似乎没有意识到main中的类实际上是同一源集中的一部分这一事实。每次我从main源代码中提到一个类时,我都会在IDE中得到一个错误(Unresolved reference: SomeClassInMain),当然,自动完成也不起作用,这使得解决方案最终不太实用

因此,总结一下目标:

  • API可以访问main源代码,这一点很重要
  • 但对于使用API(或Maven出版物)的用户来说,这是不可能的——用户唯一应该面对的是API
  • 如果可能的话,我不希望将API和主代码放在单独的模块中,并出于封装的原因单独发布它们
  • 我尝试了一种着色/阴影(fat/uber-JAR)方法,但我没有设法降低main源中internal的可见性
  • 我不熟悉这些复杂的构建配置,所以我可能只是选择了错误的方法。也许我还没找到更好的

非常非常感谢


共 (0) 个答案