粗枝大叶记录一下java9模块化改造一个项目的过程(Jigsaw)
假设项目结构如下:

其中的依赖关系为

我实际用的jdk是17
1. common模块创建描述文件,在common的src/main/java下创建module-info.java, 内容默认
/**
* nangang-efficiency-backend
*
* @author weixiaodongA
* @date 2022-07-08 10:41
*/
module nangang.efficiency.backend.common {
}
2. 编译项目,报错类似
java: 程序包 org.apache.commons.lang3.math 不可见
(程序包 org.apache.commons.lang3.math 已在未命名模块中声明,但模块 nangang.efficiency.backend.common 未读取它)
3. 静态引入三方包。修改描述文件
module nangang.efficiency.backend.common {
requires org.apache.commons.lang3;
requires static lombok;
}
重新编译看到大部分相关报错已经消失。
lombok前面有static是因为只有编译期用到,运行时用不到。
点击lombok这个模块可以看到lombok已经定义了自己的描述文件
module lombok {
requires java.compiler;
requires java.instrument;
requires jdk.unsupported;
exports lombok;
exports lombok.experimental;
exports lombok.extern.apachecommons;
exports lombok.extern.flogger;
exports lombok.extern.jackson;
exports lombok.extern.java;
exports lombok.extern.jbosslog;
exports lombok.extern.log4j;
exports lombok.extern.slf4j;
exports lombok.launch to
lombok.mapstruct;
provides javax.annotation.processing.Processor with
lombok.launch.AnnotationProcessorHider.AnnotationProcessor;
}
4. 现在依然有内部模块引用报错,比如
java: 程序包 top.rdfa.framework.biz.base 不可见
(程序包 top.rdfa.framework.biz.base 已在未命名模块中声明,但模块 nangang.efficiency.backend.common 未读取它)
修改描述文件为
module nangang.efficiency.backend.common {
requires org.apache.commons.lang3;
requires static lombok;
requires rdfa.biz;
}
jar包叫啥名,引入的时候就写啥。
5. 相应的引入其他依赖,最后common模块如下
module nangang.efficiency.backend.common {
requires org.apache.commons.lang3;
requires static lombok;
requires hutool.all;
requires slf4j.api;
requires rdfa.biz;
}
目前编译正常
7. 移除client和facade模块,用不到
8. 为dal模块增加描述文件,并编译,报错
java: 程序包 com.zaxxer.hikari 不可见
(程序包 com.zaxxer.hikari 已在未命名模块中声明,但模块 nangang.efficiency.backend.dal 未读取它)
java: 程序包 org.springframework.beans.factory.annotation 不可见
(程序包 org.springframework.beans.factory.annotation 已在未命名模块中声明,但模块 nangang.efficiency.backend.dal 未读取它)
9. 修改描述文件(幸亏idea有提示,不然还真不知模块名都写啥)
module nangang.efficiency.backend.dal {
requires com.zaxxer.hikari;
requires spring.beans;
requires spring.boot.starter.jdbc;
requires spring.jdbc;
}
依然报错
java: 程序包 org.springframework.boot.autoconfigure.jdbc 不可见
(程序包 org.springframework.boot.autoconfigure.jdbc 已在未命名模块中声明,但模块 nangang.efficiency.backend.dal 未读取它)
增加了 requires spring.boot.autoconfigure;解决。
10. 一直修改到下面这样,报错才变成内部引入问题
module nangang.efficiency.backend.dal {
requires com.zaxxer.hikari;
requires mybatis;
requires mybatis.spring;
requires spring.core;
requires spring.beans;
requires spring.boot.starter.jdbc;
requires spring.jdbc;
requires spring.boot.autoconfigure;
requires spring.boot;
requires spring.context;
requires java.sql;
}
这时候报内部依赖错
java: 程序包 cn.enn.efficiency.screen.nangang.common.po 不可见
(程序包 cn.enn.efficiency.screen.nangang.common.po 已在未命名模块中声明,但模块 nangang.efficiency.backend.dal 未读取它)
意思是common包没有引进来。common已经改造成具名模块了,所以requires nangang.efficiency.backend.common;引进来。
11. 引进来以后依然报错,还需要导出可访问的类
修改common模块的描述文件,增加exports
module nangang.efficiency.backend.common {
requires org.apache.commons.lang3;
requires static lombok;
requires hutool.all;
requires slf4j.api;
requires rdfa.biz;
exports cn.enn.efficiency.screen.nangang.common.po;
exports cn.enn.efficiency.screen.nangang.common.util;
}
jigsaw不允许通过通配符来导出,你必须明确指出哪个包可以被外部访问,不能用*号。
编译继续报错:
java: 程序包 lombok.extern.slf4j 不可见
(程序包 lombok.extern.slf4j 已在模块 lombok 中声明, 但模块 nangang.efficiency.backend.dal 未读取它)
12. 修改common模块传递依赖
现在dal模块报错说lombok不能访问,但是common模块已经有了。所以修改为传递依赖,不再报错
module nangang.efficiency.backend.common {
requires org.apache.commons.lang3;
requires transitive static lombok;
requires hutool.all;
requires slf4j.api;
requires rdfa.biz;
exports cn.enn.efficiency.screen.nangang.common.po;
exports cn.enn.efficiency.screen.nangang.common.util;
}
注意Lombok前面增加了transitive。
13. 修复dal模块的其他问题
最后的dal模块描述文件是
module nangang.efficiency.backend.dal {
requires com.zaxxer.hikari;
requires mybatis;
requires mybatis.spring;
requires spring.core;
requires spring.beans;
requires spring.boot.starter.jdbc;
requires spring.jdbc;
requires spring.boot.autoconfigure;
requires spring.boot;
requires spring.context;
requires org.apache.commons.collections4;
requires java.sql;
requires nangang.efficiency.backend.common;
}
目前编译正常
14. 给core-service增加模块描述文件
编译,报错
java: 程序包 cn.hutool.core.bean 不可见
(程序包 cn.hutool.core.bean 已在模块 hutool.all 中声明, 但模块 nangang.efficiency.backend.core.service 未读取它)
core是依赖dal和common的,所以修改dal描述文件,将common该为传递依赖,并给core增加dal依赖
module nangang.efficiency.backend.dal {
// 其他依赖
requires transitive nangang.efficiency.backend.common;
}
然后到common模块修改hutool为传递依赖(此时会有警告,不用管它。实际上,对于公共的依赖,可以一上来就指明是可传递的),增加导出(下面这些都是一个一个加上去的,遇到一个报错就加一个,不是一次性)
module nangang.efficiency.backend.common {
requires transitive org.apache.commons.lang3;
requires transitive hutool.all;
requires slf4j.api;
requires transitive rdfa.biz;
//其他导入导出
exports cn.enn.efficiency.screen.nangang.common.constants;
exports cn.enn.efficiency.screen.nangang.common.enums;
}
到dal模块增加导出(有没有觉得这个过程很有意思,如果你是手动一步步来的话),并且增加了传递依赖
requires transitive spring.core;
requires transitive spring.beans;
requires spring.boot.starter.jdbc;
requires spring.jdbc;
requires transitive spring.boot.autoconfigure;
requires transitive spring.boot;
requires transitive spring.context;
requires transitive org.apache.commons.collections4;
exports cn.enn.efficiency.screen.nangang.dal.mapper.main;
exports cn.enn.efficiency.screen.nangang.dal.po.main;
继续修复core其他问题,增加
requires easypoi.annotation;
requires easypoi.base;
requires pagehelper;
requires spring.tx;
requires spring.data.redis;
requires com.google.common;
requires poi;
requires poi.ooxml;
requires transitive spring.web;
requires transitive javax.servlet.api;
requires java.annotation;
requires org.codehaus.groovy;
15. 解惑:到这里不知道有没有人有疑问,写这么复杂,是不是maven中的依赖可以去掉了?
实际上,maven是用来定位jar包的,jigsaw是用来查找模块的。
不使用maven,我们就需要自己找到一大堆jar包(而且是特定版本的)放到classpath下面;
而使用Jigsaw,我们可以严格控制一个类能够被谁使用。
假如我们把依赖从pom中删掉而只保留模块描述,编译时模块描述文件会报错:
java: 找不到模块: nangang.efficiency.backend.dal
16. 给biz-service增加模块描述文件
这个项目没用到这个模块,跳过或者删掉
17. 给integration增加模块描述文件
编译报错,增加core模块的依赖
requires fastjson;
requires nangang.efficiency.backend.core.service;
回到Core增加导出
exports cn.enn.efficiency.screen.nangang.core.service;
这时候Lombok会报错
java: 程序包 lombok.extern.slf4j 不可见
(程序包 lombok.extern.slf4j 已在模块 lombok 中声明, 但模块 nangang.efficiency.backend.dal 未读取它)
可以回到core这将dal改成传递依赖,但是只是为了引入一个Lombok就把dal全给了integration并不合适。我们可以再引入一次lombok就好了。
实际上dal里有太多其他地方需要的依赖写成了transitive,多数都不应该传递
requires transitive nangang.efficiency.backend.dal;
18. 给processor增加模块描述文件
增加core依赖
module nangang.efficiency.backend.processor {
requires nangang.efficiency.backend.core.service;
}
编译,大片报错
java: 未命名的模块同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 未命名的模块同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 未命名的模块同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 未命名的模块同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 hutool.all 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 hutool.all 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 hutool.all 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 hutool.all 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 org.apache.commons.collections4 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 org.apache.commons.collections4 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 org.apache.commons.collections4 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 org.apache.commons.collections4 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.context 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.context 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.context 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.context 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.boot 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.boot 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.boot 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.boot 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.boot.autoconfigure 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.boot.autoconfigure 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.boot.autoconfigure 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.boot.autoconfigure 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.beans 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.beans 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.beans 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.beans 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 javax.servlet.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 javax.servlet.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 javax.servlet.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 javax.servlet.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.web 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.web 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.web 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.web 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 slf4j.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 slf4j.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 slf4j.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 slf4j.api 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.boot.starter.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.boot.starter.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.boot.starter.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.boot.starter.jdbc 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 mybatis.spring 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 mybatis.spring 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 mybatis.spring 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 mybatis.spring 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 mybatis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 mybatis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 mybatis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 mybatis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 org.codehaus.groovy 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 org.codehaus.groovy 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 org.codehaus.groovy 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 org.codehaus.groovy 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 java.annotation 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 java.annotation 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 java.annotation 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 java.annotation 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 poi.ooxml 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 poi.ooxml 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 poi.ooxml 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 poi.ooxml 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 poi 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 poi 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 poi 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 poi 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 com.google.common 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 com.google.common 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 com.google.common 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 com.google.common 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.data.redis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.data.redis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.data.redis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.data.redis 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 spring.tx 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 spring.tx 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 spring.tx 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 spring.tx 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 pagehelper 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 pagehelper 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 pagehelper 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 pagehelper 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 easypoi.base 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 easypoi.base 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 easypoi.base 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 easypoi.base 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
java: 模块 org.apache.tomcat.embed.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet
java: 模块 org.apache.tomcat.embed.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.http
java: 模块 org.apache.tomcat.embed.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.descriptor
java: 模块 org.apache.tomcat.embed.core 同时从 javax.servlet.api 和 org.apache.tomcat.embed.core 读取程序包 javax.servlet.annotation
看着意思是说javax.servlet.api和org.apache.tomcat.embed.core提供了相同的东西,冲突了,必须解决的样子。
19. 排除多余依赖
搜索HttpServletResponse,发现的确有两个jar都提供了这个接口,就是上面报错中的两个jar。tomcat是spring-web提供的,不能排除,启动的时候需要用到tomcat,所以去定位servlet-api这个jar。
一共有四处提供javax.servlet-api.jar,每次排除一处记得要立即编译一下,免得出问题。
排除过程中发现,core里面有个工具cn.enn.efficiency.screen.nangang.core.service.util.HttpUtil用到了里面的类,所以需要给core增加tomcat的依赖:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
并引入模块
requires org.apache.tomcat.embed.core;
20. 继续修复报错
在core模块导出实现包
exports cn.enn.efficiency.screen.nangang.core.service.impl;
在processor模块引入包
requires rdfa.concurrent.api;
requires rdfa.timer.client;
编译正常!
21. 调整代码中另类引入
在上一步中,其实我改了一些代码,把@Resource都改成了@Autowire。当时的开发者可能觉得@Autowire没法指定具体bean,于是使用了@Resource,这样就需要额外一个引用tomcat-annotion-api。
还有core中引入的groovy,应该也没必要。这里尝试去掉。
先去掉模块描述,这样编译报错,去修复:
requires java.annotation;
// requires org.codehaus.groovy;
requires org.apache.tomcat.embed.core;
将其中用到的groovy的Tuple2用Hutool的import cn.hutool.core.lang.Tuple;代替,虽然不太好用,不过想不起来spring自带的那个<left, right>类叫啥名了。
删掉多余的maven依赖。
22. 给web模块增加描述文件
给web增加core依赖
requires nangang.efficiency.backend.core.service;
requires org.aspectj.runtime;
requires com.fasterxml.jackson.core;
requires spring.webmvc;
requires java.annotation;
requires java.validation;
requires java.sql;
requires swagger.annotations;
requires springfox.core;
requires springfox.spring.web;
requires rdfa.auth.client;
requires rdfa.auth.facade;
通过编译发现问题,给common模块增加导出
exports cn.enn.efficiency.screen.nangang.common.annotations;
exports cn.enn.efficiency.screen.nangang.common.enetity;
给core增加导出
exports cn.enn.efficiency.screen.nangang.core.service.bo;
exports cn.enn.efficiency.screen.nangang.core.service.util;
23. 给starter增加模块描述
module nangang.efficiency.backend.starter {
requires nangang.efficiency.backend.web;
requires nangang.efficiency.backend.processor;
requires nangang.efficiency.backend.integration;
requires rdfa.actuator;
requires spring.cloud.commons;
requires spring.cloud.openfeign.core;
requires slf4j.api;
}
24. 目前编译启动正常
但是几乎不能保证功能没问题,因为jigsaw有个特性是运行时用到的类也要引进来。我猜这种类应该不少。
QA
如果编译不能通过,提示跟Java模块化暴露有相关问题咋办?
项目里面用了很多框架,需要他们支持Java17才行(你用的9就支持9)。比如Springboot需要2.5.7以上,相应的SpringCloud也得配套;Lombok也得升级,用最新版总是没错。
粗枝大叶记录一下java9模块化改造一个项目的过程(Jigsaw)的更多相关文章
- 使用 GNU autotools 改造一个软件项目
使用 GNU autotools 改造一个软件项目 及永刚 jungle@soforge.com 2006 年 3 月 24 日 版本:0.3 本文不是一篇规范的教程,而是用一个软件项目作为例子,演 ...
- 记录心得-IntelliJ iDea 创建一个maven管理的的javaweb项目
熟能生巧,还是记录一下吧~ 开始! 第一步:File--New--Project--Maven--Create from archetype--maven-archetype-webapp 第二步:解 ...
- 记录一次从linux移动一个项目到windows遇到的问题
前言 这几天在linux平台写了一个垃圾软件,浪费了我10多天的时间,感觉很垃圾,然后我想在windows平台打包这个软件,然后出现了一个项目中有相同文件名的问题,导致一些文件相互覆盖 问题描述 我把 ...
- node.js入门学习(五)--Demo模块化改造
1.node.js中模块的分类 1)node.js内置模块(核心,原生) 所有内置模块在安装node.js时就已经编译成二进制文件,可以直接加载运行(速度较快),部分内置模块,在node.exe这个进 ...
- java9 模块化 jigsaw
java9并没有在语言层面做出很多改变,而是致力于一些新特性,如模块化,其核心就是解决历史遗留问题,为以后的jar包森林理清道路.模块化是一个很大的命题,就不讲那么细致了,关于java9的特性也有很多 ...
- vuex : 模块化改造
我们知道,vuex是vue技术栈中很重要的一部分,是一个很好用的状态管理库. 如果你的项目没有那么复杂,或者对vuex的使用没有那么重度,那么,是用不着modules功能的. 但如果你写着写着就发现你 ...
- 一个项目涉及到的50个Sql语句(整理版)
/* 标题:一个项目涉及到的50个Sql语句(整理版) 说明:以下五十个语句都按照测试数据进行过测试,最好每次只单独运行一个语句. */ --1.学生表Student(S,Sname,Sage,Sse ...
- JAVA9模块化详解(一)——模块化的定义
JAVA9模块化详解 前言 java9已经出来有一段时间了,今天向大家介绍一下java9的一个重要特性--模块化.模块化系统的主要目的如下: 更可靠的配置,通过制定明确的类的依赖关系代替以前那种易错的 ...
- JAVA9模块化详解(二)——模块的使用
JAVA9模块化详解(二)--模块的使用 二.模块的使用 各自的模块可以在模块工件中定义,要么就是在编译期或者运行期嵌入的环境中.为了提供可靠的配置和强健的封装性,在分块的模块系统中利用他们,必须确定 ...
- .Net Core ORM选择之路,哪个才适合你 通用查询类封装之Mongodb篇 Snowflake(雪花算法)的JavaScript实现 【开发记录】如何在B/S项目中使用中国天气的实时天气功能 【开发记录】微信小游戏开发入门——俄罗斯方块
.Net Core ORM选择之路,哪个才适合你 因为老板的一句话公司项目需要迁移到.Net Core ,但是以前同事用的ORM不支持.Net Core 开发过程也遇到了各种坑,插入条数多了也特别 ...
随机推荐
- 09. C语言内嵌汇编代码
C语言函数内可以自定义一段汇编代码,在GCC编译器中使用 asm 或 __asm__ 关键词定义一段汇编代码,并可选添加volatile关键字,表示不要让编译器优化这段汇编代码. 内嵌汇编代码格式如下 ...
- android中Room数据库的基本使用
简介: 还在使用原生的sqllite?有这么清爽且稳如狗的room为啥不用呢? Room是Google官方推荐使用的数据库,相比较某些优秀数据库框架来说,不用过于担心某天库会停止维护,且访问数据库非常 ...
- 数据库—ER模型概念设计
文章目录 ER模型的概念 如何画ER图 ER图转换为关系数据库 ER模型的概念 实体 画图时用方形表示 属性 用椭圆形表示 关系 用菱形表示 主键(主码) 在主属性下面画划线 外键(外码) 这里一般是 ...
- SSMS表设计器显示说明(注释)字段
原文地址:https://www.giantliu.cn/2020/09/14/200914SSMSTableDesignAddDescription/ SQL Server Management S ...
- CentOS7 防火墙(firewall)的命令详解
复制代码 安装:yum install firewalld 1.firewalld的基本使用 启动: systemctl start firewalld 查看状态: systemctl status ...
- webapi动态创建后台任务(使用排队的后台任务)
很多时候我们都会使用后台定时任务,但有些任务不需要定时执行,只需要请求到来时执行一次,比如请求服务器到某个地方同步数据,但请求不需要等数据同步完成再响应.这时候就可以使用排队的后台任务. 基本原理是用 ...
- Istio(八):istio安全之认证,启用mTLS
目录 一.模块概览 二.系统环境 三.istio认证 3.1 证书创建与轮换 3.2 对等认证和请求认证 3.2.1 对等认证 3.2.2 请求认证 3.3 mTLS 3.3.1 双向 TLS 3.3 ...
- Android 12(S) Binder(三)
学以致用,这一节来native binder实战! android 12中的service用到的Bp.Bn文件多由aidl生成,所以实战中也用aidl来生成. 1.文件目录结构 文件目录结构如上,偷懒 ...
- Easysearch 内核完善之 OOM 内存溢出优化案例一则
最近某客户在使用 Easysearch 做聚合时,报出 OOM 导致掉节点的问题,当时直接让客户试着调整 indices.breaker.request.limit ,但是不起作用,于是又看了下 Ea ...
- SMB3.0多通道叠加双网卡提速
SMB3.0多通道叠加双网卡提速 (双网卡.多网卡,NAS,局域网共享速度) WIN8及以上是默认开启的.(WIN10.WIN11 默认开启) 只需要同规格的网卡,比如你一张是1Gbps的,另一张网卡 ...