Maven 引入普通jar 操作方式

device-http-server\lib\api-client-1.0.0.jar

我这里有个Jar

怎么引入到项目之中 ideaJ

先看一下 device-http-server 是 Maven 还是 Gradle 工程,好给你对应的引入方式。

你的 device-http-server 是 Maven (Spring Boot) 工程,所以引入本地 jar 要走 pom,而不是 IDEA 的 Project Structure 手动加(Maven 工程里手动加的模块依赖会在每次 reimport 时被覆盖)。

而且我看你的 pom 里已经为这个 jar 铺好路了:

  • 第 73-77 行有一段被注释的依赖,正是这个 jar:

    XML 复制代码
    <!--        <dependency>-->
    <!--            <groupId>com.m2m.iotplatform</groupId>-->
    <!--            <artifactId>api-client</artifactId>-->
    <!--            <version>1.0.0</version>-->
    <!--        </dependency>-->
  • 第 180-181 行 spring-boot-maven-plugin 已经配了 <includeSystemScope>true</includeSystemScope>,这正是为了把 system scope 的本地 jar 打进最终 fat jar。

  • 所以推荐用 方式一(system scope),和你现有配置最契合。

方式一:system scope(最省事,符合你现有配置)

<dependencies> 里加(可以直接替换那段注释):

XML 复制代码
<dependency>
    <groupId>com.m2m.iotplatform</groupId>
    <artifactId>api-client</artifactId>
    <version>1.0.0</version>
    <scope>system</scope>
    <systemPath>${project.basedir}/lib/api-client-1.0.0.jar</systemPath>
</dependency>
  • ${project.basedir}/lib/... 对应 device-http-server\lib\api-client-1.0.0.jar,用相对路径,换机器也不会失效。
  • 因为已有 includeSystemScope=truemvn package 打出来的 jar 会包含它,运行时不会缺类。
  • 加完后在 IDEA 右侧 Maven 面板点「刷新/Reload」(或 Ctrl+Shift+O)让它重新加载依赖。

注意:system scope 不会处理这个 jar 自身的传递依赖;如果 api-client 内部还依赖别的库,需要你另外手动在 pom 里补上。

XML 复制代码
 <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
复制代码
<includeSystemScope>true</includeSystemScope>

方式二:安装到本地 Maven 仓库(更规范,推荐长期用)

先执行一次安装命令(IDEA 下方 Terminal 里):

XML 复制代码
mvn install:install-file -Dfile="E:\workproject\microservices\service\device-http-server\lib\api-client-1.0.0.jar" -DgroupId=com.m2m.iotplatform -DartifactId=api-client -Dversion=1.0.0 -Dpackaging=jar

然后在 pom 里加普通依赖(不要 scope/systemPath):

XML 复制代码
<dependency>
    <groupId>com.m2m.iotplatform</groupId>
    <artifactId>api-client</artifactId>
    <version>1.0.0</version>
</dependency>
  • 这样它就是个正常依赖,IDEA 索引、打包都更干净。
  • 缺点:每台开发机/CI 都得先跑一次 install:install-file(除非你们有私服 Nexus,可以改成 deploy 上传共享)。

两种怎么选

  • 只是本地跑通、jar 跟着项目走 → 方式一(你 pom 已经配好了,加 4 行即可)。
  • 团队协作 / 有私服 / 想要干净的依赖管理 → 方式二(或上传到 Nexus 私服后当普通依赖用)。

下面把两种方式整理清楚,最后回答你那个「lib 目录」的问题。

方式一:直接引用本地 jar 文件(system scope,不用安装)

不往任何仓库放,pom 里直接指向项目内的 jar 路径:

XML 复制代码
<dependency>

<groupId>com.m2m.iotplatform</groupId>

<artifactId>api-client</artifactId>

<version>1.0.0</version>

<scope>system</scope>

<systemPath>${project.basedir}/lib/api-client-1.0.0.jar</systemPath>

</dependency>

要点:

  • ${project.basedir}/lib/... 用相对路径,jar 跟着项目走(你现在 jar 就在 device-http-server\lib\ 下,正好对应)。
  • 打包能带上它的前提:spring-boot-maven-plugin 要配 <includeSystemScope>true</includeSystemScope>------你 pom 第 180-181 行已经有了,所以 mvn package 出来的 fat jar 会包含它。
  • 局限:不解析这个 jar 自己的传递依赖。如果 api-client 内部还依赖别的库,得你手动在 pom 里补;scope=system 也被 Maven 官方视为「不推荐、已半废弃」的用法,只适合临时/内部 jar。

适合:本地快速跑通、jar 想随项目一起提交进 git。

方式二:安装/推送到仓库,再当普通依赖用

2a. 装到本机本地仓库(~/.m2

IDEA 下方 Terminal 执行一次:

XML 复制代码
mvn install:install-file -Dfile="E:\workproject\microservices\service\device-http-server\lib\api-client-1.0.0.jar" -DgroupId=com.m2m.iotplatform -DartifactId=api-client -Dversion=1.0.0 -Dpackaging=jar

2b. 推送到远程私服(有 Nexus/Artifactory 时)

XML 复制代码
mvn deploy:deploy-file -Dfile="...\api-client-1.0.0.jar" -DgroupId=com.m2m.iotplatform -DartifactId=api-client -Dversion=1.0.0 -Dpackaging=jar -Durl=<私服仓库地址> -DrepositoryId=<settings.xml里配的server id>

装好后,pom 里就写成普通依赖(不要 scope/systemPath):

XML 复制代码
<dependency>
    <groupId>com.m2m.iotplatform</groupId>
    <artifactId>api-client</artifactId>
    <version>1.0.0</version>
</dependency>

要点:

  • 这才是「正规」做法,IDEA 索引、打包、传递依赖都正常。
  • 2a 的缺点:每台开发机/CI 都得先跑一次 install:install-file;2b 上传私服后全团队共享,最干净。

适合:长期维护、团队协作、CI 构建。

关于「Maven 能不能像普通 Java 项目那样放个 lib 目录混着用」

不能像 IDEA 纯 Java 项目那样自动用。 原因在于两者的 classpath 来源不同:

  • 纯 Java / IDEA 项目:classpath 是 IDE 的「模块设置」说了算,你在 Project Structure → Modules → Dependencies 里手动加一个 lib 文件夹或 jar,IDE 就放进 classpath。
  • Maven 项目:classpath 完全由 pom.xml 声明、并从「仓库」解析出来的依赖决定。Maven 没有「自动扫描某个 lib 目录」的机制,你把 jar 丢进任何文件夹它都不会自己认。

由此衍生两个常见误区:

  1. 在 IDEA 里手动给 Maven 模块加 library:当下能编译能运行,但

    • 一旦点 Maven「Reload/Reimport」,IDEA 会按 pom 重算依赖,你手加的会被清掉;
    • 命令行 mvn compile/package 根本不认,CI 上会编译失败。 所以对 Maven 工程不可靠。
  2. 想要「lib 目录」体验的正解就是上面的方式一(system + systemPath 指向 lib 里的 jar),这是 Maven 里最接近「项目内放个 lib 文件夹」的写法。但它不处理传递依赖、且不被推荐。

一句话:Maven 工程一切以 pom 为准。要么用 system scope 指到本地文件(方式一),要么把 jar 喂进本地/远程仓库再当普通依赖(方式二)。直接丢 lib 目录让 Maven 自动加载------做不到。

简短回答:不是非要 system,而是「直接指向本地 jar 文件」这种写法只能配 system。 想用默认 scope,就得先把 jar 装进仓库(方式二)。

scope 是什么

scope(依赖范围)控制三件事:这个依赖在哪些 classpath 生效(编译/运行/测试)、会不会被打包、会不会传递给依赖你的人。常见几种:

为什么直接引文件必须用 system

关键点:systemPathsystem 是绑定的一对,必须一起用。

  • compile/默认 scope 的依赖,Maven 一定会去仓库(本地 ~/.m2 或远程私服)按 groupId:artifactId:version 找 jar。
  • 你那个 jar 还没进任何仓库,只是躺在 lib/ 目录里。用默认 scope,Maven 在仓库里找不到,就会直接报错:

Could not find artifact com.m2m.iotplatform:api-client:jar:1.0.0

  • 只有 system scope 才允许你写 systemPath 把 Maven 直接指到磁盘上那个文件,跳过仓库查找。

所以「不安装、直接指文件」= 必须 system;这是它唯一的用途。

想用默认 scope 怎么办

那就走方式二:先把 jar 装进仓库,之后写普通依赖(不写 scope 就是默认 compile),也不要 systemPath:

XML 复制代码
mvn install:install-file -Dfile="...\api-client-1.0.0.jar" -DgroupId=com.m2m.iotplatform -DartifactId=api-client -Dversion=1.0.0 -Dpackaging=jar
XML 复制代码
<dependency>
    <groupId>com.m2m.iotplatform</groupId>
    <artifactId>api-client</artifactId>
    <version>1.0.0</version>
    <!-- 不写 scope,默认就是 compile -->
</dependency>

一句话总结

  • systemPath 直接指本地文件 → 只能 system,且要 includeSystemScope=true 才能打进包、还不管传递依赖。
  • 想用默认 compile scope(更干净、能处理传递依赖)→ 先 install/deploy 进仓库,再当普通依赖写。

简言之:system 不是「更好」,只是「不安装就想引文件」的唯一选择;正规做法是方式二 + 默认 scope。

对,是这样。

  • 普通依赖(compile/runtime scope,从仓库解析的):Spring Boot 的 spring-boot-maven-plugin 打 fat jar 时默认就会把它们打进去,不需要 includeSystemScope
  • includeSystemScope=true 只为 system scope 服务:因为插件默认会排除 system scope 的依赖(觉得它是"环境自带的"),所以只有用方式一(systemPath 指本地文件)时,才必须加这一行才能把那个本地 jar 打进包。

所以:

最后生成指令

XML 复制代码
mvn deploy:deploy-file ^
  -Dfile="D:\environment\maven\tigeriotmavenlib\api-http-client\api-client-1.0.0.jar" ^
  -DgroupId=com.m2m.iotplatform ^
  -DartifactId=api-client ^
  -Dversion=1.0.0 ^
  -Dpackaging=jar ^
  -DrepositoryId=tiger-iot-maven-repository ^
  -Durl=http://nexus.tigeriot.com/repository/maven-releases/