Maven 前缀 WEB-INF/classes 到 JAR 依赖
Maven prefixing WEB-INF/classes into JAR dependency
Update: Solved! Posted solution as my own answer. Will be accepting it in two days when I'm allowed to.
一个小故事
过去几天我一直在追寻这个兔子洞,我的问题在这段时间里发生了翻天覆地的变化。最初,我认为 Spring Boot
有问题,因为它无法解析我的 @Configuration
注释之一 classes。调试它,我确定 Spring 正在寻找我的 JAR
绑定依赖项之一的所有正确位置,但是在尝试加载 [=80] 时想出了一个 FileNotFoundException
=] 来自 JAR
.
我被这个弄糊涂了,因为有问题的 JAR
确实在 class 路径上。我可以在应用程序启动期间打印出 class 路径,并看到我的 JAR
生活在里面舒适温馨。
所以我简化了。并简化。最终,我将事情归结为一个包含两个 Java 源文件和一个小占位符 JAR
的项目 Maven
。此 JAR
仅包含一个文件:tiny/jar/BaseTest.class
.
这非常有效。从那里,我交换了对这个小项目的依赖 JAR
。 . .并且启动失败。所以我比较了 JARs
并发现了一些奇怪的东西。
实现
虽然我的小 JAR
包含文件夹层次结构:
tiny/jar/BaseTest.class
较大的 JAR
看起来像:
WEB-INF/classes/com/company/...
这个 WEB-INF/classes
前缀是杀死 Spring Boot
的 class 加载程序的毒药。它期望从根开始找到 classes:com/company/...
-- 不允许有前缀。
我相信 Maven 的依赖管理在这里做了一些棘手的事情。当使用 clean install
目标创建我的 JAR
时,它内部有 com/company/...
根。如果我手动将此版本的 JAR
复制到我的服务器 WEB-INF/lib
文件夹中,一切都会正常运行、识别并完美启动。
但是当使用 Maven 引入依赖项时,WEB-INF/classes
被添加到我的文件夹层次结构中,破坏了一切。
问题
有谁知道如何防止 Maven 更改我的 JAR
的目录结构? JAR
是 100% 正确的,直到 Maven 将其作为依赖项引入,然后突然出现 WEB-INF/classes
前缀。
这里是三个POM
文件供参考。我删除了大量依赖项,但保留了其他所有内容以便于阅读。
微型罐 POM
<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>tiny</groupId>
<artifactId>jar</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<name>jar</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
大罐 POM
<?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>com.company</groupId>
<artifactId>company-foundation</artifactId>
<version>0.7.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin> <!-- Sonar -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.5</version>
</plugin>
</plugins>
</build>
<repositories>
<!-- To use snapshots, you must also use the Sonatype Snapshots respository -->
<repository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
项目 POM
<?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.test</groupId>
<artifactId>dependency-issue</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>jar-dependency-issue</name>
<description>Barebones Spring Boot project used to demonstrate a JAR loading issue.</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.JarDependencyIssueApplication</start-class>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- To run on a separate server, we need to mark tomcat starter as provided. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>com.company</groupId>
<artifactId>company-foundation</artifactId>
<version>0.7.0-SNAPSHOT</version>
</dependency>
-->
<dependency>
<groupId>tiny</groupId>
<artifactId>jar</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
解决了我的问题!我刚刚仔细研究了我的项目的配置,比较了它们是否有任何可疑的偏差。事实证明,我在 Eclipse
中较大的 JAR
s 项目将其 Deployment Assembly
(在“属性”>“部署程序集”下找到)设置为:
来源 ============ 部署路径
src/main/java
--------> /WEB-INF/classes
src/main/resources
-> /WEB-INF/classes
这导致我的服务器将 JAR
部署到内部 /WEB-INF/classes
文件夹中。
将 Deploy Path
设置更改为 /
解决了问题!现在一切正常!哇!
Update: Solved! Posted solution as my own answer. Will be accepting it in two days when I'm allowed to.
一个小故事
过去几天我一直在追寻这个兔子洞,我的问题在这段时间里发生了翻天覆地的变化。最初,我认为 Spring Boot
有问题,因为它无法解析我的 @Configuration
注释之一 classes。调试它,我确定 Spring 正在寻找我的 JAR
绑定依赖项之一的所有正确位置,但是在尝试加载 [=80] 时想出了一个 FileNotFoundException
=] 来自 JAR
.
我被这个弄糊涂了,因为有问题的 JAR
确实在 class 路径上。我可以在应用程序启动期间打印出 class 路径,并看到我的 JAR
生活在里面舒适温馨。
所以我简化了。并简化。最终,我将事情归结为一个包含两个 Java 源文件和一个小占位符 JAR
的项目 Maven
。此 JAR
仅包含一个文件:tiny/jar/BaseTest.class
.
这非常有效。从那里,我交换了对这个小项目的依赖 JAR
。 . .并且启动失败。所以我比较了 JARs
并发现了一些奇怪的东西。
实现
虽然我的小 JAR
包含文件夹层次结构:
tiny/jar/BaseTest.class
较大的 JAR
看起来像:
WEB-INF/classes/com/company/...
这个 WEB-INF/classes
前缀是杀死 Spring Boot
的 class 加载程序的毒药。它期望从根开始找到 classes:com/company/...
-- 不允许有前缀。
我相信 Maven 的依赖管理在这里做了一些棘手的事情。当使用 clean install
目标创建我的 JAR
时,它内部有 com/company/...
根。如果我手动将此版本的 JAR
复制到我的服务器 WEB-INF/lib
文件夹中,一切都会正常运行、识别并完美启动。
但是当使用 Maven 引入依赖项时,WEB-INF/classes
被添加到我的文件夹层次结构中,破坏了一切。
问题
有谁知道如何防止 Maven 更改我的 JAR
的目录结构? JAR
是 100% 正确的,直到 Maven 将其作为依赖项引入,然后突然出现 WEB-INF/classes
前缀。
这里是三个POM
文件供参考。我删除了大量依赖项,但保留了其他所有内容以便于阅读。
微型罐 POM
<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>tiny</groupId>
<artifactId>jar</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<name>jar</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
大罐 POM
<?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>com.company</groupId>
<artifactId>company-foundation</artifactId>
<version>0.7.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ws</groupId>
<artifactId>spring-ws-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow</artifactId>
<version>2.4.0.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin> <!-- Sonar -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>2.5</version>
</plugin>
</plugins>
</build>
<repositories>
<!-- To use snapshots, you must also use the Sonatype Snapshots respository -->
<repository>
<id>sonatype-snapshots</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
项目 POM
<?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.test</groupId>
<artifactId>dependency-issue</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>jar-dependency-issue</name>
<description>Barebones Spring Boot project used to demonstrate a JAR loading issue.</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<start-class>demo.JarDependencyIssueApplication</start-class>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- To run on a separate server, we need to mark tomcat starter as provided. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>com.company</groupId>
<artifactId>company-foundation</artifactId>
<version>0.7.0-SNAPSHOT</version>
</dependency>
-->
<dependency>
<groupId>tiny</groupId>
<artifactId>jar</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
解决了我的问题!我刚刚仔细研究了我的项目的配置,比较了它们是否有任何可疑的偏差。事实证明,我在 Eclipse
中较大的 JAR
s 项目将其 Deployment Assembly
(在“属性”>“部署程序集”下找到)设置为:
来源 ============ 部署路径
src/main/java
--------> /WEB-INF/classes
src/main/resources
-> /WEB-INF/classes
这导致我的服务器将 JAR
部署到内部 /WEB-INF/classes
文件夹中。
将 Deploy Path
设置更改为 /
解决了问题!现在一切正常!哇!