粗枝大叶记录一下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 开发过程也遇到了各种坑,插入条数多了也特别 ...
随机推荐
- Linux grep根据关键字匹配前后几行
在Linux环境下,查看文件内容时,很多时候需要查看指定关键字的前后几行,如查看日志文件时,如果日志文件太大,想直接在Linux 终端中查看,可以grep 'partten' filename 进行过 ...
- linux基础命令及bash shell特性
linux基础命令及bash shell特性 目录 linux基础命令及bash shell特性 1.linux基础命令 1.1 查看内核版本和linux发行版本 1.2 查看服务器硬件信息 1.3 ...
- element-ui使用el-date-picker日期组件常见场景
开始 最近一直在使用 element-ui中的日期组件. 所以想对日期组件常用的做一个简单的总结: 1.处理日期组件选择的时候面板联动问题 2.限制时间范围 解除两个日期面板之间的联动 我们发现2个日 ...
- web页面打开直接调用vlc播放视频
简介 大家都知道现在我们在网页所播放的视频都是h264编码格式,可以供所有设备正常播放.然而,相比h265它的体积更大.质量更差.目前h265大多应用于安防,体积小可以更好的存储,不过它也有着缺点,成 ...
- 促双碳|AIRIOT智慧能源管理解决方案
随着"双碳"政策和落地的推进,各行业企业围绕实现碳达峰和碳中和为目标,逐步开展智能化能源管理工作,通过能源数据统计.分析.核算.监测.能耗设备管理.碳资产管理等多种手段,对能源 ...
- C++ Virtual Functions
Virtual这个关键字在多态中扮演一个绝对重要的角色,只要member functions声明的前面加上virtual的关键字,他就会成为 Virtual member functions.任何一个 ...
- Vue3.0极速入门(二) - 目录和文件说明
目录结构 以下文件均为npm create helloworld自动生成的文件目录结构 目录截图 目录说明 目录/文件 说明 node_modules npm 加载的项目依赖模块 src 这里是我们要 ...
- ftp和tftp有什么区别
TFTP和FTP都是文件传输协议,但它们在很多方面存在明显的区别. 安全性:FTP协议使用的是明文传输,而TFTP协议使用的是UDP协议,没有使用TCP,所以不提供验证. 传输方式:FTP协议使用的是 ...
- SRE 必备利器:域名 DNS 探测排障工具
问题背景 访问某个 HTTP 域名接口,偶发性超时,原因可能多种多样,比如 DNS 解析问题.网络质量问题.对端服务负载问题等,在客户端没有良好埋点的情况下,排查起来比较费劲,只能挨个方向尝试,这里送 ...
- 使用 OpenTelemetry 构建可观测性 01 - 介绍
毫无疑问,在过去几年里,你可能已经多次听到过可观测性这个词.对于很多人来说,很难理解这个词的真正含义.对许多人来说,他们错误地将其等同于"监控".虽然可观测性的根本定义以及它所包含 ...