maven私服搭建及gradle上传

声明:文章为原创,转载请注明原文地址
http://www.jianshu.com/p/b1fe26d5b8c8
文章中代码部分已上传到Github,传送门在文章末尾。

本次的搭建是在ubuntu系统上进行的,windows搭建过程类似。

软件准备

此次搭建我们用到了JDK及nexus(sonatype的软件,不是google的手机)

  • JDK (我用的版本所1.7.0_76)
  • NEXUS (我用的所nexus-2.12.0-01,在官网下载即可,我下载了nexus-2.12.0-01-bundle.zip 去官网下载 )

安装过程

JDK的安装 :

这个我就不写了,一搜一大堆。可参考文章

NEXUS安装:
  1. 把下载的nexus-2.12.0-01-bundle.zip放到/usr/local目录下(你也可以放到其它目录)
  2. 为了减去不必用的麻烦,我建议现在开始使用你的su权限。
    命令行:sudo su
    会让你输入密码确认,确认后进入超级权限。
  3. 解压压缩文件。
    命令行:**unzip nexus-2.12.0-01-bundle.zip **
    解压文件得到 nexus-2.12.0-01文件及sonatype-work文件夹。我们现在只关心nexus-2.12.0-01文件夹。
存放位置-超级命令-解压.jpg
  1. 软连接
    为了操作方便,我们给这个比较长名字的文件夹建个软连接(好比所Windows的快捷方式),
    命令行: ln -s nexus-2.12.0-01 nexus2
  2. 运行nexus
    我们进入到nexus2指向的文件夹下
    命令行:cd nexus2 **
    启动nexus
    命令行:
    ./bin/nexus start**
    失败了,没运行起来。如图,好纠结,一面让我们run as root,一面又不建议我们这样。
软连接-运行需要root提示.jpg
  1. 设置RUN_AS_USER=root
    那我们按照它的指示设置RUN_AS_USER=root
    命令行:vi ./bin/nexus
    vi设置run_as_root.jpg

VI编辑器不熟悉的话,可以用你熟悉的方式修改,不会不丢人- -!

  1. 再次运行启动命令
    如果看到命令行提示了Started Nexus OSS,说明我们成功了。
    访问下试试:http://localhost:8081/nexus/ 如图,我们已经成功运行。
提示run_as_root-成功运行.jpg
成功运行.jpg

我遇到一个情况是这样的,已经提示我“Started Nexus OSS”。但是浏览器访问不到。这时我尝试再次使用命令启动nexus。仍然提示我“Started Nexus OSS”。如果你也遇到这种情况就注意了,现在是有问题的,服务没起来。如果起来了,再次启动会提示“Nexus OSS is already running.”我经过排查发现是因为我系统的JAVA环境不对,没有装Oracle的JDK,而是使用了自带的OpenJDK(具体版本忘了,特别声明,有的OpenJDK版本是可以让nexus正常运行的),那你就去装下Oracle的JDK吧。

配置

  1. 点击右上角的"Log In",默认用户名密码所admin/admin123。
  2. 登录后,点击右侧菜单栏Views/Respositories->Respositories,将会看到下图几个仓库。


    默认的仓库-步骤2.jpg
  3. 我们可以看到这些仓库的类型有:group、hosted、proxy、virtual。
    hosted,本地代理仓库,通常我们会部署自己的构件到这一类型的仓库。
    proxy,代理的远程仓库,它们被用来代理远程的公共仓库,如maven中央仓库。
    group,仓库组,用来合并多个hosted/proxy仓库,通常我们配置maven依赖仓库组。
    virtual,这种是maven1的,以后基本不会用到或者很少会用到,所以不用过多理会。

我这里并没有打算讲怎么新建仓库,因为nexus提供的这几个仓库对于简单使用已经可以了。

  1. 下面我们先来配置一下Central仓库:
    a.修改Download Remote Indexes选项为True(允许下载远程仓库的索引)
    b.在Central仓库上右击,选择Repair Index(代理仓库会去下载远程仓库的索引,方便搜索)
    c.片刻之后我们在仓库下方的详细信息处点击Browse Index 可以看到有个文件夹 Central,前方有个加号可以打开,如果没有信息,说明还没有下载下来,或者下载失败了。你可以选择等一等,或者在最右侧的菜单栏选择Administration->Logging,查看运行信息,可能对你有帮助。
允许下载索引-更新索引-步骤4.jpg

有的时候你确实需要等一等,因为我遇到过,怎么也没有索引下载下来,大概我吃了午饭回来,发现它自己下载好了。

  1. 同步骤4一样来配置Apache Snapshots
    这里为我们可以看到仓库policy有Releases、Snapshots两种。
    Snapshot 代表不稳定、尚处于开发中的版本。
    Release 代表稳定的版本

现在你可以尝试在右侧菜单栏的搜索框尝试搜索内容。如果你的proxy仓库成功的下载了索引,我们尝试搜索okhttp(你也可以换个关键字)你将会看到如下面的画面

搜索效果-步骤5.jpg
  1. 自带仓库Releases、Snapshots就是为我们准备的上传我们自己lib文件的仓库,所以就不必新建其它仓库了

  2. 配置仓库组Public Repositories。如下图配置好后,千万要点save进行保存。

仓库组与仓库就像我们android开发中ViewGroup 与 View的关系。本身包含其他仓库,对外又像仓库一样使用。

Public Repositories库配置-步骤7.jpg

8.新建SnapShots仓库组。点击Add->Repository Group。会在下方仓库区新生成一个“New Repository Group”。我们像下方图: snapshots配置-步骤8.jpg 那样对它进行配置。

新建库组.jpg
snapshots配置-步骤8.jpg

使用我们的仓库

在我们项目的主build.gradle中修改allprojects的maven地址:

allprojects {    
       repositories {        
              //jcenter()        
              maven {url "http://ip:8081/nexus/content/groups/PublicSnapshots/"}    
       }
}

"sync now"一下,现在我们的工程配置的依赖就已经使用我们自己搭建的私有仓库了。

各库地址URL.jpg

上图中Public Snapshots库对应的Respository Path就是我们上方替换默认maven库地址的私库地址。下面Releases、Snapshots库地址就是我们下节 发布到私服 上传脚本中自己的lib库要发布到的仓库地址。

发布到私服

接下来,我们将在Android Studio环境下,来发布我们自己的库文件
1.在我们的工程下新建一个lib,我这就叫likelib吧。
2.在主项目下新建一个maven_push.gradle来写我们的发布到maven库的脚本

// The Maven plugin adds support for deploying artifacts to Maven repositories.
// 一个可以让你把库上传到maven仓库的插件
apply plugin: 'maven'
// The signing plugin adds the ability to digitally sign built files and artifacts. These digital signatures can then be used to prove who built the artifact the signature is attached to as well as other information such as when the signature was generated.
// 对库文件进行数字签名的插件,可以通过签名知道谁创建了这个库文件,签名的时间等等信息
apply plugin: 'signing'

// 声明变量记录maven库地址
def mavenRepositoryUrl
// 判断是发布到正式库,还是snapshots库
if (isReleaseBuild()) {
    println 'RELEASE BUILD'
    // 下面的库地址指向的是我们私有仓库的Releases 仓库
    mavenRepositoryUrl = hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
            : "http://IP:8081/nexus/content/repositories/releases/"
} else {
    println 'SNAPSHOTS BUILD'
    // 下面的库地址指向的是我们私有仓库的snapshots 仓库
    mavenRepositoryUrl = hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
            : "http://IP:8081/nexus/content/repositories/snapshots/"
}
// NEXUS_USERNAME等变量在我们主项目的gradle.properties中可以找到
def getRepositoryUsername() {
    return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
}

def getRepositoryPassword() {
    return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
}
// 根据我们在likelib下gradle.properties中声明的版本名称,来分辨是Release版本还是 snapshots版本
def isReleaseBuild() {
    return !VERSION_NAME.contains("SNAPSHOT");
}

//"afterEvaluate是什么鸟?你可以理解为在配置阶段要结束,项目评估完会走到这一步。" 引用自http://jiajixin.cn/2015/08/07/gradle-android/
afterEvaluate { project ->
    // 我们声明我们要执行的上传到maven的task
    uploadArchives {
        repositories {
            mavenDeployer {
                beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
                // 我们类比下compile com.squareup.okhttp:okhttp:2.7.0
                // artifactId 对应com.squareup.okhttp; groupId 对应okhttp;version对应2.7.0
                // 这样就类似坐标的方式定位到了制定的库文件
                pom.artifactId = POM_ARTIFACT_ID
                pom.groupId = POM_GROUP_ID
                pom.version = VERSION_NAME

                // 授权验证,这里也就是你登陆搭建的私服服务器时候的用户名\密码
                repository(url: mavenRepositoryUrl) {
                    authentication(userName: getRepositoryUsername(), password: getRepositoryPassword())
                }

                // 这里是配置我们maven库需要的pom.xml文件的各个内容,具体意思我们在主目录gradle.properties中解释
                pom.project {
                    name POM_NAME
                    packaging POM_PACKAGING
                    description POM_DESCRIPTION
                    url POM_URL

                    scm {
                        url POM_SCM_URL
                        connection POM_SCM_CONNECTION
                        developerConnection POM_SCM_DEV_CONNECTION
                    }

                    licenses {
                        license {
                            name POM_LICENCE_NAME
                            url POM_LICENCE_URL
                            distribution POM_LICENCE_DIST
                        }
                    }

                    developers {
                        developer {
                            id POM_DEVELOPER_ID
                            name POM_DEVELOPER_NAME
                        }
                    }
                }
            }
        }
    }

    // 进行数字签名
    signing {
        required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
        sign configurations.archives
    }

    // type显示指定任务类型或任务, 这里指定要执行Javadoc这个task,这个task在gradle中已经定义
    task androidJavadocs(type: Javadoc) {
        // 设置源码所在的位置
        source = android.sourceSets.main.java.sourceFiles
    }

    // 生成javadoc.jar
    task androidJavadocsJar(type: Jar) {
        // 指定文档名称
        classifier = 'javadoc'
        from androidJavadocs.destinationDir
    }

    // 生成sources.jar
    task androidSourcesJar(type: Jar) {
        classifier = 'sources'
        from android.sourceSets.main.java.sourceFiles
    }

    // 产生相关配置文件的任务
    artifacts {
        archives androidSourcesJar
        archives androidJavadocsJar
    }
}

3.在主项目下gradle.properties中来声明我们运行脚步时需要的信息

# properties for maven2 repository
# nexus服务器登陆时候的用户名/密码
NEXUS_USERNAME=admin
NEXUS_PASSWORD=admin123
# 在POM文件中使用的group ID
POM_GROUP_ID=com.exmaple.like
# POM文件中指向你网站的地址
POM_URL=https://github.com/achenglike
# SCM是指版本管理工具,一下说他的相关信息
POM_SCM_URL=https://github.com/
POM_SCM_CONNECTION=https://github.com/achenglike
POM_SCM_DEV_CONNECTION=https://github.com/achenglike
# 你的开放协议相关信息
POM_LICENCE_NAME= Apache License Version 2.0
POM_LICENCE_URL= https://github.com/achenglike/Gallery/blob/master/LICENSE
POM_LICENCE_DIST=Apache License Version 2.0
# 开发者的相关信息
POM_DEVELOPER_ID=achenglike
POM_DEVELOPER_NAME=achenglike

3.在我们likelib项目下的build.gradle引入我们的脚本

apply from: '../maven_push.gradle'

4.在我们likelib项目下新建一个gradle.properties来存我们需要发布的版本、格式等信息

# 库名称
POM_NAME=Like Library
# artifactId
POM_ARTIFACT_ID=like
# 库的打包格式为aar, 常见的还有jar
POM_PACKAGING=aar
# 库的描述,说明他是干啥的
POM_DESCRIPTION=like Library
# 要发布的版本好,snapshots 版本可以使用格式 1.0.0-SNAPSHOT
VERSION_NAME=1.0.0

5.我们现在可以在android studio的Terminal中来发布我们的库文件了 。
输入命令:gradle uploadArchives
运行结束Terminal会提示成功或失败,提示成功说明已经上传到了你的私库中。

如果没有意外,我们已经发布到了我们的私有仓库,我们可以自己去看看,就像下面的图。

成功上传库文件.jpg

使用

接下来我们将使用我们上传的库文件
1.在app 模块的build.gradle中引入依赖

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.2.0'
    compile 'com.android.support:design:23.2.0'
    compile 'com.exmaple.like:like:1.0.0'
}

最下面的库引用就是我们刚才上传的库文件

2.我们在app模块使用依赖的库

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, Hello.getInstance().hello(), Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

文章为原创,转载请注明原文地址
http://www.jianshu.com/p/b1fe26d5b8c8
示例中的工程已久上传到了Github

推荐阅读更多精彩内容