Spring boot - 抛出异常 jar 不存在

Posted

技术标签:

【中文标题】Spring boot - 抛出异常 jar 不存在【英文标题】:Spring boot - throws exception jar does not exist 【发布时间】:2019-01-24 19:05:39 【问题描述】:

我正在尝试通过 mvn 包创建一个 jar,然后运行 java -jar /target/test.jar

Caused by: org.apache.commons.vfs2.FileSystemException: Could not replicate "file:///C:/Users/user/workspace/testProject/target/test.jar!/BOOT-INF/lib/myJar.jar" as it does not exist.
        at org.apache.commons.vfs2.provider.AbstractFileSystem.replicateFile(AbstractFileSystem.java:418) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.provider.zip.ZipFileSystem.<init>(ZipFileSystem.java:61) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.provider.jar.JarFileSystem.<init>(JarFileSystem.java:50) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.provider.jar.JarFileProvider.doCreateFileSystem(JarFileProvider.java:82) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.provider.AbstractLayeredFileProvider.createFileSystem(AbstractLayeredFileProvider.java:89) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.provider.AbstractLayeredFileProvider.findFile(AbstractLayeredFileProvider.java:63) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:693) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:649) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:605) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.provider.res.ResourceFileProvider.findFile(ResourceFileProvider.java:81) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:693) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:649) ~[commons-vfs2-2.0.jar!/:2.0]
        at org.apache.commons.vfs2.impl.DefaultFileSystemManager.resolveFile(DefaultFileSystemManager.java:605) ~[commons-vfs2-2.0.jar!/:2.0]
... 52 common frames omitted

当我执行mvn spring-boot:run 时,它可以正常工作,但是当我打包并运行它时,我会遇到异常。

在 pom.xml 中

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                    <configuration>
                        <classifier>spring-boot</classifier>
                        <mainClass>
                            com.client.test.Application
                        </mainClass>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

【问题讨论】:

【参考方案1】:

可执行 jar 中的大多数嵌套库不需要解包即可运行。但是,某些库可能会出现问题。有关更多详细信息,请参阅此 Spring Boot 文档https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-extract-specific-libraries-when-an-executable-jar-runs

使用 maven-dependency-plugin 和 maven-jar-plugin。 虽然需要将“target/lib”文件夹复制到 .jar 的同一位置。就像它在目标文件夹中一样。 试试这个:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>
                            $project.build.directory/libs
                        </outputDirectory>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>libs/</classpathPrefix>
                        <mainClass>
                            <package>.<MainClassName>
                        </mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

【讨论】:

当项目具有自定义/专有依赖项时,尤其会出现此问题。在这种情况下,我怀疑 test.jar 就是那种依赖。【参考方案2】:

Commons-VFS 不知道如何处理 Spring Boot 的嵌套 Jar 路径。你必须通过扩展它的 ResourceFileProvider 来教它。事实上,Spring Boot 的类加载器以 jar:file:foo.jar!bar.jar!baz.jar(一个 jar: 前缀)的形式返回资源 URL,而 Commons-VFS 需要多个“jar:”前缀,例如:jar:jar:file:foo.jar!bar.jar!baz.jar(一个“jar:”每个爆炸字符“! ")。

查看 LGPL 许可的 Portofino(https://github.com/ManyDesigns/Portofino/blob/02550f5789c307ff668b4a778328c027ec2d7fcc/microservices/spring-boot/src/main/java/com/manydesigns/portofino/microservices/boot/PortofinoBootApplication.java#L56-L59、https://github.com/ManyDesigns/Portofino/blob/02550f5789c307ff668b4a778328c027ec2d7fcc/microservices/spring-boot/src/main/java/com/manydesigns/portofino/microservices/boot/SpringBootResourceFileProvider.java)和 GPL 许可的 Renjin(https://github.com/bedatadriven/renjin/blob/cac412d232ad66d4ee8e37cfc8cb70a45e676e19/core/src/main/java/org/renjin/util/ClasspathFileProvider.java#L88-L126)中的示例修复。

【讨论】:

以上是关于Spring boot - 抛出异常 jar 不存在的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常