愉快地写Java————Java库的开发以及发布

前言

众所周知,Java编程语言的各种语法十分繁琐,很多东西使用起来十分不方便。比如Java就没有属性这一功能,使用就非常麻烦。

比如,超级语言中:

public string Name { get; set; }

在Java中要达到相同的效果,就只能这么写:

private String _name;
public String getName(){
    return _name;
}
public void setName(String name){
    _name = name;
}

对于只读属性,超级语言:

public string Name { get; }

而Java:

private final String _name;
public String getName(){
    return _name;
}

这就十分难受了,就算是有IDE生成代码,也要多按几下键盘。有些人可能就会问了,这种情况,直接使用公共字段不就可以了?我只想说,如果你有这种想法,建议重修软件构造

于是,我就突发奇想:如果超级语言的的属性是一种语法糖,那么为什么不能在Java中封装一个类来达到类似的效果呢?

所以经过一些开发,在Java中也能用一行代码达到相同的效果:

//Choose one
public final Property<String> Name = Properties.of("Alice");
public final ReadOnlyProperty<String> Name = Properties.ofReadOnly("Alice");
public final ReadOnlyProperty<String> Name = Properties.ofDefault();

基本用法

使用这个库十分简单,只需要添加引用,然后就可以使用了。

有一些基本的说明:

  • 属性通过get()方法获取值,可写的属性可以通过set(T value)进行再赋值。

  • ReadOnlyProperty<T>Property<T>OptionalProperty<T>都是接口,其中ReadOnlyProperty为只读属性的接口,只能get,不能setProperty是一般的属性,OptionalProperty则是带null检查的属性,读与写的时候要进行为空检查。

  • 有五个静态方法可以构造自动属性,详见下表,若有不明白的地方还可以查询Javadoc

    修饰符和类型方法说明
    static @NotNull Propertyof(T value)构造可读写的自动属性
    static @NotNull PropertyofDefault()构造初值为Null的属性
    static @NotNull OptionalPropertyofNullable(T value)构造初值可为空的带Null检查的属性
    static @NotNull OptionalPropertyofOptional(T value)构造带Null检查的属性
    static @NotNull ReadOnlyPropertyofReadOnly(T value)构造只读的自动属性
  • 若要手动定义属性,可以参考下面的示例代码:

    public final ReadOnlyProperty<String> Name = () -> "Alice";
    
    private String name = "Alice";
    public final Property<String> Name = new Property<String>()
    {
        @Override
        public void set(String value)
        {
            name = value;
        }
    
        @Override
        public String get()
        {
            return name;
        }
    };
    
  • 所有由静态方法创建的属性都重载了equals以便进行值的比较,手动创建的方法可以使用Properties.equals()方法进行比较。

这样下来,对Java属性的调用与创建,都有超级语言的简便性了。

打包与发布

下面就是重头戏了,因为Java语言并没有官方的包管理系统,使用的最多的包管理系统则是maven。因此,只要我们把包上传到maven central这个源里,全世界所有的人都能下载到我们制作的库。只可惜,这个流程实在是太繁琐了,因此倒是成了这篇文章的主要部分了。

前期准备工作

首先,我们得先获得在maven central上传东西的许可。方法是先创建一个Nexsus账户,创建账户之后,我们要点击上面的“新建”来提交问题。

唢呐类型主页

由于我们是开源项目,在创建问题的项目选择Community Support - Open Source Project Repository Hosting (OSSRH),下面的问题类型选择New Project,概要就描述一下项目。

创建问题

重要的是下面的Group Id,如果你有一个域名,那么很简单,将这个域名倒置,就是一个合法的Group Id了。比如hcg.today倒置就是today.hcghcgstudio.com倒置就是com.hcgstudio

如果你没有域名,那也没关系,在这里填一个Github Page的域名也行,比如io.github.mahoshojoHCG,要是实在搞不清楚也可以看一看填写指南

唢呐类型-创建问题

接下来就是填入你项目的主页和git仓库地址,这些比较简单就不展开说了。

然后提交,这个问题就提交上去了。然后专业的工作人员回来审核你的问题,主要是看你的Group Id是否合规。

在等待审核的时候,不要愣着,如果你是用自己域名验证的,那你就需要给你的域名新建一个TXT记录,指向你的问题ID,格式大概是OSSRH-****

云耀斑添加TXT记录

然后就等待人工审核了,如果有什么问题,工作人员会在问题的评论里指出,按照要求进行修改就可以了。

唢呐类型问题的评论1

等待审核通过,工作人员就会评论你成功,这样车就备好了

唢呐类型评论2

然而,我们的准备阶段才刚刚结束。

修改Gradle文件

然后,我们需要修改build.gradlegradle能够生成并且发布我们的包。

我们首先添加几个插件,在顶部的插件里:

plugins {
    id 'java'
    id 'java-library'
    id 'signing'
    id 'maven-publish'
}

然后下面的group要改成你前面申请的Group Id,比如:

group 'com.hcgstudio'

接下来,进行设置,让我们发布的时候附带源码与javadoc

java {
    withJavadocJar()
    withSourcesJar()
}

紧接着,再插入一个部分,按照这个格式进行修改,这里面对生成的包的属性进行了定义。

publishing {
    repositories {
        maven {
            def releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
            def snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots"
            url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
            credentials {
                username = "${NEXUS_USERNAME}"
                password = "${NEXUS_PASSWORD}"
            }
        }
    }
    publications {
        mavenJava(MavenPublication) {
            artifactId = 'com.hcgstudio.JImprove'
            from components.java
            versionMapping {
                usage('java-api') {
                    fromResolutionOf('runtimeClasspath')
                }
                usage('java-runtime') {
                    fromResolutionResult()
                }
            }
            pom {
                name = 'JImprove'
                description = 'A library to add features to Java.'
                url = 'https://github.com/HCGStudio/JImprove'
                licenses {
                    license {
                        name = 'The Apache License, Version 2.0'
                        url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
                    }
                }
                developers {
                    developer {
                        id = 'mahoshojoHCG'
                        name = 'Yin Zhaoyu'
                        email = 'hcg@hcg.today'
                    }
                }
                scm {
                    connection = 'scm:git:git://github.com/HCGStudio/JImprove.git'
                    developerConnection = 'scm:git:ssh://github.com/HCGStudio/JImprove.git'
                    url = 'https://github.com/HCGStudio/JImprove'
                }
            }
        }
    }
}

如果你也要用,修改的部分只有artifactIdpom,剩下的照搬就行了。

最后,加入以下部分,就差不多完工了:

signing {
    sign publishing.publications.mavenJava
}

javadoc {
    options.encoding = "UTF-8" 
    options.charSet = 'UTF-8'
    if(JavaVersion.current().isJava9Compatible()) {
        options.addBooleanOption('html5', true)
    }
}

上传GPG密钥

然后我们需要上传我们的GPG密钥。

这一步需要GNUPG,如果你使用的是Linux或者macOS的话,你的系统里大概率有这个东西的,如果你使用的是Windows的话,那么你的系统里100%有GNUPG。为什么呢?因为GNUPG是你装Git的副产品。既然在开发开源项目,电脑里是不可能没有Git的。然后对于Windows,打开Git Bash,因为GNUPG默认不添加到Path里,所以需要Git BashmacOSLinux,随便打开一个终端就行,顺便检查下有没有gpg这个命令,没有的话用brew或者pacman装一下就行。

在确认安装GNUPG之后,我们需要生成并导出密钥,生成密钥这里,GitHub有很详尽的教程,这里就不赘述了。

然后我们将GPG密钥上传到openpgp的服务器上,这里记得把邮箱换成你自己的邮箱。

gpg --export hcg@hcg.today | curl -T - https://keys.openpgp.org

如果成功,会打印一个查看的链接,点进去就能看到上传是否成功。

接着,导出私钥,供gradle稍后签名使用。

gpg --keyring secring.gpg --export-secret-keys > ~/.gnupg/secring.gpg

修改Gradle配置

接着,我们在正式发布前要做的最后一步,修改gradle的配置。

进入~/.gradle,看看里面有没有gradle.properties,如果有就打开,没有就创建一个,然后加入以下内容:

NEXUS_USERNAME=NEXSUS用户名
NEXUS_PASSWORD=NEXSUS密码
signing.keyId=GPG密钥后8位,使用gpg -K查看
signing.password=GPG密钥的密码,没设密码这里填双引号,不要留空
signing.secretKeyRingFile=刚才导出的密钥文件,Windows的话路径记得加两个\\

修改之后,我们就可以在我们源代码目录里进行发布了。

发布,以及后续工作

打开存放源代码的目录,执行

gradle clean
gradle publish

如果配置没有问题,那么就会成功的上传到服务器了,然后就大功告成了……才怪咯!如果这是nuget或者pypi,那么工作确实完成了,可是这是maven central,我们还需要再做一步。

打开Nexus,在Staging Repositories里可以看到你刚才的上传的东西,然后我们点击Close,然后他会开始做一个检查,等检查通过之后,我们点击Release,就可以在另一个检查通过之后,发布了。

Nexus

接着我们回到最开始的问题页面,回复一下表示你创建了一个Release

唢呐类型问题回复

等他最后给你回复允许同步之后,你的包在10分钟之内就可以索引到了(即可以使用了),但是如果在搜索界面出现,可能得两个小时。

不过那已经不重要了,毕竟已经能用了,搜索不搜索的暂时也影响不到了。

这里还是要提醒一下,如果后面更新的时候点Release说有文件冲突,删除掉提醒冲突的文件,没有影响的。

后记

这次废了九牛二虎之力,制作了一个Java的库,而且符合软件构造的各种指标。实际编码时间不长,反倒是上传maven的时间比较长,希望以后maven能够减少过程的时间,这样发布的时间会短很多。

以后要是想到什么减少Java代码的好主意,也会移植并且加到这个库里的。

EOF

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇