发布android的library包到Jcenter

Categories: kotlin   android

Android开发的时候会使用到很多优秀的开源库,gradle引入这些包的时候,大部分都是从Jcenter这个仓库来的,这个Jcenter库是由Bintray在维护,如果想自己开发一个开源库或者开源组件,可以打包发布到Jcenter供大家使用,方便自己也方便大家。

想发布包到Jcenter,先的去Bintray注册账户,这里注意注册一个开源账户,前面那个免费账户要什么组织什么的,我也没搞懂,反正就是一直没传成功!

注册登录之后,看下图,两个事情,知道API key在哪里、创建一个maven仓库

API Key

点击用户名下面的Edit按钮,可以进入个人信息界面,左边菜单的最后一个选项API Key就能查到你的key,这个key后续上传你的包的时候会需要用到的。

创建maven仓库

点击上上图圈出来的按钮Add New Repository ,进入创建界面,类型选择maven,填写你的库名称,然后保存

这样Bintray网站上的事情就告一段落了。

Gradle 插件

在你要发布的项目的根gradle文件中添加两个插件:

classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.6'

一个是为了给Android的项目生成maven标准用的,一个是上传文件到bintray服务器用的

建一个bintrayUpload.gradle文件,内容:

apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

// load properties 
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

// read properties
//项目名称
def projectName = properties.getProperty("project.name")
//项目的groupId
def projectGroupId = properties.getProperty("project.groupId")
//项目的artifactId,这里需要跟项目的library名称一致,不然传到bintray的包和名字对不上会找不到
def projectArtifactId = properties.getProperty("project.artifactId")
//library的版本号
def projectVersionName = properties.getProperty("project.version")
//网站地址
def projectSiteUrl = properties.getProperty("project.siteUrl")
//开源的git地址
def projectGitUrl = properties.getProperty("project.gitUrl")
//项目库的描述
def projectDesc = properties.getProperty("project.desc")
//开发者标识ID
def developerId = properties.getProperty("developer.id")
//开发者名称
def developerName = properties.getProperty("developer.name")
//开发者邮箱
def developerEmail = properties.getProperty("developer.email")
//这个就是刚才注册的bintray用户名
def bintrayUser = properties.getProperty("bintray.user")
//这个是前面提到的bintray上面的API Key
def bintrayApikey = properties.getProperty("bintray.apikey")

group = projectGroupId

// This generates POM.xml with proper parameters
install {
    repositories.mavenInstaller {
        pom {
            project {
                packaging 'aar'
                groupId projectGroupId
                artifactId projectArtifactId

                name projectName
                description projectDesc
                version projectVersionName
                url projectSiteUrl
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        id developerId
                        name developerName
                        email developerEmail
                    }
                }
                scm {
                    connection projectGitUrl
                    developerConnection projectGitUrl
                    url projectSiteUrl
                }
            }
        }
    }
}


version = projectVersionName

// 命令 java -Djava.ext.dirs=. -jar dokka-fatjar.jar ./src/main/java -format javadoc -output ./build/doc

task dokkaJavadoc(type: org.gradle.api.tasks.Exec) {
    workingDir '.'
    println "WorkingDir: $workingDir"
    ext.toolJarPath = "$workingDir"
    ext.dokkaJarPath = "$workingDir"+File.separator+"dokka-fatjar.jar"
    ext.sourceDirs = "$workingDir"+File.separator+"src"+File.separator+"main"+File.separator+"java"
    ext.outputFormat = 'javadoc'
    ext.outputDirectory = "$buildDir" + File.separator+ "doc"

    /**
     *
     * 这里输出格式可以为: html , markdown, jekyll, javadoc
     * 如果是 javadoc 格式, 他会用到 javadoc 的库,
     * 如果你的 PATH 没有包含 JDK x.x.x/lib 路径的话, 就会报 'java.lang.ClassNotFoundException: com.sun.javadoc.DocErrorReporter' 异常
     * 所以需要你主动将这个路径加进来, 或者将 JDK x.x.x/lib/tools.jar 文件拷贝出来, 下面这个命令我就是拷贝到了当前目录
     *
     * dokka-fatjar.jar 这个jar就是从 dokka 项目上下载下来的
     */
    commandLine "cmd" , "/c", "java -Djava.ext.dirs=$toolJarPath -jar $dokkaJarPath $sourceDirs -format $outputFormat -output $outputDirectory"

    /**
     * 如果你是 Linux 系统, 就用这个
     */
//    commandLine "java" ,"-Djava.ext.dirs=$toolJarPath", "-jar", "$dokkaJarPath", "$sourceDirs", "-format", "$outputFormat", "-output", "$outputDirectory"

}

/**
 * 这里将生成的文档打包成 xxxx-javadoc.jar
 */
task kotlinDocJar(type: Jar, dependsOn: dokkaJavadoc) {
    classifier = 'javadoc'
    from dokkaJavadoc.outputDirectory
}

/**
 * 这里将源码打包成 xxx-sources.jar
 */
task sourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}


artifacts {
    archives kotlinDocJar
    archives sourcesJar
}

// bintray configuration
bintray {
    user = bintrayUser
    key = bintrayApikey
    configurations = ['archives']
    pkg {
        repo = "maven"
        name = projectName
        desc = projectDesc
        websiteUrl = projectSiteUrl
        vcsUrl = projectGitUrl
        licenses = ["Apache-2.0"]
        publish = true
        publicDownloadNumbers = true
    }
}

然后把这个文件引入到你要打包的模块的gradle文件内:

apply from: "../bintrayUpload.gradle"

然后用Android Studio上gradle窗口执行两个任务

install

bintrayUpload

这样就传到bintray的服务器上了。

最后一步是到bintray的网站上,将你maven仓库里面的包同步到Jcenter,等Jcenter通过了审核后,就可以在其他项目中使用你的包了。

PS:这里重点说下bintrayUpload.gradle中的关于kotlinDocJar任务,因为我的library是用kotlin写的,于是就一直生成步了javadoc,没有javadoc,Jcenter就不肯通过审核。这里要感谢Kejin,在网上搜到了他的博客,才知道如何生成这个javadoc,文章链接

更新2018-6-22

今天又发布了一个library到jcenter服务器上去,按照上面的流程进行的,结果还是生成doc的地方卡住了。

今年换了mac电脑,环境啥的都变了,上面那个dokkaJavadoc任务死活执行不下去。开始说是-Djava.ext.dirs这个参数不正确,后来改成了 -cp ,结果错误不一样了,说是一个目录找不到,但是这个目录就是它的工作目录,肯定是在的,也没有报别的错误信息出来。

后来没办法去github上找了另外一个库:https://github.com/Kotlin/dokka kotlin 的java文档生成工具。于是修改了那个生成javadoc的任务:

apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'org.jetbrains.dokka'

// load properties
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())

// read properties
def projectName = properties.getProperty("project.name")
def projectGroupId = properties.getProperty("project.groupId")
def projectArtifactId = properties.getProperty("project.artifactId")
def projectVersionName = properties.getProperty("project.version")
def projectSiteUrl = properties.getProperty("project.siteUrl")
def projectGitUrl = properties.getProperty("project.gitUrl")
def projectDesc = properties.getProperty("project.desc")

def developerId = properties.getProperty("developer.id")
def developerName = properties.getProperty("developer.name")
def developerEmail = properties.getProperty("developer.email")

def bintrayUser = properties.getProperty("bintray.user")
def bintrayApikey = properties.getProperty("bintray.apikey")

def javadocName = properties.getProperty("javadoc.name")

group = projectGroupId

// This generates POM.xml with proper parameters
install {
    repositories.mavenInstaller {
        pom {
            project {
                packaging 'aar'
                groupId projectGroupId
                artifactId projectArtifactId

                name projectName
                description projectDesc
                version projectVersionName
                url projectSiteUrl
                licenses {
                    license {
                        name 'The Apache Software License, Version 2.0'
                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        id developerId
                        name developerName
                        email developerEmail
                    }
                }
                scm {
                    connection projectGitUrl
                    developerConnection projectGitUrl
                    url projectSiteUrl
                }
            }
        }
    }
}


version = projectVersionName
 
dokka {
    outputFormat = 'javadoc'
    outputDirectory = "$buildDir/javadoc"
}

/**
 * 这里将生成的文档打包成 xxxx-javadoc.jar
 */
task kotlinDocJar(type: Jar, dependsOn: dokka) {
    classifier = 'javadoc'
    from dokka.outputDirectory
}

/**
 * 这里将源码打包成 xxx-sources.jar
 */
task sourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.srcDirs
}


artifacts {
    archives kotlinDocJar
    archives sourcesJar
}

// bintray configuration
bintray {
    user = bintrayUser
    key = bintrayApikey
    configurations = ['archives']
    pkg {
        repo = "maven"
        name = projectName
        desc = projectDesc
        websiteUrl = projectSiteUrl
        vcsUrl = projectGitUrl
        licenses = ["Apache-2.0"]
        publish = true
        publicDownloadNumbers = true
    }
}

其实就是添加了一个插件apply plugin: 'org.jetbrains.dokka' ,然后把原来dokkaJavadoc任务改成了dokka这个任务。然后就ok了。