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 中较大的 JARs 项目将其 Deployment Assembly(在“属性”>“部署程序集”下找到)设置为:

来源 ============ 部署路径

src/main/java --------> /WEB-INF/classes

src/main/resources -> /WEB-INF/classes

这导致我的服务器将 JAR 部署到内部 /WEB-INF/classes 文件夹中。

Deploy Path 设置更改为 / 解决了问题!现在一切正常!哇!