踩坑:maven项目引入外部jar

踩坑:maven项目引入外部jar

项目中遇到一种场景,在编译源码时需要引入外部jar,此时有三种方式,即上传私服,上传本地仓库及在工程中直接引入。但是这三种方式均有坑!

容易踩坑的地方

  1. 通过将外部jar上传到私服与本地仓库,必须同时上传pom文件,否则引入不了外部jar依赖的jar包

    同时执行以下命令是正确用法

    要在本地存储库中安装 JAR,请使用以下命令:

    mvn install:install-file -Dfile=<path-to-file> -DgroupId=<group-id> -DartifactId=<artifact-id> -Dversion=<version> -Dpackaging=<packaging>

    如果还有 pom 文件,您可以使用以下命令安装它:

    mvn install:install-file -Dfile=<path-to-file> -DpomFile=<path-to-pomfile>
  2. 通过<scope>system</scope>引入的外部jar无法引入外部jar依赖jar包

搭建工程并解析

工程介绍

项目依赖关系

项目B

  • pom文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>B</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.example</groupId>
                <artifactId>C</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>
  • JAVA代码

    public class Main {
        public static void main(String[] args) {
            Hello.sayHello();
        }
    }

项目C

  • pom文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>C</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
    
    </project>
  • JAVA代码

    /**
     * @author sakura
     * @date: 2022/6/17 22:04
     * @description:
     */
    public class Hello {
        public static void sayHello() {
            System.out.println("hello");
        }
    }
    

验证:

项目B依赖项目C,观察一下三种A依赖B的方式,能否引用到C的静态方法

  1. 外部jar上传到私服与本地仓库,但不上传pom文件
  2. 通过<scope>system</scope>方式在工程中直接引入

外部jar上传到私服与本地仓库,但不上传pom文件

  • 项目Apom文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>A</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.example</groupId>
                <artifactId>B</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    </project>
  • 执行上传指令,这里使用本地仓库举例

    • 文件相对路径根位置,此时已经且换到B工程目录下。
    • -DgeneratePom=false:不自动生成pom文件。但即使自动生成的pom也带任何依赖,只有除依赖外其他信息。这里为了说明清晰就***不生成pom***了。
    mvn install:install-file -Dfile="target\B-1.0-SNAPSHOT.jar" -DgroupId="org.example" -DartifactId="B" -Dversion="1.0-SNAPSHOT" -Dpackaging="jar" -DgeneratePom=false
  • 此时切换到A工程下查看依赖树 mvn dependency:tree

    [INFO] ---------------------------< org.example:A >----------------------------
    [INFO] Building A 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [WARNING] The POM for org.example:B:jar:1.0-SNAPSHOT is missing, no dependency information available
    [INFO] 
    [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ A ---
    [INFO] org.example:A:jar:1.0-SNAPSHOT
    [INFO] \- org.example:B:jar:1.0-SNAPSHOT:compile
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  0.776 s
    [INFO] Finished at: 2022-06-17T22:56:55+08:00
    [INFO] ------------------------------------------------------------------------
    

    得出结论C的依赖没有被打包进来,自然无法调用。

通过<scope>system</scope>方式在工程中直接引入

  • 项目Apom文件

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.example</groupId>
        <artifactId>A</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <dependencies>
            <dependency>
                <groupId>org.example</groupId>
                <artifactId>B</artifactId>
                <version>1.0-SNAPSHOT</version>
                <scope>system</scope>
                <systemPath>${project.basedir}/lib/B-1.0-SNAPSHOT.jar</systemPath>
            </dependency>
        </dependencies>
    </project>
  • 项目根目录下创建lib文件夹并将打包好的B工程放进去

  • 此时切换到A工程下查看依赖树 mvn dependency:tree

    [INFO] ---------------------------< org.example:A >----------------------------
    [INFO] Building A 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ A ---
    [INFO] org.example:A:jar:1.0-SNAPSHOT
    [INFO] \- org.example:B:jar:1.0-SNAPSHOT:system
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  0.797 s
    [INFO] Finished at: 2022-06-17T23:07:41+08:00
    [INFO] ------------------------------------------------------------------------

    得出结论C的依赖没有被打包进来,自然无法调用。

正确用法

既要上传jar同时要上传POM文件

  • 切换到B工程目录下,执行

    mvn install:install-file -Dfile="target\B-1.0-SNAPSHOT.jar" -DgroupId="org.example" -DartifactId="B" -Dversion="1.0-SNAPSHOT" -Dpackaging="jar" -DgeneratePom=false
    mvn install:install-file -Dfile="pom.xml" -DgroupId="org.example" -DartifactId="B" -Dversion="1.0-SNAPSHOT" -Dpackaging="pom" -DgeneratePom=false
  • 此时切换到A工程下查看依赖树 mvn dependency:tree

    [INFO] ---------------------------< org.example:A >----------------------------
    [INFO] Building A 1.0-SNAPSHOT
    [INFO] --------------------------------[ jar ]---------------------------------
    [INFO] 
    [INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ A ---
    [INFO] org.example:A:jar:1.0-SNAPSHOT
    [INFO] \- org.example:B:jar:1.0-SNAPSHOT:compile
    [INFO]    \- org.example:C:jar:1.0-SNAPSHOT:compile
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  0.824 s
    [INFO] Finished at: 2022-06-17T23:23:14+08:00
    [INFO] ------------------------------------------------------------------------
  • 得出结论C的依赖被打包进来,可以调用