Cannot instantiate interface org.springframework.context.ApplicationListener after adding spring-security-oauth2

Stefan Falk picture Stefan Falk · Oct 29, 2017 · Viewed 29k times · Source

After I added spring-security-oauth2 to my pom.xml:

<dependency>
    <groupId>org.springframework.security.oauth</groupId>
    <artifactId>spring-security-oauth2</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>

I started to get

Exception in thread "main" java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationListener : org.springframework.boot.context.logging.ClasspathLoggingApplicationListener
    at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:439)
    at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:418)
    at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:409)
    at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:268)
    at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:247)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1245)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1233)

after running my @SpringBootApplication. Please note that I am using Spring Boot 2.0.0.M5 and I think that this might be the root of the problem (w.r.t. versions).

This is the entire pom.xml I'm using:;

<?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>

    <parent>
        <artifactId>server</artifactId>
        <groupId>mahlzeit</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>api</artifactId>

    <properties>
        <spring.boot.version>2.0.0.M5</spring.boot.version>
    </properties>

    <dependencies>

        <!-- Spring Framework Boot -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring.boot.version}</version>
            <scope>test</scope>
        </dependency>

        <!-- Spring Framework -->

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
            <version>1.0.8.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
            <version>2.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>9.4.1208-jdbc42-atlassian-hosted</version>
        </dependency>

        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

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

    <repositories>
        <!-- Required since this is currently using Spring RC version -->
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/libs-milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>

I have the suspicion this might have to do with conflicting versions - most answers on stackoverflow turn out to be just that - but I cannot make out the actual issue I am having here.


The release notes for Spring Boot 2.0.0.M5 state:

OAuth 2.0 Support

Functionality from the Spring Security OAuth project is being migrated to core Spring Security. OAuth 2.0 client support has already been added and additional features will be migrated in due course.

If you depend on Spring Security OAuth features that have not yet been migrated you will need to add org.springframework.security.oauth:spring-security-oauth2 and configure things manually. If you only need OAuth 2.0 client support you can use the auto-configuration provided by Spring Boot 2.0. We’re also continuing to support Spring Boot 1.5 so older applications can continue to use that until an upgrade path is provided.

Answer

Andy Wilkinson picture Andy Wilkinson · Oct 31, 2017

Having fixed the problems with the example's pom, I can now see the complete stack trace of the failure:

Exception in thread "main" java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationListener : org.springframework.boot.context.logging.ClasspathLoggingApplicationListener
    at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:439)
    at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:418)
    at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:409)
    at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:268)
    at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:247)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1245)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1233)
    at mahlzeit.api.Application.main(Application.java:14)
Caused by: java.lang.NoClassDefFoundError: org/springframework/context/event/GenericApplicationListener
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:362)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:361)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at org.springframework.util.ClassUtils.forName(ClassUtils.java:255)
    at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:431)
    ... 7 more
Caused by: java.lang.ClassNotFoundException: org.springframework.context.event.GenericApplicationListener
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 21 more

The root cause of the problem is that org.springframework.context.event.GenericApplicationListener isn't on the classpath. This class is part of the spring-context module and is new in Spring Framework 4.2.

Looking at the pom, you're not using Boot's dependency management (either by importing the spring-boot-dependencies bom or by using spring-boot-starter-parent as your project's parent. This means that the versions of any transitive dependencies aren't being managed. That's causing the problem here as your project is using 4.0.9.RELEASE of spring-context transitively via spring-security-oauth2.

I would strongly recommend that you use Spring Boot's dependency management. If you don't want to do that or can't do that for some unstated reason, you will have to manually ensure that all transitive dependencies have supported versions.