粗枝大叶记录一下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也得升级,用最新版总是没错。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!