Maven和Spring Boot:如何使用proguard或类似工具构建大小减小的扁平化JAR包。

huangapple 未分类评论49阅读模式
英文:

Maven and Spring Boot: how to build a flat jar with reduced size (using proguard or similar)

问题

<plugin>
    <groupId>com.github.wvengen</groupId>
    <artifactId>proguard-maven-plugin</artifactId>
    <version>${proguard.maven.plugin.version}</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>proguard</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <proguardVersion>${proguard.version}</proguardVersion>
        <injar>${project.build.finalName}.jar</injar>
        <outjar>suca${project.build.finalName}.jar</outjar>
        <obfuscate>true</obfuscate>
        <options>
            <!-- This option will replace all strings in reflections method invocations with new class names.
                 For example, invokes Class.forName('className') -->
            <option>-adaptclassstrings</option>
            <!-- This option will save all original annotations and etc. Otherwise all will be removed from files. -->
            <option>-keepattributes
                Exceptions,
                InnerClasses,
                Signature,
                Deprecated,
                SourceFile,
                LineNumberTable,
                *Annotation*,
                EnclosingMethod
            </option>
            <!-- This option will save all original names in interfaces (without obfuscation). -->
            <option>-keepnames interface **</option>
            <!-- This option will save all original methods parameters in files defined in -keep sections,
                 otherwise all parameter names will be obfuscated. -->
            <option>-keepparameternames</option>
            <!-- This option will save all original class files (without obfuscation) but obfuscate all
                 in domain and service packages. -->
            <option>-keep
                class ${spring.boot.mainclass} {
                public static void main(java.lang.String[]);
                }
            </option>
            <!-- This option ignore warnings such as duplicate class definitions and classes in incorrectly
                named files -->
            <option>-ignorewarnings</option>
            <!-- This option will save all original class files (without obfuscation) in service package -->
            <!-- <option>-keep class com.slm.proguard.example.spring.boot.service { *; }</option> -->
            <!-- This option will save all original interfaces files (without obfuscation) in all packages. -->
            <option>-keep interface * extends * { *; }</option>
            <!-- This option will save all original defined annotations in all classes in all packages. -->
            <option>-keepclassmembers class * {
                @org.springframework.beans.factory.annotation.Autowired *;
                @org.springframework.beans.factory.annotation.Value *;
                }
            </option>
        </options>
        <injarNotExistsSkip>true</injarNotExistsSkip>
        <libs>
            <!-- Put here your libraries if required -->
            <!-- <lib>${java.home}/lib/rt.jar</lib> -->
        </libs>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>net.sf.proguard</groupId>
            <artifactId>proguard-base</artifactId>
            <version>${proguard.version}</version>
        </dependency>
    </dependencies>
</plugin>
英文:

I'm working on a Maven Spring Boot Application (no web, only desktop). The project has just 30 classes, but the spring boot dependencies usage produce at the end a 13MByte jar. It's possible to use Proguard or any kind of plugin to integrate with Spring Boot to reduce JAR size? My project pom file:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;project xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&quot;&gt;
    &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;

    &lt;parent&gt;
        &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
        &lt;artifactId&gt;spring-boot-starter-parent&lt;/artifactId&gt;
        &lt;version&gt;2.3.0.RELEASE&lt;/version&gt;
    &lt;/parent&gt;

    &lt;groupId&gt;org.example&lt;/groupId&gt;
    &lt;artifactId&gt;dummy-app&lt;/artifactId&gt;
    &lt;version&gt;1.0.0&lt;/version&gt;
    &lt;packaging&gt;jar&lt;/packaging&gt;

    &lt;url&gt;https://github.com/xxx&lt;/url&gt;

    &lt;properties&gt;
        &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt;
        &lt;maven.compiler.source&gt;11&lt;/maven.compiler.source&gt;
        &lt;maven.compiler.target&gt;11&lt;/maven.compiler.target&gt;

        &lt;spring.boot.mainclass&gt;oorg.example.Application&lt;/spring.boot.mainclass&gt;

        &lt;antlr.version&gt;4.7.1&lt;/antlr.version&gt;
        &lt;junit-jupiter.version&gt;5.5.2&lt;/junit-jupiter.version&gt;
        &lt;hamcrest.version&gt;2.2&lt;/hamcrest.version&gt;

        &lt;proguard.maven.plugin.version&gt;2.2.0&lt;/proguard.maven.plugin.version&gt;
        &lt;proguard.version&gt;6.2.0&lt;/proguard.version&gt;
    &lt;/properties&gt;

    &lt;licenses&gt;
        &lt;license&gt;
            &lt;name&gt;The Apache Software License, Version 2.0&lt;/name&gt;
            &lt;url&gt;http://www.apache.org/licenses/LICENSE-2.0.txt&lt;/url&gt;
            &lt;distribution&gt;repo&lt;/distribution&gt;
        &lt;/license&gt;
    &lt;/licenses&gt;


    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.antlr&lt;/groupId&gt;
                &lt;artifactId&gt;antlr4-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;${antlr.version}&lt;/version&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;antlr4&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;configuration&gt;
                            &lt;listener&gt;true&lt;/listener&gt;
                            &lt;visitor&gt;true&lt;/visitor&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
                &lt;dependencies&gt;
                    &lt;!-- https://mvnrepository.com/artifact/org.antlr/antlr4-runtime --&gt;
                    &lt;dependency&gt;
                        &lt;groupId&gt;org.antlr&lt;/groupId&gt;
                        &lt;artifactId&gt;antlr4-runtime&lt;/artifactId&gt;
                        &lt;version&gt;${antlr.version}&lt;/version&gt;
                    &lt;/dependency&gt;
                &lt;/dependencies&gt;
            &lt;/plugin&gt;

            &lt;plugin&gt;
                &lt;groupId&gt;org.eluder.coveralls&lt;/groupId&gt;
                &lt;artifactId&gt;coveralls-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;4.3.0&lt;/version&gt;
            &lt;/plugin&gt;

            &lt;plugin&gt;
                &lt;groupId&gt;org.jacoco&lt;/groupId&gt;
                &lt;artifactId&gt;jacoco-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;0.8.5&lt;/version&gt;
            &lt;/plugin&gt;

            &lt;plugin&gt;
                &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
                &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;repackage&lt;/goal&gt;
                        &lt;/goals&gt;
                        &lt;configuration&gt;
                            &lt;finalName&gt;Example&lt;/finalName&gt;
                            &lt;mainClass&gt;${spring.boot.mainclass}&lt;/mainClass&gt;
                        &lt;/configuration&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;

        &lt;/plugins&gt;

    &lt;/build&gt;

    &lt;reporting&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;org.jacoco&lt;/groupId&gt;
                &lt;artifactId&gt;jacoco-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;0.8.5&lt;/version&gt;
            &lt;/plugin&gt;
        &lt;/plugins&gt;
    &lt;/reporting&gt;

    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter&lt;/artifactId&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-aop&lt;/artifactId&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;com.google.guava&lt;/groupId&gt;
            &lt;artifactId&gt;guava&lt;/artifactId&gt;
            &lt;version&gt;29.0-jre&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;!-- https://mvnrepository.com/artifact/org.antlr/antlr4-runtime --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.antlr&lt;/groupId&gt;
            &lt;artifactId&gt;antlr4-runtime&lt;/artifactId&gt;
            &lt;version&gt;${antlr.version}&lt;/version&gt;
        &lt;/dependency&gt;

        &lt;dependency&gt;
            &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
            &lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
            &lt;scope&gt;test&lt;/scope&gt;
            &lt;exclusions&gt;
                &lt;exclusion&gt;
                    &lt;groupId&gt;org.junit.vintage&lt;/groupId&gt;
                    &lt;artifactId&gt;junit-vintage-engine&lt;/artifactId&gt;
                &lt;/exclusion&gt;
            &lt;/exclusions&gt;
        &lt;/dependency&gt;

        &lt;!-- junit 5 --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.junit.jupiter&lt;/groupId&gt;
            &lt;artifactId&gt;junit-jupiter-engine&lt;/artifactId&gt;
            &lt;version&gt;${junit-jupiter.version}&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;

        &lt;!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest --&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;org.hamcrest&lt;/groupId&gt;
            &lt;artifactId&gt;hamcrest&lt;/artifactId&gt;
            &lt;version&gt;${hamcrest.version}&lt;/version&gt;
            &lt;scope&gt;test&lt;/scope&gt;
        &lt;/dependency&gt;

    &lt;/dependencies&gt;

&lt;/project&gt;

I try to integrate with a proguard plugin, but I can not find any way to make it works. Any ideas to accomplish this task?

&lt;plugin&gt;
    &lt;groupId&gt;com.github.wvengen&lt;/groupId&gt;
    &lt;artifactId&gt;proguard-maven-plugin&lt;/artifactId&gt;
    &lt;version&gt;${proguard.maven.plugin.version}&lt;/version&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;phase&gt;package&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;proguard&lt;/goal&gt;
            &lt;/goals&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
    &lt;configuration&gt;
        &lt;proguardVersion&gt;${proguard.version}&lt;/proguardVersion&gt;
        &lt;injar&gt;${project.build.finalName}.jar&lt;/injar&gt;
        &lt;outjar&gt;suca${project.build.finalName}.jar&lt;/outjar&gt;
        &lt;obfuscate&gt;true&lt;/obfuscate&gt;
        &lt;options&gt;
&lt;!--                        &lt;option&gt;-shrink&lt;/option&gt;--&gt;
&lt;!--                        &lt;option&gt;-optimize&lt;/option&gt;--&gt;
            &lt;!-- This option will replace all strings in reflections method invocations with new class names.
                 For example, invokes Class.forName(&#39;className&#39;)--&gt;
            &lt;option&gt;-adaptclassstrings&lt;/option&gt;
            &lt;!-- This option will save all original annotations and etc. Otherwise all we be removed from files.--&gt;
            &lt;option&gt;-keepattributes
                Exceptions,
                InnerClasses,
                Signature,
                Deprecated,
                SourceFile,
                LineNumberTable,
                *Annotation*,
                EnclosingMethod
            &lt;/option&gt;
            &lt;!-- This option will save all original names in interfaces (without obfuscate).--&gt;
            &lt;option&gt;-keepnames interface **&lt;/option&gt;
            &lt;!-- This option will save all original methods parameters in files defined in -keep sections,
                 otherwise all parameter names will be obfuscate.--&gt;
            &lt;option&gt;-keepparameternames&lt;/option&gt;
            &lt;!-- This option will save all original class files (without obfuscate) but obfuscate all
                 in domain and service packages.--&gt;
            &lt;option&gt;-keep
                class ${spring.boot.mainclass} {
                public static void main(java.lang.String[]);
                }
            &lt;/option&gt;
            &lt;!-- This option ignore warnings such as duplicate class definitions and classes in incorrectly
                named files--&gt;
            &lt;option&gt;-ignorewarnings&lt;/option&gt;
            &lt;!-- This option will save all original class files (without obfuscate) in service package--&gt;
            &lt;!--&lt;option&gt;-keep class com.slm.proguard.example.spring.boot.service { *; }&lt;/option&gt;--&gt;
            &lt;!-- This option will save all original interfaces files (without obfuscate) in all packages.--&gt;
            &lt;option&gt;-keep interface * extends * { *; }&lt;/option&gt;
            &lt;!-- This option will save all original defined annotations in all class in all packages.--&gt;
            &lt;option&gt;-keepclassmembers class * {
                @org.springframework.beans.factory.annotation.Autowired *;
                @org.springframework.beans.factory.annotation.Value *;
                }
            &lt;/option&gt;
        &lt;/options&gt;
        &lt;injarNotExistsSkip&gt;true&lt;/injarNotExistsSkip&gt;
        &lt;libs&gt;
            &lt;!--Put here your libraries if required--&gt;
            &lt;!--&lt;lib&gt;${java.home}/lib/rt.jar&lt;/lib&gt;--&gt;
        &lt;/libs&gt;
    &lt;/configuration&gt;
    &lt;dependencies&gt;
        &lt;dependency&gt;
            &lt;groupId&gt;net.sf.proguard&lt;/groupId&gt;
            &lt;artifactId&gt;proguard-base&lt;/artifactId&gt;
            &lt;version&gt;${proguard.version}&lt;/version&gt;
        &lt;/dependency&gt;
    &lt;/dependencies&gt;
&lt;/plugin&gt;

Note: all dependency has almost a class that I use in my project, I can not remove them.

huangapple
  • 本文由 发表于 2020年5月29日 21:38:38
  • 转载请务必保留本文链接:https://java.coder-hub.com/62087314.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定