精华内容
下载资源
问答
  • maven 打包插件

    2019-12-04 09:52:30
    scala的编译插件 maven 打包插件 org.apache.maven.plugins maven-compiler-plugin 3.6.1 1.8 ...

    scala的编译插件 maven 打包插件

        <plugins>
                   <!--scala 的maven 编译插件-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.2.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
             <!--maven 打包插件,打出来包带所有依赖-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>WordCount</mainClass>
                        </manifest>
                    </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
    
        </plugins>
    </build>
    
    展开全文
  • maven打包插件

    2021-04-04 22:00:10
    maven打包插件 nohup java -jar xxx.jar >log.txt & <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <...

    maven打包插件

    运行jar命令

    nohup java -jar xxx.jar >log.txt &
    

    使用mvn命令进行打包时需要加入打包插件

    开发时使用eclipse直接运行springboot项目不用打包插件也可运行,但是使用命令行必须加入插件

    	  <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <version>1.5.7.RELEASE</version>
            <configuration>
              <mainClass>com.ljp.MainApp</mainClass>
              <layout>ZIP</layout>
            </configuration>
            <executions>
              <execution>
                <goals>
                  <goal>repackage</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
    

    非springboot项目可以使用普通打包插件

    	  <!--将该项目打包成可执行的jar的插件 -->
          <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.5.2</version>
            <configuration>
              <appendAssemblyId>false</appendAssemblyId>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <!--该项目的启动类 -->
                  <mainClass>com.ljp.MainApp</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <id>make-assembly</id>
                <phase>package</phase>
                <goals>
                  <goal>assembly</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
    
          <resources>
            <resource>
              <directory>src/main/java</directory>
              <includes>
                <include>**/*.xml</include>
              </includes>
            </resource>
          </resources>
    
    展开全文
  • Maven打包插件

    2020-05-14 20:38:47
    Maven中的打包插件:可以打出瘦包、胖包、源码包、javadoc包 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-...

    Maven中的打包插件:可以打出瘦包、胖包、源码包、javadoc包

    java运行jar包中指定Class的main方法

    java -classpath ****.jar ****.****.className [args]
    

    打包插件:

    <build>
           <plugins>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-compiler-plugin</artifactId>
                   <version>3.1</version>
                   <configuration>
                       <source>1.7</source>
                       <target>1.7</target>
                   </configuration>
               </plugin>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-shade-plugin</artifactId>
                   <version>2.3</version>
                   <executions>
                       <execution>
                           <phase>package</phase>
                           <goals>
                               <goal>shade</goal>
                           </goals>
                       </execution>
                   </executions>
               </plugin>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-surefire-plugin</artifactId>
                   <version>2.18.1</version>
               </plugin>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-source-plugin</artifactId>
                   <version>2.2.1</version>
                   <executions>
                       <execution>
                           <id>attach-sources</id>
                           <goals>
                               <goal>jar</goal>
                           </goals>
                       </execution>
                   </executions>
               </plugin>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-javadoc-plugin</artifactId>
                   <version>2.9.1</version>
                   <executions>
                       <execution>
                           <id>attach-javadocs</id>
                           <goals>
                               <goal>jar</goal>
                           </goals>
                       </execution>
                   </executions>
               </plugin>
           </plugins>
       </build>
    
    展开全文
  • 自定义Maven打包插件

    2020-12-21 23:28:00
    自定义Maven打包插件实战 打包业务描述:   打包时,根据需要打包的模块.json配置文件,动态打入自己需要的Controller,排除掉不需要的模块Controller类。 打包插件设计思路: 插件使用如下: 一 、先

    前言

      Maven大家都很熟悉,插件也非常丰富。比如它的打包插件maven-assembly-plugin可以根据模板配置自己想要的打包内容,但当它的模板配置无法满足自己定制化打包需求时,此时就需要我们将maven研究的更深入些,利用自定义maven插件去实现我们自己的打包逻辑。

    自定义Maven打包插件实战

    打包业务描述:

      打包时,根据需要打包的模块.json配置文件,动态打入自己需要的Controller,排除掉不需要的模块Controller类。

    打包插件设计思路:

    在这里插入图片描述

    插件使用如下:

    在这里插入图片描述

    一 、先创建Maven项目,编写pom.xml

    <?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>pre-maven-plugin</artifactId>
        <packaging>maven-plugin</packaging>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
            <maven.plugin.api>3.5.0</maven.plugin.api>
            <maven-plugin-annotations>3.5.2</maven-plugin-annotations>
            <reflections.version>0.9.10</reflections.version>
            <fastjson.version>1.2.58</fastjson.version>
            <lombok.version>1.18.16</lombok.version>
            <commons-io.version>2.6</commons-io.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.apache.maven</groupId>
                <artifactId>maven-plugin-api</artifactId>
                <version>${maven.plugin.api}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.maven.plugin-tools</groupId>
                <artifactId>maven-plugin-annotations</artifactId>
                <version>${maven-plugin-annotations}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>org.reflections</groupId>
                <artifactId>reflections</artifactId>
                <version>${reflections.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons-io.version}</version>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-plugin-plugin</artifactId>
                    <version>3.6.0</version>
                </plugin>
            </plugins>
        </build>
    
    
    </project>
    

    注意:maven插件的 packaging 必须是maven-plugin,其次是需要依赖的jar包maven-plugin-api、maven-plugin-annotations。

    二、编写插件实现类

    package mojo;
    
    import com.alibaba.fastjson.JSON;
    import dto.Module;
    import lombok.Data;
    import org.apache.commons.lang3.StringUtils;
    import org.apache.maven.plugin.AbstractMojo;
    import org.apache.maven.plugin.MojoExecutionException;
    import org.apache.maven.plugin.MojoFailureException;
    import org.apache.maven.plugins.annotations.LifecyclePhase;
    import org.apache.maven.plugins.annotations.Mojo;
    import org.apache.maven.plugins.annotations.Parameter;
    
    import java.io.File;
    import java.io.IOException;
    import java.lang.annotation.Annotation;
    import java.lang.reflect.Method;
    import java.nio.file.Files;
    import java.text.MessageFormat;
    import java.util.*;
    import util.*;
    
    /**
     * @author zkc
     * @version 1.0.0
     * @since 2020-12-21
     */
    @Mojo(name = "jwfRepackage", defaultPhase = LifecyclePhase.PACKAGE)
    @Data
    public class ZkcRepackageMojo extends AbstractMojo {
        /**
         * 应用的模块json配置文件,支持“,”逗号分隔多个应用
         */
        @Parameter(required = true)
        private String applicationModuleJson;
        /**
         * 配置应用模块json所在文件夹名称,默认application
         */
        @Parameter
        private String applicationFolderName = "application";
        /**
         * maven编译时classes路径,只读,不需要手动配置
         */
        @Parameter(defaultValue = "${project.compileClasspathElements}", readonly = true, required = true)
        private List<String> compilePath;
        /**
         * maven项目中版本号,只读,不需要手动配置
         */
        @Parameter(defaultValue = "${project.version}", readonly = true, required = true)
        private String projectVersion;
        /**
         * maven项目中artifactId,只读,不需要手动配置
         */
        @Parameter(defaultValue = "${project.artifactId}", readonly = true, required = true)
        private String artifactId;
    
    
        @Override
        public void execute() throws MojoExecutionException, MojoFailureException {
    
            long startTime = System.currentTimeMillis();
            System.out.println(MessageFormat.format("自定义分模块打包插件开始执行:[{0}]", startTime));
    
            // 解析应用模块json配置文件
            List<Module> moduleList = analysisApplicationModuleJson(StringUtils.split(applicationModuleJson, ","));
            if (CommonUtil.isCollectionEmpty(moduleList)) {
                System.out.println(MessageFormat.format("应用模块json解析为空:maven编译地址[{0}],应用模块json地址[{1}]", String.join(",", compilePath), applicationModuleJson));
                return;
            }
    
            // 自定义类加载器,加载原始jar包,过滤出非应用的模块Controller类
            String moduleJarPath = PathUtil.buildJarPath(compilePath) + PathUtil.buildJarName(artifactId, projectVersion);
            Set<String> excludeClasses = getExcludeClasses(moduleJarPath, moduleList);
            if (CommonUtil.isCollectionEmpty(excludeClasses)) {
                long endTime = System.currentTimeMillis();
                System.out.println(MessageFormat.format("自定义分模块打包插件结束执行,没有需要排除的模块Class,耗时:[{0}]毫秒", endTime - startTime));
                return;
            }
    
            // 删除无用的应用模块Controller类,重新打包
            try {
                JarUtil.delete(moduleJarPath, excludeClasses);
            } catch (Exception e) {
                System.out.println(MessageFormat.format("删除无用应用模块Controller类,重新打包失败:[{0}],[{1}]", moduleJarPath, excludeClasses));
                e.printStackTrace();
            }
    
            long endTime = System.currentTimeMillis();
            System.out.println(MessageFormat.format("自定义分模块打包插件结束执行,供排除[{0}]个非应用模块Class,耗时:[{1}]毫秒", excludeClasses.size(), endTime - startTime));
    
        }
    
        /**
         * 解析应用模块json配置文件
         *
         * @param moduleJsons 应用模块json配置地址
         * @return 返回解析后的模块集合
         */
        private List<Module> analysisApplicationModuleJson(String[] moduleJsons) {
            if (CommonUtil.isArrayEmpty(moduleJsons) || CommonUtil.isCollectionEmpty(compilePath)) {
                return null;
            }
            List<Module> moduleList = new ArrayList<>();
            Arrays.stream(moduleJsons).forEach(moduleJson -> {
                String moduleJsonPath = PathUtil.buildModuleJsonPath(compilePath, moduleJson, applicationFolderName);
                File jsonFile = new File(moduleJsonPath);
                if (!jsonFile.exists()) {
                    System.out.println(MessageFormat.format("应用模块json文件未找到:[{0}]", moduleJsonPath));
                }
                try {
                    List<Module> moduleListTemp = JSON.parseArray(new String(Files.readAllBytes(jsonFile.toPath())),
                            Module.class);
                    moduleList.addAll(moduleListTemp);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            return moduleList;
        }
    
        /**
         * 自定义类加载器,加载原始jar包,过滤出非应用的模块Controller类
         *
         * @param moduleJarPath 原始jar包路径
         * @param moduleList    应用模块类集合
         * @return 返回需要过滤的模块类
         */
        @SuppressWarnings("unchecked")
        private Set<String> getExcludeClasses(String moduleJarPath, List<Module> moduleList) {
            Set<String> excludeClasses = new HashSet<>();
            ModuleClassLoader moduleClassLoader = new ModuleClassLoader(moduleJarPath);
            ModuleClassLoader.getModuleClassMap().forEach((className, bytes) -> {
                // 解析@ModuleController注解
                try {
                    Class clazz = moduleClassLoader.loadClass(className);
                    Annotation[] annotations = clazz.getAnnotationsByType(moduleClassLoader.loadClass(PathUtil.MODULE_CLASS));
                    for (Annotation annotation : annotations) {
                        Class aClass = annotation.getClass();
                        try {
                            Method method = aClass.getMethod(PathUtil.MODULE_METHOD);
                            String value = (String) method.invoke(annotation);
                            boolean moduleClassFlag = moduleList.stream().anyMatch(module -> Objects.equals(module.getModuleId(), value));
                            if (!moduleClassFlag) {
                                excludeClasses.add(className);
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                } catch (ClassNotFoundException e) {
                    System.out.println(MessageFormat.format("加载[{0}]类报错,因未加载对应jar包,可忽略", className));
                }
            });
            return excludeClasses;
        }
    
    }
    
    

    注意:maven插件支持注解方式和Javadoc 方式开发,本实战中使用注解方式@Mojo指定插件的目标类和插件的运行阶段。

    三、自定义类加载

    package util;
    
    import org.apache.commons.lang3.StringUtils;
    
    import java.io.*;
    import java.text.MessageFormat;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.jar.JarEntry;
    import java.util.jar.JarFile;
    
    /**
     * @author zkc
     * @version 1.0.0
     * @since 2020-12-21
     */
    public class ModuleClassLoader extends ClassLoader {
    
        private final static Map<String, byte[]> MODULE_CLASS_MAP = new ConcurrentHashMap<>();
    
        public ModuleClassLoader(String moduleJarPath) {
            try {
                readJar(moduleJarPath);
            } catch (IOException e) {
                System.out.println(MessageFormat.format("读取jar包异常:地址[{0}]", moduleJarPath));
                e.printStackTrace();
            }
        }
    
        public static void addClass(String className, byte[] byteCode) {
            if (!MODULE_CLASS_MAP.containsKey(className)) {
                MODULE_CLASS_MAP.put(className, byteCode);
            }
        }
    
        /**
         * 遵守双亲委托规则
         *
         * @param name 类全路径
         * @return 返回类字节码对象
         */
        @Override
        protected Class<?> findClass(String name) {
            try {
                byte[] result = getClass(name);
                if (result != null) {
                    return defineClass(name, result, 0, result.length);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private byte[] getClass(String className) {
            return MODULE_CLASS_MAP.getOrDefault(className, null);
        }
    
        private void readJar(String moduleJarPath) throws IOException {
            readJarFile(moduleJarPath);
        }
    
        private void readJarFile(String moduleJarPath) throws IOException {
            File file = new File(moduleJarPath);
            if (!file.exists()) {
                throw new FileNotFoundException();
            }
            JarFile jarFile = new JarFile(file);
            Enumeration<JarEntry> enumeration = jarFile.entries();
            while (enumeration.hasMoreElements()) {
                JarEntry jarEntry = enumeration.nextElement();
                String name = jarEntry.getName().replace("BOOT-INF/classes/", "").replace("\\", ".")
                        .replace("/", ".");
                if (isRead(name)) {
                    String className = name.replace(".class", "");
                    try (InputStream input = jarFile.getInputStream(jarEntry); ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                        int bufferSize = 1024;
                        byte[] buffer = new byte[bufferSize];
                        int bytesNumRead;
                        while ((bytesNumRead = input.read(buffer)) != -1) {
                            baos.write(buffer, 0, bytesNumRead);
                        }
                        addClass(className, baos.toByteArray());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        private boolean isRead(String name) {
            return StringUtils.isNotBlank(name) && name.endsWith(PathUtil.CLASS)
                    && (name.startsWith(PathUtil.COMMON_CONTROLLER) || name.startsWith(PathUtil.COMMON_ANNOTATION));
        }
    
        public static Map<String, byte[]> getModuleClassMap() {
            return MODULE_CLASS_MAP;
        }
    }
    
    
    

    注意:maven插件运行时,插件的运行环境中类加载器肯定只会加载插件本身的class信息。如果你想操作应用的类,需要自定义类加载器,通过一定的寻址逻辑找到你想加载的jar包,自行加入到插件的运行环境中。

    四、备份原始springboot的jar包,生成新jar包

    package util;
    
    import org.apache.commons.io.FileUtils;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.text.MessageFormat;
    import java.util.Enumeration;
    import java.util.Set;
    import java.util.jar.JarEntry;
    import java.util.jar.JarFile;
    import java.util.jar.JarOutputStream;
    
    /**
     * @author zkc
     * @version 1.0.0
     * @since 2020-12-21
     */
    public class JarUtil {
    
        public static void delete(String jarName, Set<String> deletes) throws Exception {
            // 先备份原始jar包
            File oriFile = new File(jarName);
            if (!oriFile.exists()) {
                System.out.println(MessageFormat.format("排除类时,原始jar包不存在[{0}]", jarName));
                return;
            }
            // 以时间戳重命名备份文件名
            String bakJarName = jarName.substring(0, jarName.length() - 3) + System.currentTimeMillis() + PathUtil.JAR;
            File bakFile = new File(bakJarName);
            // 备份原始jar包
            FileUtils.copyFile(oriFile, bakFile);
            // 排除deletes中的class,重新打包新jar包文件
            JarFile bakJarFile = new JarFile(bakJarName);
            JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarName));
            Enumeration<JarEntry> entries = bakJarFile.entries();
            while (entries.hasMoreElements()) {
                JarEntry entry = entries.nextElement();
                String name = entry.getName().replace("BOOT-INF/classes/", "").replace("\\", ".").replace("/", ".").replace(".class", "");
                if (!deletes.contains(name)) {
                    InputStream inputStream = bakJarFile.getInputStream(entry);
                    jos.putNextEntry(entry);
                    byte[] bytes = readStream(inputStream);
                    jos.write(bytes, 0, bytes.length);
                } else {
                    System.out.println(MessageFormat.format("排除非应用模块类:[{0}]", entry.getName()));
                }
            }
            // 关闭流
            jos.flush();
            jos.finish();
            jos.close();
            bakJarFile.close();
        }
    
        private static byte[] readStream(InputStream inStream) throws Exception {
            ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len = -1;
            while ((len = inStream.read(buffer)) != -1) {
                outSteam.write(buffer, 0, len);
            }
            outSteam.close();
            inStream.close();
            return outSteam.toByteArray();
        }
    
    }
    
    

    五、自定义模块注解类

    package com.zkc.web.annotation;
    
    import java.lang.annotation.*;
    
    /**
     * @author zkc
     * @version 1.0.0
     * @since 2020-12-21
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Module {
    
        String moduleId();
    
        String moduleName();
    
    }
    
    

    插件运行效果

    [INFO] 
    [INFO] --- pre-maven-plugin:1.0-SNAPSHOT:jwfRepackage (default) @ web ---
    自定义分模块打包插件开始执行:[1,608,560,919,883]
    排除非应用模块类:[BOOT-INF/classes/com/zkc/web/controller/ProductController.class]
    排除非应用模块类:[BOOT-INF/classes/com/zkc/web/controller/RoleController.class]
    自定义分模块打包插件结束执行,供排除[2]个非应用模块Class,耗时:[153]毫秒
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    

    完整代码以上传码云

    码云地址: git地址


    我的专栏

    1. 设计模式
    2. 认证授权框架实战
    3. java进阶知识
    4. maven进阶知
    5. spring进阶知识
    展开全文
  • Maven 打包插件说明

    2019-08-19 10:29:03
    Maven 打包插件说明 https://blog.csdn.net/wangming520liwei/article/details/85005225
  • 问题 项目中需要对Java应用打包 指定主函数 ...解法 添加主函数Maven打包插件 <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> ...
  • Maven打包插件maven-assembly-plugin配置

    千次阅读 2018-11-13 19:40:56
    Maven打包插件maven-shade-plugin配置在pom.xml文件中的配置新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定...
  • Spring Boot 2关于maven打包插件的使用spring-boot-maven-plugin插件1、直接引用2、通过参数spring.config.location区分不同环境3、通过参数profiles区分不同环境 spring-boot-maven-plugin插件 ...
  • Maven打包插件Assembly 1.在dubbo的provider项目(实现类项目)中pom.xml配置assembly插件信息 <build> <plugins> <!-- 指定项目的打包插件信息 --> <plugin> <artifactId...
  • maven打包插件配置

    2019-09-06 11:16:57
    一、maven打包可执行jar文件,需要引入插件 <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <appendAssemblyId>false</appendAssemblyId> ...
  • Maven的生命周期与Maven插件是项目绑定的,生命周期可以理解为项目构建步骤的集合,它定义了各个构建环节的执行顺序,有了这个顺序,Maven 就可以自动化的执行构建命令。Maven 的核心程序中定义了抽象的生命周期,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,220
精华内容 2,088
关键字:

maven打包插件