【问题标题】:Maven prefixing WEB-INF/classes into JAR dependencyMaven 将 WEB-INF/classes 前缀到 JAR 依赖项中
【发布时间】:2015-02-24 17:03:55
【问题描述】:

更新:已解决!发布解决方案作为我自己的答案。两天后我可以接受。

一个小故事

过去几天我一直在追查这个兔子洞,而我的问题在那段时间里发生了巨大的变化。最初,我认为Spring Boot 有问题,因为它无法解析我的@Configuration 注释类之一。通过调试,我确定 Spring 正在所有正确的位置寻找我的 JAR 绑定依赖项之一,但在尝试从 JAR 加载类时却出现了 FileNotFoundException

我被这个吓坏了,因为有问题的 JAR 在类路径上是可以验证的。我可以在应用程序启动期间打印出类路径,并看到我的 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 类加载器的毒药。它希望从根目录开始查找类:com/company/... -- 不允许使用前缀。

我相信 Maven 的依赖管理在这里做了一些棘手的事情。当我的JAR 使用clean install 目标创建时,它内部有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>

【问题讨论】:

  • 那么.. 如果您运行“mvn package”,现在您的“大罐子”里面会是什么?我不太清楚这里可能发生了什么——该项目的 pom 是否曾经指定过战争包装?可能有人将那场战争重命名为 jar 吗?如果“mvn package”当前生成的内容在您检查时看起来是正确的,那么也许您可以执行“mvn install”来替换之前生成的不正确的工件。只是一个想法..
  • 使用 Maven 打包时,“大 jar”包含四个文件夹:templates/META-INF/config/com/,这是完美的。当我将它作为 maven 依赖项引入第二个项目时,一切都会中断。我需要 Maven 依赖项在 com/ 之前没有前缀 /WEB-INF/classes --- 除了我之外没有人现在正在接触这个项目,但最终“大”依赖项将成为许多项目的基础。你知道如何防止 Maven 将 /WEB-INF/classes 文件夹结构添加到以前只包含上面列出的四个文件夹的 JAR 吗?
  • 好的。听起来您只需要将您的主要“Project POM”从存储库中获取的那个替换为您现在可以使用“mvn package”正确构建的那个。我在想,如果您只是针对“big jar”项目发出“mvn install”,您将用现在应该满足您需求的工件替换错误生成的工件。有意义吗?
  • 在这个过程中,我已经完成了几十次我的包裹的clean install。我可以查看我的.m2 文件夹,其中的JAR 是正确的。在将 JAR 依赖项拉入我的子项目之前,它没有问题。
  • 之前在 Maven 中看到过一些奇怪的行为,但这不是其中之一(添加 /WEB-INF/classes)。

标签: maven-3 spring-boot


【解决方案1】:

解决了我的问题!我刚刚完成了对项目配置的研究,比较了它们是否存在任何可疑的偏差。原来我在Eclipse 中的较大的JARs 项目将其Deployment Assembly(在属性> 部署程序集下找到)设置为:

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

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

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

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

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

【讨论】:

  • 哈哈。为什么我认为您使用 Maven 来创建您的工件?很高兴你找到它。
  • 猜猜这是 m2eclipse 的事情.. 没有意识到这是等式的一部分。
  • 是的,我使用的是 Spring Tool Suite 中内置的 Maven 版本。直到我完全没有 Maven 特定的设置来调查时,我才开始研究特定于 IDE 的配置。当我开始查看项目设置时,我意识到 IDE 在 JAR 的打包方面有发言权。解决方案紧随其后。再次感谢您的时间。当你也被难住时,你帮助我摆脱了对 Maven 的怀疑。
  • 哈,谢谢。在彻底检查我的开发工具后,今天再次遇到这个问题。问题感觉很熟悉,所以我检查了我的问题历史,你知道什么,我给了我一个答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 2011-08-30
  • 2012-09-10
  • 1970-01-01
  • 2019-09-03
相关资源
最近更新 更多