Search code examples
tomcatspring-bootgradlevaadinvaadin8

Deploying Vaadin/SpringBoot as WAR


Am trying to deploy a minimal Vaadin/SpringBoot application as a WAR file into a stand-alone Tomcat.

Everything works if I run gradle vaadinRun and access under localhost:8080, but creating the WAR file with gradle war and then copying it into the webapps folder of my Tomcat results in a 404. Unfortunately Tomcat logs don't show anything. Trying to access via localhost:8080/hello-vaadin.

Here is the application class itself:

package com.somecompany;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.servlet.ServletComponentScan;
import com.vaadin.spring.annotation.EnableVaadin;

@ServletComponentScan
@SpringBootApplication
@EnableVaadin
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) throws Exception {
        configureApplication(new SpringApplicationBuilder()).run(args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
         return configureApplication(builder);
    }

    private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }

}

This is the corresponding UI-class:

package com.somecompany;

import com.vaadin.annotations.Theme;
import com.vaadin.spring.annotation.SpringUI;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.UI;
import com.vaadin.ui.Grid;
import org.springframework.beans.factory.annotation.Autowired;
import com.vaadin.ui.Label;

@SpringUI
@Theme("valo")
public class HelloWorldUI extends UI {

    @Autowired
    public HelloWorldUI() {

    }

    @Override
    protected void init(VaadinRequest request) {
        setContent(new Label("Hello World!"));
    }

}

And finally my gradle script:

plugins {
    id "java"
    id "com.devsoap.plugin.vaadin" version "1.2.4"
    id "org.springframework.boot" version "1.5.7.RELEASE"
}

jar {
    baseName = 'com.somecompany.hello-vaadin'
    version =  '0.0.1-SNAPSHOT'
}

apply plugin: 'war'

war {
    baseName = 'hello-vaadin'
    version =  '1.0'
}

springBoot {
    mainClass = 'com.somecompany.Application'
}

bootRepackage {
    mainClass = 'com.somecompany.Application'
}

repositories {
    jcenter()
    mavenCentral()
    maven { url "http://oss.sonatype.org/content/repositories/vaadin-snapshots/" }
    maven { url 'https://repo.spring.io/libs-release' }
    maven { url "https://repository.jboss.org/nexus/content/repositories/releases" }
}

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
}

After going through tutorial after tutorial, there must be something that I overlook. But what, I don't see what the problem could be?

Any hints highly appreciated!


Solution

  • Finally, I have managed to make it work. This is how:

    MyApplication.java

    package com.somecompany;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MyApplication {
        public static void main(String[] args) throws Exception {
            SpringApplication.run(MyApplication.class, args);
        }
    }
    

    MyServletInitializer.java

    package com.somecompany;
    
    import org.springframework.boot.web.support.SpringBootServletInitializer;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    
    public class MyServletInitializer extends SpringBootServletInitializer {
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
            return builder.sources(MyApplication.class);
        }
    }
    

    MyConfiguration.java

    package com.somecompany;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Bean;
    
    @Configuration
    public class MyConfiguration {
        @Bean
        public String myLabelString() {
            return "Hello World Bean!";
        }
    }
    

    HelloWorldUI.java

    package com.somecompany;
    
    import com.vaadin.spring.annotation.SpringUI;
    import com.vaadin.server.VaadinRequest;
    import com.vaadin.ui.UI;
    import org.springframework.beans.factory.annotation.Autowired;
    import com.vaadin.ui.Label;
    
    @SpringUI
    public class HelloWorldUI extends UI {
    
        @Autowired
        String helloWorldString;
    
        @Override
        protected void init(VaadinRequest request) {
            if (helloWorldString != null) {
                setContent(new Label(helloWorldString));
            } else {
                setContent(new Label("Injection does not work!"));
            }
        }
    }
    

    build.gradle

    plugins {
        id 'com.devsoap.plugin.vaadin' version '1.2.1'
        id 'org.springframework.boot' version '1.5.3.RELEASE'
    }
    
    apply plugin: 'war'
    
    war {
        baseName = 'hellovaadin'
    }
    
    springBoot {
        mainClass = 'com.somecompany.MyApplication'
    }
    

    Then with gradle build I build the WAR file and then copy it into the webapps folder of my tomcat instance.

    I have extended the example by also showing how to inject/autowire a bean.