文章目录

  • 说明
  • java相关的插件
  • scala相关的插件
  • maven命令打包
  • 创建项目
  • 分别指定java和scala的source root路径
  • 编辑pom文件
  • 执行命令
  • 运行jar
  • idea打包
  • 参考资料
  • maven-shade-plugin
  • resource transformers


说明

一开始用的是在idea中打包的方式,但是在更新项目结构或是更新依赖后,需要手动的去修改原来的配置,不是很方便。于是查找资料看下用maven命令如何打包

java相关的插件

java代码编译与打包,我参考了这篇文章的内容,介绍的很详细:
需要引入的插件为maven-compiler-plugin(java编译插件)、maven-shade-plugin(java打包插件,用于将个人代码和第三方依赖打包到一个jar包中)

maven-shade-plugin 插件提供了两个能力:
把整个项目(包含它的依赖)都打包到一个 “uber-jar” 中
shade - 即重命名某些依赖的包
由此引出了两个问题:
什么是 uber-jar ?
uber-jar 也叫做 fat-jar 或者 jar-with-dependencies,意思就是包含依赖的 jar。
什么是 shade ?
shade 意为遮挡,在此处可以理解为对依赖的 jar 包的重定向(主要通过重命名的方式)。

如果要将个人代码和第三方依赖分开打包需要使用maven-jar-plugin、maven-dependency-plugin,可以参照这篇文章

scala相关的插件

scala代码编译与打包,我参考了这篇文章的内容,https://www.jianshu.com/p/461671002589 需要引入的插件为maven-scala-plugin(scala编译插件)

maven命令打包

创建项目

java写的项目能打包成安装包吗 java项目编译打包_java


java写的项目能打包成安装包吗 java项目编译打包_java写的项目能打包成安装包吗_02


在main路径下新增Diractory 并命名为scala,然后修改属性为source root

java写的项目能打包成安装包吗 java项目编译打包_java_03

分别指定java和scala的source root路径

最初我的scala和java代码都放在java这个source root下,然后使用maven编译、打包时也顺利执行,但是在本地cmd中通过java -jar 或java -classpath运行jar包时总是提示找不到或无法加载主类 然后我将scala和java代码拆分后再打包,这个问题就没有出现了,用java -jar 或java -classpath运行jar包都可以正常得到输出。

java写的项目能打包成安装包吗 java项目编译打包_scala_04


添加package,分别创建java、scala 方法

java写的项目能打包成安装包吗 java项目编译打包_maven_05


scala 中main方法需定义在object 中,否则java -jar中运行时会提示

java写的项目能打包成安装包吗 java项目编译打包_scala_06

java写的项目能打包成安装包吗 java项目编译打包_java写的项目能打包成安装包吗_07

编辑pom文件

添加依赖、添加插件
完整pom文件如下所示
和编译、打包相关的配置都在<build> </build>标签内

<?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>com.my</groupId>
    <artifactId>test-package</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- 在这里定义你的入口类 -->
        <mainClass>com.chinalife.sfrs.scala.gscRenewalPolicyDataParsing</mainClass>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <scala.version>2.11.0</scala.version>
        <spark.version>2.4.0-cdh6.3.0</spark.version>
        <spark_scala.version>2.11</spark_scala.version>
        <hadoop.version>3.0.0-cdh6.3.0</hadoop.version>
        <hive.version>2.1.1-cdh6.3.0</hive.version>
        <log4j2.version>2.11.2</log4j2.version>
        <hutool.version>5.6.7</hutool.version>
    </properties>

    <repositories>
        <repository>
            <id>alimaven</id>
            <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
        </repository>
        <repository>
            <id>alimaven2</id>
            <url>https://maven.aliyun.com/repository/public</url>
        </repository>

        <repository>
            <id>cloudera</id>
            <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_${spark_scala.version}</artifactId>
            <version>${spark.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>jcl-over-slf4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.spark/spark-sql -->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_${spark_scala.version}</artifactId>
            <version>${spark.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.scala-lang/scala-actors -->
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-actors</artifactId>
            <version>2.11.12</version>
        </dependency>

        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-library</artifactId>
            <version>${scala.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.hadoop/hadoop-client -->
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>${hadoop.version}</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-pool/commons-pool -->
        <dependency>
            <groupId>commons-pool</groupId>
            <artifactId>commons-pool</artifactId>
            <version>1.6</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.scala-tools/maven-scala-plugin -->
        <dependency>
            <groupId>org.scala-tools</groupId>
            <artifactId>maven-scala-plugin</artifactId>
            <version>2.15.2</version>
            <exclusions>
                <exclusion>
                    <artifactId>jcl-over-slf4j</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--log4j2 核心包-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j2.version}</version>
            <scope>runtime</scope>
        </dependency>
        <!--如果现有组件使用Log4j 1.x并且您希望将此日志记录路由到Log4j 2,则删除所有log4j 1.x依赖项并添加以下内容-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-1.2-api</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <!--如果现有组件使用Apache Commons Logging 1.x并且您希望将此日志记录路由到Log4j 2,则添加以下内容但不删除任何Commons Logging 1.x依赖项。-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <!--如果现有组件使用SLF4J并且您希望将此日志记录路由到Log4j 2,则添加以下内容但不删除任何SLF4J依赖项。-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j2.version}</version>
        </dependency>
        <!--为了正确支持和处理Web应用程序的ClassLoader环境和容器生命周期,需要一个额外的模块。该模块仅在运行时需要。此外,如果您在OSGi环境中使用servlet,请确保您的首选版本的servlet API已经可用(例如,如果您要使用3.0,但是您还加载了2.5,请确保它们都已加载)。-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>${log4j2.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-mapper-asl -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.codehaus.jackson/jackson-core-asl -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <version>2.15.2</version>
                <executions>
                    <execution>
                        <id>scala-compile-first</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <includes>
                                <include>**/*.scala</include>
                            </includes>
                        </configuration>
                    </execution>
                    <execution>
                        <id>scala-test-compile</id>
                        <goals>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.0</version>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
                <executions>
                    <execution>
                        <phase>compile</phase>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <!-- Run shade goal on package phase -->
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <!-- Do not copy the signatures in the META-INF folder.
                                    Otherwise, this might cause SecurityExceptions when using the JAR. -->
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>

                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>${groupId}.${mainClass}</mainClass>
                                </transformer>
                            </transformers>

                            <createDependencyReducedPom>false</createDependencyReducedPom>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        </plugins>
    </build>

</project>

执行命令

mvn clean package -DskipTests

命令中的clean、package分别对应工程生命周期中的clean、package阶段

-DskipTests指跳过test阶段

java写的项目能打包成安装包吗 java项目编译打包_java_08

运行jar

java写的项目能打包成安装包吗 java项目编译打包_java_09

idea打包

java写的项目能打包成安装包吗 java项目编译打包_spark_10

java写的项目能打包成安装包吗 java项目编译打包_maven_11


java写的项目能打包成安装包吗 java项目编译打包_scala_12


java写的项目能打包成安装包吗 java项目编译打包_java写的项目能打包成安装包吗_13


java写的项目能打包成安装包吗 java项目编译打包_java_14


java写的项目能打包成安装包吗 java项目编译打包_java_15


然后在项目的根路径下的out文件夹中的Artifact中可以看到编译打包好的jar包和其它第三方依赖

java写的项目能打包成安装包吗 java项目编译打包_java_16

参考资料

这片对maven-shade-plugin的讲解很全面
maven-plugin-shade 详解

maven-jar-plugin的使用

springboot 项目 使用maven打包 分离第三方依赖打包 教程

这片介绍java编译、打包是最详细的一篇
Maven 打包-添加第三方包、依赖包 mvn clean package

maven-shade-plugin

资料:
https://maven.apache.org/plugins/maven-shade-plugin/examples/resource-transformers.html

resource transformers

如果类或资源没有重复出现,则直接将类或资源合并到一个jar包中输出,如果类或资源重复出现,择需要选择处理重复类或资源的方法,可选的方法有以下几种:
package:org.apache.maven.plugins.shade.resource

ApacheLicenseResourceTransformer

Prevents license duplication

ApacheNoticeResourceTransformer

Prepares merged NOTICE

AppendingTransformer

Adds content to a resource

ComponentsXmlResourceTransformer

Aggregates Plexus components.xml

DontIncludeResourceTransformer

Prevents inclusion of matching resources

GroovyResourceTransformer

Merges Apache Groovy extends modules

IncludeResourceTransformer

Adds files from the project

ManifestResourceTransformer

Sets entries in the MANIFEST

PluginXmlResourceTransformer

Aggregates Mavens plugin.xml

ResourceBundleAppendingTransformer

Merges ResourceBundles

ServicesResourceTransformer

Relocated class names in META-INF/services resources

XmlAppendingTransformer

Adds XML content to an XML resource