I am trying to create a Spring Boot project with spring-boot-starter-hateoas.

pom.xml

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

    <groupId>com.company</groupId>
    <artifactId>project</artifactId>
    <version>0.1.0</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>10</maven.compiler.source>
        <maven.compiler.target>10</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
            <version>2.0.3.RELEASE</version>
        </dependency>
    </dependencies>
</project>

ProjectApplication.java

package com.company.project.web;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

HelloWorldController.java

package com.company.project.web.controller;

import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/hello-world")
public class HelloWorldController {
    @GetMapping
    public ResponseEntity<String> getHelloWorld() {
        final var body = "Hello, World!";
        return ResponseEntity.ok(body);
    }
}

"Process finished with exit code 1" is all I get in IntelliJ IDEA when I run this application. I've also tried packaging it as a JAR and running it outside the IDE. Setting the parent to spring-boot-starter-parent or including spring-boot-starter-web as well solves the problem.

I might be mistaken, but just including the HATEOAS starter should be enough to get everything up and running, right? I also had to include the logging library. Not sure if that is related.

Comment From: snicoll

I might be mistaken, but just including the HATEOAS starter should be enough to get everything up and running, right?

No. Adding that HATEOAS starter doesn't turn your application into a web application. In the future please ask questions on StackOverflow. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Comment From: peterjohansen

Sorry, I think I phrased it poorly. Is it intended behavior that the application silently fails when only the HATEOAS starter is included? Not much of a starter if it crashes and doesn't tell you why. With just pom.xml and ProjectApplication.java it still fails, but if spring-boot-starter-hateoas is replaced with spring-boot-starter it starts up and shuts down properly. I just wanted to clarify what I meant since it seems like a bug to me.

Comment From: snicoll

In the meantime @wilkinsona reminded me that our hateoas starter does indeed bring the web starter (which is something we may want to fix at some point)

I can see your project doesn't use any dependency management whatsoever (hardcoding versions for each dependency is a smell). If you use our starter parent (that does apply dependency management) the problem does not occur.

We're not 100% sure yet where that's coming from so we'll have another pass to it.

Comment From: wilkinsona

Spring Boot 2.0 relies upon Spring Framework 5's spring-icl module in place of Commons Logging. When you launch the app with no dependency management and a dependency on spring-boot-starter-hateoas:2.0.3.RELEASE it fails with the following exception:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
    at org.springframework.boot.SpringApplication.<clinit>(SpringApplication.java:198)
    at com.example.demo.Gh13789Application.main(Gh13789Application.java:10)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 2 more

If you look a the output from mvn dependency:tree you can see why:

[INFO] com.example:gh-13789:jar:0.0.1-SNAPSHOT
[INFO] \- org.springframework.boot:spring-boot-starter-hateoas:jar:2.0.3.RELEASE:compile
[INFO]    +- org.springframework.boot:spring-boot-starter-web:jar:2.0.3.RELEASE:compile
[INFO]    |  +- org.springframework.boot:spring-boot-starter:jar:2.0.3.RELEASE:compile
[INFO]    |  |  +- org.springframework.boot:spring-boot:jar:2.0.3.RELEASE:compile
[INFO]    |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.0.3.RELEASE:compile
[INFO]    |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.0.3.RELEASE:compile
[INFO]    |  |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO]    |  |  |  |  \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO]    |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.10.0:compile
[INFO]    |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.10.0:compile
[INFO]    |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO]    |  |  +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO]    |  |  \- org.yaml:snakeyaml:jar:1.19:runtime
[INFO]    |  +- org.springframework.boot:spring-boot-starter-json:jar:2.0.3.RELEASE:compile
[INFO]    |  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.6:compile
[INFO]    |  |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO]    |  |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.9.6:compile
[INFO]    |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.6:compile
[INFO]    |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.6:compile
[INFO]    |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.6:compile
[INFO]    |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.0.3.RELEASE:compile
[INFO]    |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.31:compile
[INFO]    |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.31:compile
[INFO]    |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.31:compile
[INFO]    |  +- org.hibernate.validator:hibernate-validator:jar:6.0.10.Final:compile
[INFO]    |  |  +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO]    |  |  +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[INFO]    |  |  \- com.fasterxml:classmate:jar:1.3.4:compile
[INFO]    |  +- org.springframework:spring-web:jar:5.0.7.RELEASE:compile
[INFO]    |  \- org.springframework:spring-webmvc:jar:5.0.7.RELEASE:compile
[INFO]    |     \- org.springframework:spring-expression:jar:5.0.7.RELEASE:compile
[INFO]    +- org.springframework.hateoas:spring-hateoas:jar:0.24.0.RELEASE:compile
[INFO]    |  +- org.springframework:spring-aop:jar:4.3.12.RELEASE:compile
[INFO]    |  +- org.springframework:spring-beans:jar:4.3.12.RELEASE:compile
[INFO]    |  +- org.springframework:spring-context:jar:4.3.12.RELEASE:compile
[INFO]    |  +- org.springframework:spring-core:jar:4.3.12.RELEASE:compile
[INFO]    |  \- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO]    \- org.springframework.plugin:spring-plugin-core:jar:1.2.0.RELEASE:compile

Note that a number of Spring Framework jars have the version 4.3.12.RELEASE. This is because this is the default version used by Spring HATEOAS. Its dependency on, for example, spring-core is closest to the root of the tree so Maven prefers its version (this problem would not occur with Gradle as, when the same dependency appears multiple times in the dependency graph, it prefers the latest version rather than the version that's nearest to the root of the graph).

I guess seeing this exception prompted you to add commons-logging:commons-logging. This, unfortunately, compounded the problem. With Commons Logging in place, the application then fails with an exception caused by the use of Spring Framework 4.3.12 when Boot 2.0 requires Spring Framework 5. The exception is the following:

java.lang.NoSuchMethodError: org.springframework.util.Assert.isTrue(ZLjava/util/function/Supplier;)V
    at org.springframework.boot.context.properties.bind.Bindable.withExistingValue(Bindable.java:162)
    at org.springframework.boot.context.properties.bind.Bindable.ofInstance(Bindable.java:192)
    at org.springframework.boot.SpringApplication.bindToSpringApplication(SpringApplication.java:545)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:359)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:317)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
    at com.example.demo.Gh13789Application.main(Gh13789Application.java:10)

This exception is passed into Commons Logging's JDK 1.4 logger (Java Util Logging) and it swallows it. This appears to be related to Spring Boot's logging system configuration. Launching the app with -Dorg.springframework.boot.logging.LoggingSystem=none" results in the following output:

14:46:06.099 [background-preinit] DEBUG org.jboss.logging - Logging Provider: org.jboss.logging.Log4j2LoggerProvider
14:46:06.103 [background-preinit] INFO org.hibernate.validator.internal.util.Version - HV000001: Hibernate Validator 6.0.10.Final
14:46:06.109 [background-preinit] DEBUG org.hibernate.validator.internal.engine.resolver.TraversableResolvers - Cannot find javax.persistence.Persistence on classpath. Assuming non JPA 2 environment. All properties will per default be traversable.
14:46:06.112 [background-preinit] DEBUG org.hibernate.validator.internal.xml.ValidationXmlParser - Trying to load META-INF/validation.xml for XML based Validator configuration.
14:46:06.113 [background-preinit] DEBUG org.hibernate.validator.internal.xml.ResourceLoaderHelper - Trying to load META-INF/validation.xml via TCCL
14:46:06.113 [background-preinit] DEBUG org.hibernate.validator.internal.xml.ResourceLoaderHelper - Trying to load META-INF/validation.xml via Hibernate Validator's class loader
14:46:06.114 [background-preinit] DEBUG org.hibernate.validator.internal.xml.ValidationXmlParser - No META-INF/validation.xml found. Using annotation based configuration only.
14:46:06.234 [background-preinit] DEBUG org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator - Loaded expression factory via original TCCL
14:46:06.238 [background-preinit] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator as ValidatorFactory-scoped message interpolator.
14:46:06.238 [background-preinit] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.resolver.TraverseAllTraversableResolver as ValidatorFactory-scoped traversable resolver.
14:46:06.238 [background-preinit] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.util.ExecutableParameterNameProvider as ValidatorFactory-scoped parameter name provider.
14:46:06.238 [background-preinit] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.DefaultClockProvider as ValidatorFactory-scoped clock provider.
14:46:06.239 [background-preinit] DEBUG org.hibernate.validator.internal.engine.ValidatorFactoryImpl - HV000234: Using org.hibernate.validator.internal.engine.scripting.DefaultScriptEvaluatorFactory as ValidatorFactory-scoped script evaluator factory.
Jul 17, 2018 2:46:06 PM org.springframework.boot.SpringApplication reportFailure
SEVERE: Application run failed
java.lang.NoSuchMethodError: org.springframework.util.Assert.isTrue(ZLjava/util/function/Supplier;)V
    at org.springframework.boot.context.properties.bind.Bindable.withExistingValue(Bindable.java:162)
    at org.springframework.boot.context.properties.bind.Bindable.ofInstance(Bindable.java:192)
    at org.springframework.boot.SpringApplication.bindToSpringApplication(SpringApplication.java:545)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:359)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:317)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
    at com.example.demo.Gh13789Application.main(Gh13789Application.java:11)

Comment From: wilkinsona

This appears to have been a regression. 2.0.0.RELEASE fails with the following output:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.0.RELEASE)

2018-07-17 15:05:50.636  INFO 24181 --- [           main] com.example.demo.Gh13789Application      : Starting Gh13789Application on aw-rmbp.local with PID 24181 (/Users/awilkinson/dev/workspaces/spring/spring-boot/2.0.x/gh-13789/target/classes started by awilkinson in /Users/awilkinson/dev/workspaces/spring/spring-boot/2.0.x/gh-13789)
2018-07-17 15:05:50.639  INFO 24181 --- [           main] com.example.demo.Gh13789Application      : No active profile set, falling back to default profiles: default
2018-07-17 15:05:50.712  INFO 24181 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@d6da883: startup date [Tue Jul 17 15:05:50 BST 2018]; root of context hierarchy
2018-07-17 15:05:51.126  WARN 24181 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration]; nested exception is java.lang.NoSuchMethodError: org.springframework.util.Assert.state(ZLjava/util/function/Supplier;)V
2018-07-17 15:05:51.139 ERROR 24181 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Destroy method on bean with name 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory' threw an exception

java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@d6da883: startup date [Tue Jul 17 15:05:50 BST 2018]; root of context hierarchy
    at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:414) [spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.context.support.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.destroySingletons(FactoryBeanRegistrySupport.java:230) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1030) [spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:556) [spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:388) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1234) [spring-boot-2.0.0.RELEASE.jar:2.0.0.RELEASE]
    at com.example.demo.Gh13789Application.main(Gh13789Application.java:11) [classes/:na]

2.0.1, 2.0.2, and 2.0.3 all fail silently. 2.0.4 snapshots fail with the following output:

Jul 17, 2018 3:10:15 PM org.springframework.boot.SpringApplication reportFailure
SEVERE: Application run failed
java.lang.NoSuchMethodError: org.springframework.util.Assert.isTrue(ZLjava/util/function/Supplier;)V
    at org.springframework.boot.context.properties.bind.Bindable.withExistingValue(Bindable.java:162)
    at org.springframework.boot.context.properties.bind.Bindable.ofInstance(Bindable.java:192)
    at org.springframework.boot.SpringApplication.bindToSpringApplication(SpringApplication.java:548)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:362)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1258)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1246)
    at com.example.demo.Gh13789Application.main(Gh13789Application.java:11)

This seems better than 2.0.0 as it clearly shows the stack trace of the first failure rather than of a subsequent failure.

Comment From: Saravana94

What is the solution for this issue?

java.lang.NoSuchMethodError: org.springframework.util.Assert.isTrue(ZLjava/util/function/Supplier;)V

Comment From: wilkinsona

@Saravana94 You need to ensure that you have the required version of Spring Framework on your classpath. Using Spring Boot's dependency management is the recommended way to do that. Exactly what needs to be done depends on whether you're using Maven or Gradle.

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.