【实习日记】在Tomcat上部署Spring boot


用Spring Boot开发的Web工程,在本机的Eclipse中Run as Spring Boot可以跑通,但打包成war在Tomcat上却跑不通。

首先这篇文章介绍了部署Spring Boot到Tomcat上的一般方法。但是我的程序抛出了一些奇怪异常。

java.lang.NoSuchMethodError: org.springframework.util.ClassUtils.isPresent(Ljava/lang/String;Ljava/lang/ClassLoader;)Z

一番搜索之后,发现了这篇文章。于是怀疑是版本冲突,Spring过低的原因。

但自己并不知道如何确定工程中Spring的版本,pom.xml中并没有给出版本号。

<?xml version="1.0" encoding="UTF-8"?>


4.0.0

<groupId>org.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>demo</name>
<description>Demo project for Spring Boot</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <start-class>demo.DemoApplication</start-class>
    <java.version>1.7</java.version>
    <hibernate.version>4.3.5.Final</hibernate.version>
    <tomcat.version>7.0.59</tomcat.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-tomcat</artifactId>
        <scope>provided</scope>
    </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-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.35</version>
    </dependency>
    <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-asl</artifactId>
        <version>0.9.5</version>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

然后有找到了stackoverflow上的这篇文章。它的回答实在是太赞了,粘贴到这里。

The problem has now been resolved. Thank you everyone for your assistance.

It turns out that the main project had a dependency which had another MediaDao class, in exactly the same package path. Someone had basically copied the class into that dependency (as a library resource so that lots of projects could use it without specifying the main project as a dependency). However, that someone had not removed the class in the main project.

So, when I modified the class in the main project (I added the updateAlfrescoNodeRef method), and ran the application in STS on my machine, Tomcat used the version of the class in the main project, and not in the library because the library project was closed. When the application was deployed to the server however, it looks like the version of the class in the library was used instead (which, of course, didn’t have the updateAlfrescoNodeRef method in it).

Expert tip if you ever find yourself in a similar situation: In STS, press CTRL+SHIFT+T to open the “Open Type” dialog, and enter the name of the problematic class to see a list of projects that have a class with that name.

所以,当我们怀疑依赖出问题时,按下

CTRL+SHIFT+T

搜索冲突的class名称,就可以看到它在哪些包中出现了。

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.