引文

Gradle的配置文件有点像Makefile,都是用脚本来控制代码的编译。大体上Gradle跟Maven差不多,因为最终都是把项目文件整理成javac的编译参数,用jar来打包,区别在于形式上的不同,Gradle的编译选项使用的是脚本(Groovy或Kotlin),Maven用的是Xml。据Gradle的官方称,Gradle的编译性能要比Maven快上几倍,刚好最在做一个项目的时候,因为在Maven中加了一个依赖,导致IDE一直处于繁忙状态,只能去任务管理器中把进程结束掉,恢复原来的配置。虽然这个依赖是可有可无的,但促使我有了想尝试一下Gradle的念头。

换成Gradle本身倒不是太难的事情,直接在Maven项目中执行Gradle Init就可以将Maven项目转换成Gradle项目,写了几个测试项目,也没什么问题,但我的项目是跟jfx有关的,这不免要用到java的模块化功能,于是问题就来了。Java的模块化在用Maven构建的时候很正常,一切换到Gradle就不行了,报找不模块的错误。分析了一下,是因为报错的模块都没有经过模块化的,按照Java官方的说法,如果库没有模块化,就放到classpath下,在module-info.java里使用jar包的名称来作为自动模块的模块名。这在Maven下不用特别设置,就可以顺利编译,但在Gradle下边是不行的。大概是Maven作了自动处理,而Gradle没有。翻了无数遍Gradle的文档,终于发现Gradle遇到这种情况确实是需要特别处理的,需要在build.gradle里加一个叫extra-java-module-info的插件,然后使用这个插件申明一下那些未模块化的类库,这样才可以在module-info.java中正常地引入。

以下部分演示如何Gradle项目中使用非模块化(未命名模块unnamed module)库,希望能帮到那些使用Gradle的小伙伴们。

准备工作

安装Gradle工具
由于不是本文的重点,具体过程省略,可以参考以上链接完成Gradle的安装和配置。

生成项目
如何生成项目,参考以上链接。

代码演示

新建一个项目

我创建一个叫test的项目。项目结构跟Maven差不多,只是项目根目录下多了一些跟gradle有关的东西。我们先看一下build.gradle文件,跟构建相关的内容基本上就在这个文件里,初始的build.gradle是个样子:

/*
 * This file was generated by the Gradle 'init' task.
 *
 * This generated file contains a sample Java Library project to get you started.
 * For more details take a look at the Java Libraries chapter in the Gradle
 * User Manual available at https://docs.gradle.org/6.5/userguide/java_library_plugin.html
 */

plugins {
    // Apply the java-library plugin to add support for Java Library
    id 'java-library'
}

repositories {
    // Use jcenter for resolving dependencies.
    // You can declare any Maven/Ivy/file repository here.
	
    jcenter()
}

dependencies {
    // This dependency is exported to consumers, that is to say found on their compile classpath.
    api 'org.apache.commons:commons-math3:3.6.1'

    // This dependency is used internally, and not exposed to consumers on their own compile classpath.
    implementation 'com.google.guava:guava:29.0-jre'

    // Use JUnit test framework
    testImplementation 'junit:junit:4.13'
}

修改仓库

由于墙的原因,默认的仓库下载依赖项会很慢,所以要改国内有镜像,我这里用的阿里Maven仓库镜像。
将:

repositories {
    // Use jcenter for resolving dependencies.
    // You can declare any Maven/Ivy/file repository here.
	
    jcenter()
}

改成:

repositories {
    // Use jcenter for resolving dependencies.
    // You can declare any Maven/Ivy/file repository here.
	maven{
		url 'https://maven.aliyun.com/repository/central'
	}
    mavenCenter()
}

加入依赖包

在dependencies中加入fastjson的依赖包:

dependencies {
    //...省略已有内容
	
    implementation 'com.alibaba:fastjson:1.2.70'

    // ...省略已有内容

}

此时在命令行运行一下gradlew build是没有什么问题的。

模块化

为了实现模块化,需要在源码根目录(${project_path}\src\main\java)下加入module-info.java文件。

module-info.java

module test {
	exports test;
	requires com.google.common;
	requires fastjson;
}

再次运行gradlew build出错了:

E:\projects\test1\src\main\java\module-info.java:3: 错误: 找不到模块: com.google.common
	requires com.google.common;
	                   ^
E:\projects\src\main\java\module-info.java:4: 错误: 找不到模块: fastjson
	requires fastjson;

出现这个问题的原因是没有把依赖项放到module-path里去。在使用javac编译的时候会有这一个参数:

--add-modules <模块>(,<模块>)* 除了初始模块之外要解析的根模块; 如果 为 ALL-MODULE-PATH, 则为模块路径中的所有模块。

在gradle中的配置是这样的,用文本编辑器打开build.gradlew,加上这么一段内容:

java {
		modularity.inferModulePath = true
	}

然后我们再次编译,会发现此时错误少了一个。

E:\projects\ebiz\java\test1\src\main\java\module-info.java:4: 错误: 找不到模块: fastjson
	requires fastjson;
	         ^
1 个错误

这其实很好理解,guava-29.0-jre.jar的在MANIFEST.MF文件中指定了Automatic-Module-Name: com.google.common,说明已经是自动模块化了的,所以在模块化项目中直接导入,而fastjson-1.2.70.jar的在MANIFEST.MF文件中没有这一行。这也说明阿里的开发人员并不CARE模块化这玩意,在MANIFEST.MF中加一行Automatic-Module-Name不愿意去做。

配置非模块化库(也叫未命名模块库unnamed module library)

gradle自身不会管你引用的库是不是模块化的,它都统一处理的,为了将非模块化库独立出来,此时我们就要使用一个模块的工具插件了——extra-java-module-info。

我们在plugins里加上一行。

id "de.jjohannes.extra-java-module-info" version "0.1"

然后再加上这一段:

extraJavaModuleInfo {
	// This does not have to be a complete description (e.g. here 'org.apache.commons.collections' does not export anything here).
	// It only needs to be good enough to work in the context of this application we are building.
	module('commons-math3-3.6.1.jar','org.apache.commons','3.6.1')
	module('failureaccess-1.0.1.jar','failureaccess','1.0.1')
	module('jsr305-3.0.2.jar','jsr305','3.0.2')
	module('listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar','listenablefuture-9999.0-empty-to-avoid-conflict-with-guava','9999.0')
	module('j2objc-annotations-1.3.jar','j2objc-annotations','1.3')
	module('hamcrest-core-1.3.jar','hamcrest-core','1.3')
	module('fastjson-1.2.70.jar','fastjson','1.2.70') {
		exports("com.alibaba.fastjson")
	}
	automaticModule("guava-29.0-jre.jar", "com.google.common")
}

再次运行gradlew build,结果显示成功。

到这里,在Gradle模块化项目中引入非模块化的演示部分就结束了。

总结

虽然Gradle出来的时候也不短了,但相对Maven来说,用户量也少了不少。由于Maven的广泛使用,该踩的坑都被前人给踩了,使用Maven的时候,可以做到基本上不读文档,完全靠粘贴复制都能混日子,而Gradle则不一样,需要使用者深入的学习和研究,才能用起来得心应手。

posted @ 2020-06-26 16:14 八爻老骥 阅读(1189) 评论(0) 推荐(0) 编辑
摘要: 概述 什么是前端,简单讲就是在程序开发中,跟美工设计人员打交道比较多的部分。或者讲是展现给多数用户的操作界面部分,操作界面可以是实体的(比如遥控器、按键面片等),也可以是虚拟的(比如显示器里的各种窗口)。大多数情况下,我们使用的是虚拟界面,也就是利用计算机图形功能,在显示器中画出来供我们操作的部分。 阅读全文
posted @ 2020-05-20 22:28 八爻老骥 阅读(1973) 评论(0) 推荐(0) 编辑
摘要: 在没有ORM的时代,我们直接从数据库中返回完整的数据集,然后通过键值对取出相应字段的数据,当然更要需要,取出的数据还要转换成编程语言相应的类型,再进行数据的操作。这种方式存储数据干脆直接,还可以利用Sql语句进行查询的优化,有些复杂的查询逻辑还可以编写成存储过程,充分利用数据库的性能,降低客户端的压 阅读全文
posted @ 2020-05-08 21:05 八爻老骥 阅读(326) 评论(0) 推荐(0) 编辑
摘要: .Net Framework 4.5和.Net Core开始提供类似Office界面风格的控件。没事想抄个Windows自带的画图玩玩,Ribbon窗口往一套,倒也简单,只是细节方面有些不同,最明显的就是主菜单部分,画图里是扁平的形状,并且内容是用的文本。然而RibbonApplicationMen 阅读全文
posted @ 2020-05-03 22:41 八爻老骥 阅读(1002) 评论(0) 推荐(0) 编辑
摘要: 什么是多线程,这在相关计算机原理的书籍里都有介绍,通常所说的多线程是指进程内的多线程,由进程创建一个私有线程表,自行管理自己的线程,这样好处是线程阻塞了,只会挂起进程,而不会影响到整个操作系统的运行。每个线程都有自己的栈,每创建一个线程就会分配一定的资源给线程,这就是为什么说要谨慎使用线程,否则会造 阅读全文
posted @ 2020-05-01 17:40 八爻老骥 阅读(400) 评论(0) 推荐(0) 编辑
摘要: 前后端分离大概是指是HTML和服务器代码的分离,因为浏览器中解释执行的HTML+JS+CSS代码混合着包含的内容确实是不友好,于是就有人发明了代码分离的技术,比如asp.net的基于事件的codebehind,struts的mvc方式。再后来,为了更彻底地分离,前端直接做成了独立的程序包或应用,比如 阅读全文
posted @ 2020-04-28 22:16 八爻老骥 阅读(1945) 评论(0) 推荐(0) 编辑
摘要: DirectX的位置 老子云,道生一,一生二,二生三,三生万物。也就是所谓的九九归一,万变不离其宗,所有在计算上运行的程序,最终都是一条条在CPU上执行的二进制。计算机的硬件就是道,硬件的性能直接给出算计机的运算能力上限,操作系统就是道生出来的一,运行在系统下的各种编译环境、SDK就是一生出来的二, 阅读全文
posted @ 2020-04-27 10:18 八爻老骥 阅读(528) 评论(0) 推荐(0) 编辑
摘要: 简介 本文使用D3D绘制一个三角形,通过这个程序可以了解一下D3D的基本开发过程。 开发环境 系统:Windows 10 IDE:Visual Studio 2019 注意 本示例需要两个帮助文件 "点击下载" 开发步骤 创建窗口 1、新建一个空白C++项目,文件 新建 项目,语言选择C++,平台选 阅读全文
posted @ 2020-04-24 14:15 八爻老骥 阅读(1156) 评论(0) 推荐(0) 编辑
摘要: 要掌握计算机技术相关的技术,就一句话,叫说干就干。这里的干就是实践,而实践的基础就是照示例试一试,也就是所谓的是骡子是马,先拿出来溜一溜。学习DirectX同样是如此,微软为DirectX提供了很多示例,这些示例的项目代码都可以从GITHUB上下载得到。不过,掌握DirectX还是一件比较难的事情, 阅读全文
posted @ 2020-04-22 00:04 八爻老骥 阅读(532) 评论(0) 推荐(1) 编辑
摘要: 原理跟WPF版本的差不多,只是渲染的底层逻辑都要自己写。 UI部分使用了Direct2D和DirextWrite实现。 4月19日更新 增加复杂模型的渲染 ~~~ //部分实现代码 m_device GetWrappedDevice() AcquireWrappedResources(m_devic 阅读全文
posted @ 2020-04-13 23:37 八爻老骥 阅读(305) 评论(0) 推荐(0) 编辑
点击右上角即可分享
微信分享提示