cannot access org.springframework.web.WebApplicationInitializer
Asked Answered
C

4

7

I am currently working through the example on scheduling tasks using Spring 4, Java 1.8, and Gradle (https://spring.io/guides/gs/scheduling-tasks/).

However, when running this example, I receive the following error:

Error:(11, 8) java: cannot access org.springframework.web.WebApplicationInitializer class file for org.springframework.web.WebApplicationInitializer not found

The source code to my Application.java is as follows:

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class Application extends SpringBootServletInitializer {

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

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class);
    }
}

My gradle file:

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.2.RELEASE")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'war'

jar {
    baseName = 'gs-scheduling-tasks'
    version =  '0.1.0'
}

repositories {
    mavenCentral()
}

sourceCompatibility = 1.8
targetCompatibility = 1.8

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

Why is org.springframework.web.WebApplicationInitializer causing this error when it is not even mentioned in the guide?

Thanks.

Comanchean answered 13/12, 2016 at 19:59 Comment(2)
can you post your gradle fileFoliaceous
@KlausGroenbaek sure, I have added that to my original post as well. Thanks.Comanchean
D
10

Add this dependency to fix this problem. I perfectly worked for me.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency> 
Dwayne answered 6/11, 2018 at 11:44 Comment(0)
F
8

The guide does not extend SpringBootServletInitializer, remove it or add spring-boot-starter-web as a dependency if you want to start a Tomcat webserver inside you application.

Foliaceous answered 13/12, 2016 at 20:12 Comment(1)
Thanks. I added that dependency and now it works exactly the way I wanted.Comanchean
I
1

You are extending SpringBootServletInitializer which implements WebApplicationInitializer

check http://grepcode.com/file/repo1.maven.org/maven2/org.springframework.boot/spring-boot/1.0.2.RELEASE/org/springframework/boot/context/web/SpringBootServletInitializer.java

Use this Application class instead as the guide is showing

@SpringBootApplication
@EnableScheduling
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class);
    }
}
Indeterminism answered 13/12, 2016 at 20:11 Comment(3)
Good link. Now this makes sense. Thanks.Comanchean
I do not like this answer since sometimes you just need the SpringBootServletInitializer if your company ensists on deploying to e.g. PayaraVituperation
@GinaDeBeukelaer, thank you for the comment. The user was working with a certain guide only for Spring Boot.Indeterminism
P
0

As @Sully pointed out, SpringBootServletInitializer indeed implements WebApplicationInitializer, yet both are in different JAR-s (artifacts). It's perfectly reasonable NOT TO use spring-boot-starter-web when you want to deploy your WAR file to standalone Tomcat — otherwise you would include Tomcat's engine (unless you explicitly exclude it from dependencies). If that's the case, then I suggest to put in the parent POM:

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>${spring.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <version>${servlet-api.version}</version>
      </dependency>
    </dependencies>
  </dependencyManagement>

and then in your "web module" project:

  <dependencies>
    <dependency>
      <groupId>jakarta.servlet</groupId>
      <artifactId>jakarta.servlet-api</artifactId>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
    </dependency>
  </dependencies>

The spring-boot-dependencies provides both spring-boot-starter and spring-web (that contains missing class). But to make everything work, you need to provide also the servlet API, hence we add also that one.

With this approach you have the minimal WAR size and don't have to remember to exclude Tomcat dependencies.

Psycholinguistics answered 3/1 at 9:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.