我有一个android gradle项目结构,如下所示
关键事实
基于module1-aar
没有javadocs、gpg、签名或发布,一切都很好。应用程序运行,一切都很好。
当我开始添加任务以生成javadocs时,一切都变得一团糟。module1-aar将构建和生成没有问题的javadocs。然而,module2-aar在javadoc任务期间总是失败。
任务在下面。大部分都是从这里借来的How to generate javadoc for android library when it has dependencies which are also aar libraries?
project.task("javadoc", type: Javadoc) {
afterEvaluate {
configurations.all
.each {item ->
item.setCanBeResolved(true)
}
classpath += configurations.api
classpath += configurations.implementation
// Wait after evaluation to add the android classpath
// to avoid "buildToolsVersion is not specified" error
classpath += files(android.getBootClasspath())
// Process AAR dependencies
def aarDependencies = classpath.filter { it.name.endsWith('.aar') }
classpath -= aarDependencies
//fails here when an AAR depends on an AAR
aarDependencies.each { aar ->
// Extract classes.jar from the AAR dependency, and add it to the javadoc classpath
def outputPath = "$buildDir/tmp/aarJar/${aar.name.replace('.aar', '.jar')}"
classpath += files(outputPath)
// Use a task so the actual extraction only happens before the javadoc task is run
dependsOn task(name: "extract ${aar.name}").doLast {
extractEntry(aar, 'classes.jar', outputPath)
}
}
}
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
classpath += project.files(android.getBootClasspath())
classpath += configurations.implementation
classpath += fileTree(dir: project.buildDir.absolutePath + "/tmp/aarsToJars/")
classpath += files(project.buildDir.absolutePath + "/intermediates/compile_r_class_jar/release/R.jar")
classpath += files(project.buildDir.absolutePath + "/generated/source/buildConfig/release/release")
classpath += files(project.buildDir.absolutePath + "/generated/source/r/buildConfig/release/release")
destinationDir = file( project.buildDir.absolutePath + "/outputs/javadoc/")
failOnError true
options.charSet 'UTF-8'
options.docEncoding 'UTF-8'
options.encoding 'UTF-8'
options.addBooleanOption 'Xdoclint:none', true
exclude '**/BuildConfig.java'
exclude '**/R.java'
exclude '**/doc-files/*'
}
// Utility method to extract only one entry in a zip file
private def extractEntry(archive, entryPath, outputPath) {
if (!archive.exists()) {
throw new GradleException("archive $archive not found")
}
def zip = new java.util.zip.ZipFile(archive)
zip.entries().each {
if (it.name == entryPath) {
def path = new File(outputPath)
if (!path.exists()) {
path.getParentFile().mkdirs()
// Surely there's a simpler is->os utility except
// the one in java.nio.Files? Ah well...
def buf = new byte[1024]
def is = zip.getInputStream(it)
def os = new FileOutputStream(path)
def len
while ((len = is.read(buf)) != -1) {
os.write(buf, 0, len)
}
os.close()
}
}
}
zip.close()
}
//wires in the javadoc task to the normal build
tasks.named("build") { finalizedBy("generateJavadocJar") }我得到的错误消息如下
* What went wrong:
A problem occurred configuring project ':module2-aar'.
> Could not resolve all files for configuration ':module2-aar:implementation'.
> Could not resolve project :module1-aar.
Required by:
project :module2-aar
> Cannot choose between the following variants of project :module1-aar:
- debugRuntimeElements
- releaseRuntimeElements
All of them match the consumer attributes:
- Variant 'debugRuntimeElements' capability com.github.test:module1-aar:6.1.11-SNAPSHOT:
- Unmatched attributes:
- Provides com.android.build.api.attributes.AgpVersionAttr '7.1.3' but the consumer didn't ask for it
- Provides com.android.build.api.attributes.BuildTypeAttr 'debug' but the consumer didn't ask for it
- Provides com.android.build.gradle.internal.attributes.VariantAttr 'debug' but the consumer didn't ask for it
- Provides org.gradle.usage 'java-runtime' but the consumer didn't ask for it
- Variant 'releaseRuntimeElements' capability com.github.test:module1-aar:6.1.11-SNAPSHOT:
- Unmatched attributes:
- Provides com.android.build.api.attributes.AgpVersionAttr '7.1.3' but the consumer didn't ask for it
- Provides com.android.build.api.attributes.BuildTypeAttr 'release' but the consumer didn't ask for it
- Provides com.android.build.gradle.internal.attributes.VariantAttr 'release' but the consumer didn't ask for it
- Provides org.gradle.usage 'java-runtime' but the consumer didn't ask for it我一直在玩gradle任务,似乎每当我试图在模块2-AAR的类路径上迭代时,就会生成错误消息。
我尝试了许多其他建议,比如将模块2-AAR的依赖声明从
api project(':module2-aar')至
api project(path:':module2-aar')不过,这没什么用
我也试过这个:
api project(path: ':module1-aar', configuration: 'default')虽然上述方法解决了所报告的问题,但它会导致编译问题,在compile...and期间,模块2-AAR在类路径中似乎没有模块1-AAR-它似乎在模块1-AAR之前编译。
不幸的是,当引用android项目时,configuration意味着什么的文档太少了,或者我找错地方了。我不知道还有哪些其他的有效值可用。
总之,我不知道这里有什么问题,只是我花了太多的时间在这上面。
发布于 2022-06-09 18:18:04
我将发布解决在javadoc中使用"aar“文件的问题的解决方案。在试图解决这个问题的过程中,我也得到了间谍所指的同样的错误。这个错误实际上意味着它可以区分它应该使用的是发布库还是调试库。在我看来,试图纠正这个问题是徒劳的,因此,我采取了一种不同的方法来解决我认为本质上相同的问题。
在我的例子中,我有一个包含多个子项目的项目,当我生成我的javadoc文档时,我想要生成一个合并的javadoc文档,它只包含一些子项目(不是所有的子项目)。据我所知,这并不是Android Studio内置的一种功能。目前版本的Android (2021.2.1)似乎在为android库模块生成javadoc文档时遇到了问题。有两个问题:
1.)javadoc类路径没有添加android引导类。在引用任何android方法时都会出现错误,例如“上下文”、“字体”等。
2.)javadoc类路径没有添加任何AndroidX库。许多AndroidX库都是"aar“文件。当使用javadoc时,Android (2021.2.1)不能正确处理aar文件。
我的环境类似于间谍,只不过我使用的是android插件7.2.0。我在"app“模块的build.gradle.kts脚本中创建了一个定制的javadoc任务。我的“应用”模块是一个android应用程序模块。代码需要放在包含插件"com.android.application“或"com.android.library”的任何模块中。我为合并的javadoc生成的一些模块是java库,这是可以的。
// create a custom configuration
val javadocDeps = configurations.create("javadocDeps")
// add javadoc dependencies that you need.
dependencies {
javadocDeps(project(":OsgiFramework"))
// note: I'm using a libs version catalog for the dependencies
// you can add hardwired dependencies if you prefer
javadocDeps (libs.androidx.appcompat)
javadocDeps (libs.androidx.fragment)
javadocDeps (libs.androidx.navigation.fragment)
javadocDeps (libs.androidx.navigation.ui)
javadocDeps (libs.androidx.constraint.layout)
}
// register the createCoreJavadoc task
// in my case, "gradlew app:createCoreJavadoc" creates the merged javadoc
tasks {
register<Javadoc>("createCoreJavadoc") {
setFailOnError(true)
val docDir: File = File(project.projectDir.parentFile.parentFile, "Doc/Core")
println("javadoc destination dir: " + docDir.absolutePath)
// set the location where the documentation is produced in
setDestinationDir(docDir)
// select the projects to produce merged javadoc for
var sourcepaths: FileCollection = project(":CoreInterfaces").files("src/main/java")
sourcepaths =
sourcepaths.plus(project(":CoreInternalInterfaces").files("src/main/java"))
sourcepaths = sourcepaths.plus(project(":CoreAndroidInterfaces").files("src/main/java"))
sourcepaths =
sourcepaths.plus(project(":CoreAndroidInternalInterfaces").files("src/main/java"))
sourcepaths = sourcepaths.plus(project(":OsgiInterface").files("src/main/java"))
sourcepaths =
sourcepaths.plus(project(":InstallPlanInterfaces_1_0_0").files("src/main/java"))
setSource(sourcepaths.asFileTree)
// fix the problem with the missing android bootclasses
android.bootClasspath.forEach{
classpath += fileTree(it)
}
// create a temporary directory for storing the "classes.jar" file contained in the *.aar files
val tmpDir:File = File(project.buildDir, "\\tmpAar\\")
if (tmpDir.exists()) tmpDir.delete()
tmpDir.mkdirs()
// add the javadoc dependencies
javadocDeps.forEach {
// I've got a custom class that allows me to treat jar or zip files and a file system
// you could replace this using spy's zip file extraction method
val zipFileSystem: com.phinneyridge.ZipFileSystem = ZipFileSystem(it.absolutePath,null)
if (it.name.endsWith(".aar")) {
// extract the classes.jar file from the aar file to the tmpDir
// renaming it to name of the aar file, but change the extension to jar
val tmpFile:File = File(tmpDir, it.name.replace(".aar", ".jar"))
zipFileSystem.extractEntry("classes.jar", tmpFile)
} else {
// for jar files, we just add it to the path
classpath += fileTree(it)
}
}
// now add the tmpDir files to the javadoc classpath
classpath += fileTree(tmpDir)
// for diagnosis purposes, we'll print the classpath.
// Notice that you have a lot more path entries then you have javadocDeps
println("classpath: " + classpath.asPath)
}
}发布于 2022-07-24 07:07:05
我知道您有这样一个项目结构: app -> module2 -> module1。
其中->的意思是依赖流。因此,我部署了一个具有相同依赖流的项目,但使用了gradle 7.0.2 (因为这正是我目前使用的),并且为module2和module1生成javadoc没有问题。
基本上,它归结为在每个模块的每个级别上实现这一点:https://stackoverflow.com/a/73096187/9902249
我希望它对你有用。
https://stackoverflow.com/questions/71906540
复制相似问题