sofastack / sofa-ark

SOFAArk is a light-weight,java based classloader isolation framework.
https://www.sofastack.tech/projects/sofa-boot/sofa-ark-readme/
Apache License 2.0
1.56k stars 497 forks source link

"NoClassDefFoundError" When do "java -jar" #903

Closed ochive closed 4 months ago

ochive commented 5 months ago

Describe the question or bug

我的需求是将多个有依赖冲突的子项目打包为ark插件, 引入主项目后使用即可.

如果不使用ARK, 项目运行和打包后运行都是正常的. 目前引入ark将项目的依赖打包为ark plugin, 再将主项目打成ark包, 都是正常的. 直接使用IDEA启动项目(不加任何VM参数), 也可以正常访问.

但是直接运行jar包就报错:

java "-Dsofa.ark.embed.enable=true" -jar ".\dataintegration-run-management-provider-1.0.0-SNAPSHOT-ark-executable.jar"
 java "-Dsofa.ark.embed.enable=true" -jar ".\dataintegration-run-management-provider-1.0.0-SNAPSHOT-ark-executable.jar"
Exception in thread "main" java.lang.NoClassDefFoundError: com/alipay/sofa/ark/common/util/FileUtils
        at com.alipay.sofa.ark.bootstrap.BaseExecutableArchiveLauncher.createArchive(BaseExecutableArchiveLauncher.java:70)
        at com.alipay.sofa.ark.bootstrap.BaseExecutableArchiveLauncher.<init>(BaseExecutableArchiveLauncher.java:42)
        at com.alipay.sofa.ark.bootstrap.ArkLauncher.<init>(ArkLauncher.java:38)
        at com.alipay.sofa.ark.bootstrap.ArkLauncher.main(ArkLauncher.java:35)
Caused by: java.lang.ClassNotFoundException: com.alipay.sofa.ark.common.util.FileUtils
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
        ... 4 more

Environment

Pom.xml

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <!--打包可运行 mvn package spring-boot:repackage-->
            <plugin>
                <groupId>com.alipay.sofa</groupId>
                <artifactId>sofa-ark-maven-plugin</artifactId>
                <version>${sofa.ark.version}</version>
                <executions>
                    <execution>
                        <id>default-cli</id >
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
        <!--sofa boot-->
<!--        <dependency>-->
<!--            <groupId>com.alipay.sofa</groupId>-->
<!--            <artifactId>runtime-sofa-boot-starter</artifactId>-->
<!--            <version>${sofa.boot.version}</version>-->
<!--        </dependency>-->
<!--        <dependency>-->
<!--            <groupId>com.alipay.sofa</groupId>-->
<!--            <artifactId>isle-sofa-boot-starter</artifactId>-->
<!--            <version>${sofa.boot.version}</version>-->
<!--        </dependency>-->
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>sofa-ark-springboot-starter</artifactId> <!-- spring boot 宿主应用的必要依赖-->
            <version>${sofa.ark.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>sofa-ark-all</artifactId>
            <version>${sofa.ark.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>sofa-ark-api</artifactId>
            <version>${sofa.ark.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>web-ark-plugin</artifactId>
            <version>${sofa.ark.version}</version>
        </dependency>
ochive commented 5 months ago

我再次仔细看了官方文档, 里面提到2.0版本以后, 直接使用springboot的maven打包插件即可.

<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <outputDirectory>target</outputDirectory>
                    <classifier>ark-biz</classifier>
                </configuration>
                <executions>
                    <execution>
                        <id>package</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

打包后得到一个包"project-1.0.0-SNAPSHOT-ark-biz.jar", 以前打包时是生成三个包, "origin.jar", "origin-ark-biz.jar", "origin-ark-executable.jar". 直接使用java -jar运行"ark-biz.jar"包, 可以成功运行了.虽然有报错, 但应该是缺少几个JDK8包造成的.

ochive commented 5 months ago

我还是有一个问题, 文档里提到命令行运行或者IDEA运行都要携带参数:

-Dsofa.ark.embed.enable=true -Dcom.alipay.sofa.ark.master.biz=${bizName}

但我没带参数,似乎也可运行, 请问带参数的作用是什么?

lvjing2 commented 5 months ago

你好,是为了解决合并部署的问题吗?

lvjing2 commented 5 months ago

我再次仔细看了官方文档, 里面提到2.0版本以后, 直接使用springboot的maven打包插件即可.

<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <outputDirectory>target</outputDirectory>
                    <classifier>ark-biz</classifier>
                </configuration>
                <executions>
                    <execution>
                        <id>package</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

打包后得到一个包"project-1.0.0-SNAPSHOT-ark-biz.jar", 以前打包时是生成三个包, "origin.jar", "origin-ark-biz.jar", "origin-ark-executable.jar". 直接使用java -jar运行"ark-biz.jar"包, 可以成功运行了.虽然有报错, 但应该是缺少几个JDK8包造成的.

这个不对吧,是哪里的官网呢?

ochive commented 5 months ago

你好,是这个地址中提到的:"https://www.sofastack.tech/projects/sofa-boot/sofa-ark-migration-guide/".

在SOFAArk1.0中使用sofa-ark-maven-plugin打包,在SOFAArk2.0中采用spring-boot原生打包插件spring-boot-maven-plugin打包
ochive commented 5 months ago

我再次仔细看了官方文档, 里面提到2.0版本以后, 直接使用springboot的maven打包插件即可.

<plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <outputDirectory>target</outputDirectory>
                    <classifier>ark-biz</classifier>
                </configuration>
                <executions>
                    <execution>
                        <id>package</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

打包后得到一个包"project-1.0.0-SNAPSHOT-ark-biz.jar", 以前打包时是生成三个包, "origin.jar", "origin-ark-biz.jar", "origin-ark-executable.jar". 直接使用java -jar运行"ark-biz.jar"包, 可以成功运行了.虽然有报错, 但应该是缺少几个JDK8包造成的.

这个不对吧,是哪里的官网呢?

你好,是这个地址中提到的:"https://www.sofastack.tech/projects/sofa-boot/sofa-ark-migration-guide/".

在SOFAArk1.0中使用sofa-ark-maven-plugin打包,在SOFAArk2.0中采用spring-boot原生打包插件spring-boot-maven-plugin打包
ochive commented 5 months ago

我目前已经解决我提到的问题了, 步骤如下:

  1. 统一sofa-ark版本为2.2.7 (3.X前的最后一个release版本)
  2. 插件项目的依赖中仅将sofa-ark-plugin-maven-plugin的版本升级到2.2.7,其他不变
  3. 主应用将sofa-boot从中移除, 因为我只需要类隔离功能.
  4. 主应用引入sofa-ark的依赖.
<dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>sofa-ark-springboot-starter</artifactId> <!-- spring boot 宿主应用的必要依赖-->
            <version>${sofa.ark.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>sofa-ark-all</artifactId>
            <version>${sofa.ark.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>sofa-ark-api</artifactId>
            <version>${sofa.ark.version}</version>
        </dependency>
  1. 主应用配置打包插件
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring-boot.version}</version>
                <configuration>
                    <outputDirectory>target</outputDirectory>
                    <classifier>ark-biz</classifier>
                </configuration>
                <executions>
                    <execution>
                        <id>package</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
  1. maven重新编译打包
  2. 执行"jar -jar my-app-ark-biz.jar", 无论是否携带"-Dsofa.ark.embed.enable=true -Dcom.alipay.sofa.ark.master.biz=${bizName}"这两VM参数, 都启动成功.但是为了安全起见,我还是带了.
  3. 其他一些报错, 可能是因为sofa-ark依赖jdk8的一些sun包, 我引入一些sun的pollyfill包后解决了, 比如"jdk.tools-jdk.tools","com.sun-tools".
lvjing2 commented 5 months ago

你是使用多应用合并部署能力吗?不参考下 https://github.com/koupleless/samples 这个吗?这个是使用 SOFAArk 做的模块化研发框架与平台能力。

lvjing2 commented 4 months ago

Hi, 你的问题解决了吗?

ochive commented 4 months ago

@lvjing2 你好,已经解决了, 谢谢! 因为这是一个存量项目, 由于它有大量插件项目(各自依赖各种冲突), 因此使用了ark.我对此项目了解有限, 因此目前能解决多依赖的隔离就可以了.

通过这次问题, 我初次接触了模块隔离技术, 后续开发低代码项目时会优先考虑Sofa的新版本,谢谢!