9

I want to create a war file from a Spring Boot application, which I can deploy to a standalone Tomcat container, not using the embedded one.

I can create the war file and run it on its own using "java -jar pdfjs-annotator.war" and it works fine.

I built the application using gradle bootRepackage (Using Gradle, Tomcat7, Java 1.7).

But when I deploy the war file to a standalone Tomcat and start it, the app seems to boot without errors according to the log, but I cannot access any of the resources nor do the controller urls work.

For example, my index.html is a static html page under src/main/resources/static/index.html, which I can usually call via localhost:8080/index.html, but when deployed to a standalone Tomcat, the page does not get delivered (it's then in the war file in WEB-INF/classes/static/index.html) through that same url. And also any kind of controller mapping don't seem to work. I am getting a 404 error instead.

build.gradle:

buildscript {
    ext {
        springBootVersion = '1.2.3.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
        classpath("io.spring.gradle:dependency-management-plugin:0.5.0.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse-wtp'
apply plugin: 'idea'
apply plugin: 'spring-boot' 
apply plugin: 'io.spring.dependency-management' 
apply plugin: 'war'


war {
    baseName = 'pdfjs-annotator'
    version = '1.0.0-SNAPSHOT'
}

allprojects {
    apply plugin: 'java'
    sourceCompatibility = 1.6
    targetCompatibility = 1.6
}

repositories {
    mavenCentral()
}

configurations {
    providedRuntime
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-data-jpa")
    compile("org.springframework.boot:spring-boot-starter-data-rest")
    compile("org.springframework.boot:spring-boot-starter-web")
    runtime("mysql:mysql-connector-java")
    providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
    testCompile("org.springframework.boot:spring-boot-starter-test")
    compile ('org.hibernate.javax.persistence:hibernate-jpa-2.0-api:1.0.1.Final')
}


eclipse {
    classpath {
         containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
         containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7'
    }
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.3'
}

My main application class:

@EnableJpaRepositories
@SpringBootApplication
public class PdfAnnotator extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(PdfAnnotator.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(PdfAnnotator.class);
    }

}

When I look into the exploded war, I do see the following META-INF/MANIFEST.MF:

Manifest-Version: 1.0
Start-Class: com.mypackage.pdfcomment.PdfAnnotator
Spring-Boot-Version: 1.2.3.RELEASE
Main-Class: org.springframework.boot.loader.WarLauncher

The gradle build process usually generated two war artifacts, one named .war and one named .war.original - the .war is the one that holds proper MANIFEST.MF entries and it's the one I used to deploy to the standalone Tomcat.

What's missing? I already checked other questions here on SO:

and also the Spring Boot docs, but could not find a hint of what's wrong.

* === Update === *

I installed a brand new Tomcat7, deployed the war file there, and everything's working fine. Seemed to be some issue with the Tomcat instance/configuration I had running. Not sure what exactly the issue was, but I won't bother to check it further since it's working fine now with the new Tomcat.

Community
  • 1
  • 1
Mathias Conradt
  • 28,420
  • 21
  • 138
  • 192
  • Spring Boot gradle plugin does usually create two artifacts one with the tomcat inside and one not. I forgot about the nameing but just try both. Beside that I would use a war file. I know that it isn't necessary anymore but to be safe. – mh-dev May 09 '15 at 18:10
  • @mh-dev Right, I think you mean .war and .war.original - I will give it a try. So far, I've just used the .war. – Mathias Conradt May 09 '15 at 18:11
  • @mh-dev I tried both, but no difference. The .war that I used should be the right one anyway, because that's the only one that has proper MANIFEST.MF entries. – Mathias Conradt May 09 '15 at 18:16
  • Did you check with the tomcat adminstration panel if the app was deployed and checked all tomcat logs for anything? (also the context path of your app) – mh-dev May 09 '15 at 18:18
  • Yes, the app is properly loaded as I can see in the Tomcat manager and I can see no errors in the log. Log of boot up process is here: http://pastebin.com/sHNgQrRr – Mathias Conradt May 09 '15 at 18:21
  • It seems as if some kind of Dispatcher logic is missing, i.e. for serving the html pages from WEB-INF/classes/static, but Spring Boot docs doesn't say much about it. – Mathias Conradt May 09 '15 at 18:23
  • Are you 100% sure that your test context path is correct, because this is differnt between spring boot with embedded tomcat and in the deployed app. – mh-dev May 09 '15 at 18:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/77407/discussion-between-mathias-lin-and-mh-dev). – Mathias Conradt May 09 '15 at 18:24
  • The log output shows that the app has started successfully so your build.gradle and app configuration are, more than likely, correct. The log on pastebin shows a context path of `/pdfjs-annotator-1.0.0-SNAPSHOT`. Have you tried `http://localhost:8080/pdfjs-annotator-1.0.0-SNAPSHOT/index.html`? – Andy Wilkinson May 10 '15 at 06:22
  • @AndyWilkinson Yes, tried it already. – Mathias Conradt May 10 '15 at 07:45
  • 1
    Update: Thanks to @mh-dev for the time and support via TeamViewer yesterday. The project is actually setup correctly, it seems to be something with the Tomcat instance I had running. I setup a brand new Tomcat7 instance, deployed the war, and everything's fine. So obviously some issues with the Tomcat I had been using. – Mathias Conradt May 10 '15 at 07:46

2 Answers2

3

I had this exact problem. It was because my application was built with Java 1.8 but Tomcat was running with 1.7. Everything appeared to deploy properly and there were no errors. I simply got a 404 trying to hit my services which had otherwise been fine with the embedded tomcat server. Took me ages to figure it out but it was just a case of upgrading java on the Tomcat installation.

Daisy Day
  • 652
  • 7
  • 19
0

The project is actually setup correctly and it turned out that the problem was with the Tomcat instance I was running. Probably something wrong with the configuration or jars. The instance is in place already for a long time, maybe things got messed up over time.

Now with a brand new Tomcat7 instance installed, the war works just fine.

Mathias Conradt
  • 28,420
  • 21
  • 138
  • 192
  • I think this could be your problem http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file – Giordano Jun 11 '15 at 13:29
  • I had all this in place, but didn't work. Anyway, it was related to the Tomcat instance itself, not the app. – Mathias Conradt Jun 11 '15 at 17:19