10 springboot项目使用maven,如何减小其jar大小?

m3eecexj  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(225)

我们的项目有大约10个spingboot模块,我们使用maven来管理依赖关系。10罐大小约2克。最近我们需要减少jar的大小,以方便我们的客户部署。
我有一个想法,提取公共jar(不经常更改),例如spring-.jar、spring boot-.jar、jodd*.jar、elasticsearch等。只要>=2个项目使用一个相同的依赖项,我们称之为“公共jar”。
如果你知道一些有用的解决方法,请告诉我。
我试过这种方法,但遇到了一些麻烦。
新的一个程序作为工具来计算我的项目之间的公共artifactid,最后我得到了一个artifactid列表。
新的maven模块来打包公共依赖项,最后得到一个lib文档包含公共jar文件。我把它命名为“公共库”。
将旧项目的pom文件更改如下:
添加maven jar插件,让我的项目加载公共库的类

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <mainClass>com.xx.MyManagerApplication</mainClass>
                <useUniqueVersions>false</useUniqueVersions>
                <addClasspath>true</addClasspath>
                <!--classpathPrefix let Manifest.MF's Class-Path add the 'common-lib' as prefix-->
                <classpathPrefix>common-lib/</classpathPrefix>
            </manifest>
            <manifestEntries>
                <Class-Path>.</Class-Path>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

将spring boot maven插件的配置更改为:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <mainClass>com.xx.MyManagerApplication</mainClass>
        <layout>ZIP</layout>
        <excludeArtifactIds>
            spring-webmvc,
            spring-web,
            spring-tx,
            spring-security-rsa,
            spring-security-crypto,
            spring-jdbc,
            spring-jcl,
            spring-expression,
            spring-core,
            spring-context,
            spring-cloud-starter-zipkin,
            ...ellipsis
        </excludeArtifactIds>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

最后,我的项目的jar库只包含一个公共库。jar的尺寸减小到900k(过去是105m)。它大大减小了jar的尺寸。
将myproject.jar和common lib放在同一目录下
公共库
很多jar。。。
我的项目.jar
然后启动我的项目 java -Dspring.profiles.active=dev -Dspring.config.location=application.yml -jar my-project.jar 然而,它并没有像我梦想的那样工作。而是在控制台中显示一条错误消息

[2020-12-01 15:54:19.252+0800]-[foundation-manager]-[1;31m[ERROR][0;39m-[]-[8340:main] o.s.boot.SpringApplication               837 : Application run failed

java.lang.NoClassDefFoundError: groovy/lang/GroovyObject
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
        at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at org.springframework.boot.BeanDefinitionLoader.<init>(BeanDefinitionLoader.java:84)
        at org.springframework.boot.SpringApplication.createBeanDefinitionLoader(SpringApplication.java:745)
        at org.springframework.boot.SpringApplication.load(SpringApplication.java:685)
        at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:381)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:305)
        at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:137)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.bootstrapServiceContext(BootstrapApplicationListener.java:208)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:104)
        at org.springframework.cloud.bootstrap.BootstrapApplicationListener.onApplicationEvent(BootstrapApplicationListener.java:70)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:338)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:297)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1242)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1230)
        at com.yealink.foundation.manager.app.FoundationManagerApplication.main(FoundationManagerApplication.java:44)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:87)
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50)
        at org.springframework.boot.loader.PropertiesLauncher.main(PropertiesLauncher.java:593)
Caused by: java.lang.ClassNotFoundException: groovy.lang.GroovyObject
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:338)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 40 common frames omitted

groovy的lib不是公共lib,它存在于项目的jar中。原因是第2步我更改了manifest.mf文件,以便jvm在公共lib/groovy..jar中找到groovy的lib?
如果你知道一些有用的解决方法,请告诉我。

hi3rlvi2

hi3rlvi21#

我做了一些类似于你的设置,但在我的情况下,这是为了优化docker推。
不过,我的spring boot maven插件不同:
看看下面的内容是否对您有所帮助:

<!-- This plugin copies different external dependencies into separate folders
                 that are later used to build an optimized Docker image -->
            <plugin>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-external-project-dependencies</id>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeScope>runtime</includeScope>
                            <excludeGroupIds>com.susan</excludeGroupIds>
                            <outputDirectory>${project.build.directory}/external-dependencies</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>copy-hello-cloud-platform-dependencies</id>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeScope>runtime</includeScope>
                            <includeGroupIds>com.susan.hello.cloud-platform</includeGroupIds>
                            <outputDirectory>${project.build.directory}/cloud-dependencies</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>copy-susan-project-dependencies</id>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeScope>runtime</includeScope>
                            <includeGroupIds>com.susan.ca.cc</includeGroupIds>
                            <outputDirectory>${project.build.directory}/susan-dependencies</outputDirectory>
                        </configuration>
                    </execution>
                    <execution>
                        <id>submodule-dependencies</id>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <includeScope>runtime</includeScope>
                            <includeGroupIds>com.susan</includeGroupIds>
                            <excludeGroupIds>com.susan.ca.cc,com.susan.hello.cloud-platform</excludeGroupIds>
                            <outputDirectory>${project.build.directory}/submodule-dependencies</outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>

        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>build-info</id>
                    <goals>
                        <goal>build-info</goal>
                    </goals>
                </execution>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <skip>true</skip>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>com.susan.hello.whee.HelloApplication</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

复制/susan/target/external dependencies/lib
复制/susan/target/hello dependencies/lib
复制/susan/target/cloud dependencies/lib
复制/susan/target/submodule dependencies/lib
app.jar在/lib之外
java-jar应用程序.jar
一切看起来都和你做的一样,我唯一能想到的就是springbootmaven插件设置。

相关问题