I have a GWT application (gwt 2.8) on wich I want to add Spring-Boot dependency (1.5.3.RELEASE). I want a standalone executable war application
Here is my web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee">
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.mycompany.fonems.webapp.server.FonemsWebappApplication</param-value>
</init-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Servlets -->
<servlet>
<servlet-name>messageServlet</servlet-name>
<servlet-class>com.mycompany.fonems.webapp.server.FONEMSWebMessageServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>messageServlet</servlet-name>
<url-pattern>/fonemswebapp/FONEMSWebMessageService.rpc</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>securityServlet</servlet-name>
<servlet-class>com.mycompany.fonems.webapp.server.FONEMSWebSecurityServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>securityServlet</servlet-name>
<url-pattern>/fonemswebapp/FONEMSWebSecurityService.rpc</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>loginServlet</servlet-name>
<servlet-class>com.mycompany.fonems.webapp.server.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<filter>
<filter-name>gwtCacheControlFilter</filter-name>
<filter-class>com.mycompany.fonems.webapp.server.GWTCacheControlFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gwtCacheControlFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>Fonemswebapp.html</welcome-file>
</welcome-file-list>
</web-app>
where FonemsWebappApplication is my spring-boot entry point class.
package com.mycompany.fonems.webapp.server;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
#Slf4j
#Configuration
#ComponentScan(basePackages = { "com.mycompany.fonems" })
#EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class FonemsWebappApplication {
#Inject
private Environment env;
public static void main(String[] args) throws UnknownHostException {
log.info("-------------------------------\tApplication is starting ...");
SpringApplicationBuilder app = new SpringApplicationBuilder(FonemsWebappApplication.class);
Environment env = app.run(args).getEnvironment();
String portNumber = env.getProperty("server.port");
log.info("\n----------------------------------------------------------\n\t"
+ "Application '{}' is running! Access URLs:\n\t" + "Local: \t\thttp://127.0.0.1:{}\n\t"
+ "External: \thttp://{}:{}\n----------------------------------------------------------",
env.getProperty("spring.application.name"), portNumber, InetAddress.getLocalHost().getHostAddress(), portNumber);
log.info("-------------------------------\tApplication is running");
}
}
I launch my application. It seems to start with no error. Nevertheless, in my web broser I have this error:
Problem accessing /fonemswebapp/FONEMSWebMessageService.rpc
The path is not found
Here the logs:
[ main] o.s.w.s.resource.ResourceUrlProvider : Looking for resource handler mappings
[ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/**/favicon.ico", locations=[ServletContext resource [/
], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/], class path resource []], resolvers=[org.springframework.we
b.servlet.resource.PathResourceResolver#7de5871d]
[ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/webjars/**", locations=[class path resource [META-INF/
resources/webjars/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResolver#49d42faf]
[ main] o.s.w.s.resource.ResourceUrlProvider : Found resource handler mapping: URL pattern="/**", locations=[ServletContext resource [/], class pat
h resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resolvers=[org.springframework.web.servlet.resource.PathResourceResol
ver#4948daec]
[ main] o.s.web.servlet.DispatcherServlet : Initializing servlet 'dispatcherServlet'
[ main] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
[ main] o.s.web.servlet.DispatcherServlet : Using MultipartResolver [org.springframework.web.multipart.support.StandardServletMultipartResolver#
709d86a2]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate LocaleResolver with name 'localeResolver': using default [org.springframework.web.s
ervlet.i18n.AcceptHeaderLocaleResolver#2e1add6f]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate ThemeResolver with name 'themeResolver': using default [org.springframework.web.ser
vlet.theme.FixedThemeResolver#46702c26]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate RequestToViewNameTranslator with name 'viewNameTranslator': using default [org.spri
ngframework.web.servlet.view.DefaultRequestToViewNameTranslator#2e3cd732]
[ main] o.s.web.servlet.DispatcherServlet : Unable to locate FlashMapManager with name 'flashMapManager': using default [org.springframework.web
.servlet.support.SessionFlashMapManager#7f6b57f2]
[ main] o.s.web.servlet.DispatcherServlet : Published WebApplicationContext of servlet 'dispatcherServlet' as ServletContext attribute with name
[org.springframework.web.servlet.FrameworkServlet.CONTEXT.dispatcherServlet]
[ main] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 31 ms
[ main] o.s.web.servlet.DispatcherServlet : Servlet 'dispatcherServlet' configured successfully
[ main] .s.b.c.e.j.JettyEmbeddedServletContainer : Jetty started on port(s) 8088 (http/1.1)
[ main] o.s.w.c.s.StandardServletEnvironment : Adding [server.ports] PropertySource with highest search precedence
[ main] c.n.f.w.server.FonemsWebappApplication : Started FonemsWebappApplication in 7.634 seconds (JVM running for 8.248)
[ main] c.n.f.w.server.FonemsWebappApplication :
----------------------------------------------------------
Application 'fonems-webapp-refonte' is running! Access URLs:
Local: http://127.0.0.1:8088
External: http://10.20.146.96:8088
----------------------------------------------------------
[ main] c.n.f.w.server.FonemsWebappApplication : ------------------------------- Application is running
<< Then I launch this URL: http://127.0.0.1:8088/Fonemswebapp.html in my web broser>>
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/fonemswebapp/fonemsweba
pp.nocache.js]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /fonemswebapp/fonemswebapp.nocache.js
s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/fonemswebapp/fonemswebapp.nocache.js]
o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/fonemswebapp/fonemswebapp.nocache.js] are [/**]
o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/fonemswebapp/fonemswebapp.nocache.js] are {}
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/fonemswebapp/fonemswebapp.nocache.js] to HandlerExecutionChain with handler [ResourceHttpR
equestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resol
vers=[org.springframework.web.servlet.resource.PathResourceResolver#4948daec]]] and 1 interceptor
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/fonemswebapp/fonemswebapp.nocache.js] is: -1
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.Str
ing, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
o.s.w.s.m.m.a.HttpEntityMethodProcessor : Written [{timestamp=Fri Jun 16 11:02:10 CEST 2017, status=404, error=Not Found, message=Not Found, p
ath=/fonemswebapp/fonemswebapp.nocache.js}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#6b09ce57]
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/fonemswebapp/fonemsweba
pp.nocache.js]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /fonemswebapp/fonemswebapp.nocache.js
s.w.s.m.m.a.RequestMappingHandlerMapping : Did not find handler method for [/fonemswebapp/fonemswebapp.nocache.js]
o.s.w.s.handler.SimpleUrlHandlerMapping : Matching patterns for request [/fonemswebapp/fonemswebapp.nocache.js] are [/**]
o.s.w.s.handler.SimpleUrlHandlerMapping : URI Template variables for request [/fonemswebapp/fonemswebapp.nocache.js] are {}
o.s.w.s.handler.SimpleUrlHandlerMapping : Mapping [/fonemswebapp/fonemswebapp.nocache.js] to HandlerExecutionChain with handler [ResourceHttpR
equestHandler [locations=[ServletContext resource [/], class path resource [META-INF/resources/], class path resource [resources/], class path resource [static/], class path resource [public/]], resol
vers=[org.springframework.web.servlet.resource.PathResourceResolver#4948daec]]] and 1 interceptor
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/fonemswebapp/fonemswebapp.nocache.js] is: -1
o.s.web.servlet.DispatcherServlet : DispatcherServlet with name 'dispatcherServlet' processing GET request for [/error]
s.w.s.m.m.a.RequestMappingHandlerMapping : Looking up handler method for path /error
s.w.s.m.m.a.RequestMappingHandlerMapping : Returning handler method [public org.springframework.http.ResponseEntity<java.util.Map<java.lang.Str
ing, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)]
o.s.web.servlet.DispatcherServlet : Last-Modified value for [/error] is: -1
o.s.w.s.m.m.a.HttpEntityMethodProcessor : Written [{timestamp=Fri Jun 16 11:02:10 CEST 2017, status=404, error=Not Found, message=Not Found, p
ath=/fonemswebapp/fonemswebapp.nocache.js}] as "application/json" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#6b09ce57]
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
o.s.web.servlet.DispatcherServlet : Null ModelAndView returned to DispatcherServlet with name 'dispatcherServlet': assuming HandlerAdapt
er completed request handling
o.s.web.servlet.DispatcherServlet : Successfully completed request
When I launch the url in firefox, my form is displayed. When I click on search button, I have this error in the broser:
HTTP ERROR 404 Problem accessing /fonemswebapp/FONEMSWebMessageService.rpc. Reason: Not Found
Here is my pom.xml
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.mycompany.fonems</groupId>
<artifactId>fonems-parent</artifactId>
<version>0.0.140-SNAPSHOT</version>
<relativePath>../fonems-parent/pom.xml</relativePath>
</parent>
<artifactId>fonems-webapp-refonte</artifactId>
<packaging>war</packaging>
<name>FONEMS WebApp</name>
<properties>
<!-- Setting maven.compiler.source to something different to 1.8
needs that you configure the sourceLevel in gwt-maven-plugin since
GWT compiler 2.8 requires 1.8 (see gwt-maven-plugin block below) -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<!-- Don't let your Mac use a crazy non-standard encoding -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- ensure all GWT deps use the same version (unless overridden) -->
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt</artifactId>
<version>${gwt.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mycompany.fonems</groupId>
<artifactId>fonems-fwk-server-common</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.mycompany.fonems</groupId>
<artifactId>fonems-refonte-dao</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<artifactId>javax.el-api</artifactId>
<groupId>javax.el</groupId>
</exclusion>
<exclusion>
<artifactId>xercesImpl</artifactId>
<groupId>xerces</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-servlet</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-user</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.gwt</groupId>
<artifactId>gwt-dev</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.smartgwt</groupId>
<artifactId>smartgwt</artifactId>
<version>${smartgwt.version}</version>
</dependency>
<dependency>
<groupId>com.smartgwt</groupId>
<artifactId>smartgwt-skins</artifactId>
<version>${smartgwt.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mycompany.drh</groupId>
<artifactId>newncauth</artifactId>
<version>${mycompany.drh.version}</version>
</dependency>
<dependency>
<groupId>mycompany.drh</groupId>
<artifactId>mycompany.droits-habilitations.rmi</artifactId>
<version>${mycompany.drh.rmi.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<!-- Output classes directly into the webapp, so that IDEs and "mvn process-classes" update them in DevMode -->
<!-- <outputDirectory>${project.build.directory}/src/main/webapp/WEB-INF/classes</outputDirectory> -->
<plugins>
<!-- GWT Maven Plugin-->
<plugin>
<groupId>net.ltgt.gwt.maven</groupId>
<artifactId>gwt-maven-plugin</artifactId>
<version>${gwt.maven.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>import-sources</goal>
<goal>compile</goal>
<goal>import-test-sources</goal>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<moduleName>com.mycompany.fonems.webapp.Fonemswebapp</moduleName>
<moduleShortName>Fonemswebapp</moduleShortName>
<failOnError>true</failOnError>
<!-- GWT compiler 2.8 requires 1.8, hence define sourceLevel here if you use
a different source language for java compilation -->
<sourceLevel>1.8</sourceLevel>
<!-- Compiler configuration -->
<compilerArgs>
<!-- Ask GWT to create the Story of Your Compile (SOYC) (gwt:compile) -->
<arg>-compileReport</arg>
<arg>-XcompilerMetrics</arg>
</compilerArgs>
<!-- DevMode configuration -->
<warDir>${project.build.directory}/${project.build.finalName}</warDir>
<classpathScope>compile+runtime</classpathScope>
<!-- URL(s) that should be opened by DevMode (gwt:devmode). -->
<startupUrls>
<startupUrl>Fonemswebapp.html</startupUrl>
</startupUrls>
<webappDirectory>${outputFolder}</webappDirectory>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<warSourceDirectory>target/www/</warSourceDirectory>
<packagingExcludes>WEB-INF/lib/tomcat-*.jar</packagingExcludes>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>false</executable>
<!-- Enable the line below to have remote debugging of your application on port 5005 <jvmArguments>-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005</jvmArguments> -->
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Why, in the logs, we see ServletDispatcher occurences? In my application should I define a ServletDispatcher? If it is the case, how to define my 5 web.xml servlets and filter to be taken into account?
What is curious, is that application runs and responds normally when I launch it from the GWT Development Mode (eclipse plugin).
Thank you
Related
Summary :
Testing out Spring Security OAuth2 Resource Server JWT with SpringBoot 2.7.7 which uses Spring Security 5.7.6 to query Authorisation Server at startup.
According to :
https://docs.spring.io/spring-security/reference/5.7/servlet/oauth2/resource-server/jwt.html#_startup_expectations
Startup Expectations
When this property and these dependencies are used, Resource Server
will automatically configure itself to validate JWT-encoded Bearer
Tokens.
It achieves this through a deterministic startup process:
Query the Provider Configuration or Authorization Server Metadata endpoint for the jwks_url property
Query the jwks_url endpoint for supported algorithms
Configure the validation strategy to query jwks_url for valid public keys of the algorithms found
Configure the validation strategy to validate each JWTs iss claim against idp.example.com.
A consequence of this process is that the authorization server must be
up and receiving requests in order for Resource Server to successfully
start up.
If the authorization server is down when Resource Server queries it
(given appropriate timeouts), then startup will fail.
I have the property defined in application.properties AND the dependencies in pom.xml as above.
However, my very small example to try this out does not work ( e.g. The Resource Server does not appear to be querying the Authorisation Server at all at startup, and therefore the Resource Server starts-up successfully.
I was expecting my very small app to fail at startup as per documentation, but it did not ! Went as far as shutting down the Authorisation Server, and the SpringBoot Resources Server app still starts up.
Here's what I did :
1) pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>oauth2-resource-server</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>oauth2-resource-server</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<spring-cloud.version>2021.0.5</spring-cloud.version>
<bootstrap.version>5.2.3</bootstrap.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-oauth2-jose</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency-->
<!--dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency-->
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
2. application.properties
server.port=8081
spring.thymeleaf.cache=false
spring.security.oauth2.resourceserver.jwt.issuer-uri=http://openam.localtest.me:8080/openam/oauth2/realms/subrealm/
spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://openam.localtest.me:8080/openam/oauth2/realms/subrealm/connect/jwk_uri
3. Configuration class:
package org.example.oauth2resourceserver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;
#Configuration
#EnableWebSecurity
public class OAuth2ResourceServerSecurityConfiguration {
#Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}")
String jwkSetUri;
#Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests((authorize) -> authorize
.antMatchers(HttpMethod.GET, "/**").hasAuthority("SCOPE_message:read")
.antMatchers(HttpMethod.POST, "/**").hasAuthority("SCOPE_message:write")
.anyRequest().authenticated()
)
.oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt);
return http.build();
}
#Bean
JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(this.jwkSetUri).build();
}
}
4. Controller
package org.example.oauth2resourceserver;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
#Controller
public class ExampleMVCController {
#GetMapping("/")
public String main(Model model) {
return "welcome";
}
#GetMapping("/welcome")
public String welcome(Model model) {
return "welcome";
}
}
5. Application
package org.example.oauth2resourceserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class Oauth2ResourceServerApplication {
public static void main(String[] args) {
SpringApplication.run(Oauth2ResourceServerApplication.class, args);
}
}
With the Authorisation Server down, output on the console when I run the Resource Server is:
2022-12-28 03:32:38.148 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : Starting Oauth2ResourceServerApplication using Java 11.0.15 on xxxxx-Inspiron-15-7510 with PID 1377958 (/home/xxxxx/projects/oauth2-resource-server/target/classes started by jsalvo in /home/xxxxx/projects/oauth2-resource-server)
2022-12-28 03:32:38.150 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : No active profile set, falling back to 1 default profile: "default"
2022-12-28 03:32:38.561 INFO 1377958 --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=12f14043-de4d-3b01-a8aa-ef038a41274e
2022-12-28 03:32:38.733 INFO 1377958 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8081 (http)
2022-12-28 03:32:38.739 INFO 1377958 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2022-12-28 03:32:38.739 INFO 1377958 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.70]
2022-12-28 03:32:38.819 INFO 1377958 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2022-12-28 03:32:38.820 INFO 1377958 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 634 ms
2022-12-28 03:32:38.931 INFO 1377958 --- [ main] o.s.s.web.DefaultSecurityFilterChain : Will secure any request with [org.springframework.security.web.session.DisableEncodeUrlFilter#748ac6f3, org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter#68f6e55d, org.springframework.security.web.context.SecurityContextPersistenceFilter#2bfaba70, org.springframework.security.web.header.HeaderWriterFilter#5584d9c6, org.springframework.security.web.csrf.CsrfFilter#3bf54172, org.springframework.security.web.authentication.logout.LogoutFilter#58af5076, org.springframework.security.oauth2.server.resource.web.BearerTokenAuthenticationFilter#650c405c, org.springframework.security.web.savedrequest.RequestCacheAwareFilter#9301672, org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter#2577a95d, org.springframework.security.web.authentication.AnonymousAuthenticationFilter#6fff46bf, org.springframework.security.web.session.SessionManagementFilter#17e9bc9e, org.springframework.security.web.access.ExceptionTranslationFilter#4da39ca9, org.springframework.security.web.access.intercept.AuthorizationFilter#2954f6ab]
2022-12-28 03:32:39.140 INFO 1377958 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8081 (http) with context path ''
2022-12-28 03:32:39.152 INFO 1377958 --- [ main] o.e.o.Oauth2ResourceServerApplication : Started Oauth2ResourceServerApplication in 1.27 seconds (JVM running for 1.512)
What am I missing ?
What code in Spring Security OAuth2 Resource Server does the call to the Authorisation Server at startup ?
UPDATE 2022-12-28
As suggested by the comments, I have completely removed my OAuth2ResourceServerSecurityConfiguration above. Still no luck.
On looking at the source code for OAuth2ResourceServerJwtConfiguration.JwtDecoderConfiguration :
It appears that you must only specify one of the following properties, but not both:
spring.security.oauth2.resourceserver.jwt.issuer-uri
spring.security.oauth2.resourceserver.jwt.jwk-set-uri
The method at :
JwtDecoderConfiguration.jwtDecoderByIssuerUri() method has an #IssuerUriCondition annotation that dictates a condition where you must only have the spring.security.oauth2.resourceserver.jwt.issuer-uri property defined.
So I commented out the other property ( commented out spring.security.oauth2.resourceserver.jwt.jwk-set-uri from application.properties), but when I debug into that method via IntelliJ, it steps at line 139 below but it does not step / stop at line 141 within the lambda, which is where the code that actually calls the authorisation server, even if I try to Step-In ( F7 ) from line 139:
In short, I am still at a loss. Anyone have any ideas ?
I am a beginner at spring boot and I cannot my spring boot application on the server. I used tomcat server and IDE as eclipse. I want to run my app in browser.
My console is here
:: Spring Boot :: (v2.4.1)
2021-01-14 09:36:34.144 INFO 14508 --- [ main] com.example.demo.FirstApp1Application : Starting FirstApp1Application using Java 15.0.1 on DESKTOP-TCH1T7S with PID 14508 (E:\springboot\FirstApp1\target\classes started by Samanthika in E:\springboot\FirstApp1)
2021-01-14 09:36:34.160 INFO 14508 --- [ main] com.example.demo.FirstApp1Application : No active profile set, falling back to default profiles: default
2021-01-14 09:36:35.384 INFO 14508 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2021-01-14 09:36:35.397 INFO 14508 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2021-01-14 09:36:35.397 INFO 14508 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
2021-01-14 09:36:35.507 INFO 14508 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2021-01-14 09:36:35.508 INFO 14508 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1283 ms
2021-01-14 09:36:35.730 INFO 14508 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2021-01-14 09:36:35.842 WARN 14508 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.NoSuchMethodError: 'org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.setUseLastModified(boolean)'
2021-01-14 09:36:35.843 INFO 14508 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
2021-01-14 09:36:35.846 INFO 14508 --- [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2021-01-14 09:36:35.864 INFO 14508 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-01-14 09:36:35.879 ERROR 14508 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
An attempt was made to call a method that does not exist. The attempt was made from the following location:
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.addResourceHandlers(WebMvcAutoConfiguration.java:339)
The following method did not exist:
'org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.setUseLastModified(boolean)'
The method's class, org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration, is available from the following locations:
jar:file:/C:/Users/Samanthika/.m2/repository/org/springframework/spring-webmvc/5.2.12.RELEASE/spring-webmvc-5.2.12.RELEASE.jar!/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.class
The class hierarchy was loaded from the following locations:
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration: file:/C:/Users/Samanthika/.m2/repository/org/springframework/spring-webmvc/5.2.12.RELEASE/spring-webmvc-5.2.12.RELEASE.jar
Action:
Correct the classpath of your application so that it contains a single, compatible version of org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration
this is my pom.xml file. hera I have added two dependencies apart from default web dependencies
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>FirstApp1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>FirstApp1</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.12.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Here the FirstApp1Application.java class
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;
#SpringBootApplication
public class FirstApp1Application {
public static void main(String[] args) {
SpringApplication.run(FirstApp1Application.class, args);
System.out.println("Welcome");
}
}
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HomeController {
#RequestMapping(value="/welcome")
public static String Welcome(){
return "Welcome to spring boot";
}
}
Just try to remove the version tag from spring-boot-starter-web dependency and remove the spring-webmvc dependency from pom.xml file.
Removing the version tag from this dependency.
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Most probably you are using incompatible modules. This is also what the error message says:
Correct the classpath of your application so that it contains a
single, compatible version of
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration
In order to fix this go to https://start.spring.io/ and generate a project based on your needs. For an "MVC project" you only need spring-boot-starter-parent and spring-boot-starter-web; you definitely should not bring in webmvc, here's an example pom:
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>15</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Error creating bean with name 'resourceHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.NoSuchMethodError: 'org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.setUseLastModified(boolean)'
Based on the above line, you didn't annotate the class with #Component, IOC can't register that been
I have developed small spring boot application with jar packaging. The application use case is, user will login into application and it will display welcome page. Below is my code.
Main class
package com.ibm.heathcare;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
#SpringBootApplication
#ComponentScan(basePackages= {"com.ibm.heathcare.*"})
public class HeathcareappApplication {
public static void main(String[] args) {
SpringApplication.run(HeathcareappApplication.class, args);
}
}
Login controller class
package com.ibm.heathcare.controller;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.ibm.heathcare.modal.Login;
import com.ibm.heathcare.modal.User;
import com.ibm.heathcare.service.AuthService;
#Controller
#SessionAttributes({"userName","uid"})
public class LoginController {
#Autowired
AuthService authService;
#RequestMapping("/login")
public String showLoginPage(ModelMap model){
//model.addAttribute("login", new Login());
return "login";
}
#RequestMapping("/logout")
public String showLogoutPage(ModelMap model){
model.put("message", "Successfully Log out...");
return "redirect:/login";
}
#RequestMapping("/welcome")
public String showWelcomePage(ModelMap model) {
return "welcome";
}
#RequestMapping(value="/login" ,method=RequestMethod.POST)
public String showwelcomePage(#RequestParam String uid, #RequestParam String pwd,ModelMap model){
Optional<User> optUser=authService.getAuthenticate(uid, pwd);
if(optUser.isPresent()) {
User user=optUser.get();
model.put("userName", user.getUserName() );
model.put("uid", user.getUserId());
return "welcome";
}else {
model.addAttribute("login", new Login("",""));
model.addAttribute("errorMessage",new String("Invalid Credential"));
return "login";
}
}
}
login.jsp
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<form method="post">
User ID :<input type="text" name="uid"/><p>
Password:<input type="password" name="pwd"/><br>
<input type="submit" value="Login" />
</form>
</body>
</html>
welcome.jsp
<%# include file="common/header.jspf" %>
<%# include file="common/navigation.jspf" %>
<div class="jumbotron text-center" >
<h1>Welcome<h1><p>
<h2> ${userName} </h2>
</div>
<%# include file="common/footer.jspf" %>
application.properties
#Server Configuration
server.port = 8282
#ViwResolver
spring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp
POM.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.ibm</groupId>
<artifactId>heathcare</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>heathcareapp</name>
<description>Health Care Management Application</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.9</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.6</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap-datepicker</artifactId>
<version>1.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Now when I have executed this application through eclipse it was working fine.
I have built a jar of application using maven tool which created in target folder. I have executed the application jar from target folder using command line. It worked fine. But when I copy same jar to another folder on my machine and try to execute using java -jar app.jar command and hit the url http://localhost:8282/login in browser it gives me Whitelabel Error Page with status code 404. I am not sure what is wrong with the application. I have searched lot on web and some experts suggested to explicitly write #ComponentScan with basepackage information in main class. I did same but it was not worked for me.
In console I am getting below log.
2020-07-10 10:38:52.605 INFO 11788 --- [ task-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2020-07-10 10:38:53.888 INFO 11788 --- [ main] DeferredRepositoryInitializationListener : Spring Data repositories initialized!
2020-07-10 10:38:53.918 INFO 11788 --- [ main] c.ibm.heathcare.HeathcareappApplication : Started HeathcareappApplication in 24.424 seconds (JVM running for 25.755)
2020-07-10 10:39:18.728 INFO 11788 --- [nio-8282-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2020-07-10 10:39:18.729 INFO 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2020-07-10 10:39:18.730 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Detected StandardServletMultipartResolver
2020-07-10 10:39:18.783 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : enableLoggingRequestDetails='false': request parameters and headers will be masked to prevent unsafe logging of potentially sensitive data
2020-07-10 10:39:18.784 INFO 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 54 ms
2020-07-10 10:39:18.901 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : GET "/login", parameters={}
2020-07-10 10:39:18.916 DEBUG 11788 --- [nio-8282-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to com.ibm.heathcare.controller.LoginController#showLoginPage(ModelMap)
2020-07-10 10:39:19.022 DEBUG 11788 --- [nio-8282-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, application/xhtml+xml, image/webp, application/xml;q=0.9, */*;q=0.8]
2020-07-10 10:39:19.022 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.view.JstlView : View name 'login', model {}
2020-07-10 10:39:19.043 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.view.JstlView : Forwarding to [/WEB-INF/jsp/login.jsp]
2020-07-10 10:39:19.160 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Completed 404 NOT_FOUND
2020-07-10 10:39:19.163 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : "ERROR" dispatch for GET "/error", parameters={}
2020-07-10 10:39:19.168 DEBUG 11788 --- [nio-8282-exec-1] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped to org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)
2020-07-10 10:39:19.664 DEBUG 11788 --- [nio-8282-exec-1] o.s.w.s.v.ContentNegotiatingViewResolver : Selected 'text/html' given [text/html, text/html;q=0.8]
2020-07-10 10:39:19.684 DEBUG 11788 --- [nio-8282-exec-1] o.s.web.servlet.DispatcherServlet : Exiting from "ERROR" dispatch, status 404
Please help me to find the problem.
First of all you are trying to serve jsp views using jar. It is provided in the spring-boot documentation itself that jsp does not go well with jar packaging. So, change packaging from jar to war . Then , ensure that the jsp files are placed under the WEB-INF like you provided in the application.properties. Most probably your issue is that the jsp was not included in the jar since it was in the WEB-INF folder.
The issue is that when you are using java -*.jar to deploy a springboot application , the jsp files will not be present in the embedded tomcat and while trying to serve the request you will get a 404 PAGE NOT FOUND. This is because of the jar packaging ,that the jsp files are not getting copied from the WEB-INF folder.If you keep the jsp files under the META-INF/resources folder while using jar as packaging it should work.
Related : Why does Spring boot not support jsp while it can render the page if we add proper jar reference
I receive the "HTTP Status 404 – Not Found" even though the Tomcat server seems to have initialized and running in the localhost:8080.
The pom.xml is
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>gs-consuming-rest</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The Controller is
package com.example.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class HelloController {
#RequestMapping("/")
public String hello(){
return "Hello!";
}
}
The Main Application code is
package com.example.demo;
import java.util.Arrays;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
#SpringBootApplication
public class HelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(HelloWorldApplication.class, args);
}
}
The console logs :
2019-08-09 19:53:07.161 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : Starting HelloWorldApplication on DESKTOP-BIMC3QL with PID 13948 (C:\Users\AdharshD\Documents\workspace-sts-3.9.9.RELEASE\HelloWorld\target\classes started by AdharshD in C:\Users\AdharshD\Documents\workspace-sts-3.9.9.RELEASE\HelloWorld)
2019-08-09 19:53:07.164 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : No active profile set, falling back to default profiles: default
2019-08-09 19:53:07.791 INFO 13948 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-08-09 19:53:07.810 INFO 13948 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-08-09 19:53:07.810 INFO 13948 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-08-09 19:53:07.891 INFO 13948 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-08-09 19:53:07.891 INFO 13948 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 679 ms
2019-08-09 19:53:08.076 INFO 13948 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-08-09 19:53:08.079 INFO 13948 --- [ main] com.example.demo.HelloWorldApplication : Started HelloWorldApplication in 1.211 seconds (JVM running for 1.855)
You are missing spring-boot-starter-web artifact. Artifact contains tells spring boot to scan the package (in which main method is present) and all his subpackage for configuration, components and controller. Since this artifact is missing, spring doesn’t register your controller and throws 404-Not found.
I'm wrapping an existing vanilla JAX-RS application JAR with a Spring Boot application using cxf.jaxrs.classes-scan and cxf.jaxrs.classes-scan-packages. When I run as a JAR or with maven spring-boot:run, dependency injection works fine. When I run as a WAR (on WebSphere Liberty 17.0.0.2), the #Inject-able fields are null during REST requests.
Here's the SpringBootApplication:
#SpringBootApplication(scanBasePackages = { "com.test" })
public class CustomerServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(CustomerServiceApplication.class, args);
}
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(CustomerServiceApplication.class);
}
}
Here's src/main/resources/application.properties:
cxf.path=/
cxf.jaxrs.classes-scan=true
cxf.jaxrs.classes-scan-packages=com.test,com.fasterxml.jackson.jaxrs.json
Here's the Maven pom.xml (the vanilla JAX-RS application JAR is customerservice-java which is in the local repository):
<?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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>customerservice-springboot</groupId>
<artifactId>customerservice-springboot</artifactId>
<packaging>war</packaging>
<version>2.0.0-SNAPSHOT</version>
<name>Customer Service :: Spring Boot</name>
<!-- We need to use cxf-spring-boot-starter-jaxrs 3.2.0 because of https://issues.apache.org/jira/browse/CXF-7237
At the time of writing this code, the latest available version in Maven central
is 3.1.7 so we need to use the Apache snapshot repository. -->
<repositories>
<repository>
<id>apache.snapshots</id>
<name>Apache Development Snapshot Repository</name>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-spring-boot-starter-jaxrs</artifactId>
<version>3.2.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>customerservice-java</groupId>
<artifactId>customerservice-java</artifactId>
<version>2.0.0-SNAPSHOT</version>
<classifier>jar</classifier>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Here's the web service in the JAR project:
package com.test;
import javax.inject.Inject;
import javax.ws.rs.CookieParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
#Path("/")
public class CustomerServiceRest {
#Inject
CustomerService customerService;
#GET
#Path("/byid/{custid}")
#Produces("text/plain")
public Response getCustomer(#PathParam("custid") String customerid, #CookieParam("token") String jwtToken) {
return Response.ok(customerService.getCustomerId(customerid)).build();
}
}
Here's the bean:
package com.test;
import javax.inject.Named;
#Named
public class CustomerService {
public String getCustomerById(String username) {
// ... implementation ..
return customerDoc.toJson();
}
}
Here's the WAR logging output:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.4.RELEASE)
INFO c.a.s.CustomerServiceApplication - Starting CustomerServiceApplication on 23fb5f5646c3 with PID 20 (/opt/ibm/wlp/usr/servers/defaultServer/apps/expanded/customerservice-springboot-2.0.0-SNAPSHOT.war/WEB-INF/classes started by root in /opt/ibm/wlp/output/defaultServer)
INFO c.a.s.CustomerServiceApplication - No active profile set, falling back to default profiles: default
INFO o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext - Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#67e7ebcd: startup date [Wed Jul 19 19:36:12 UTC 2017]; root of context hierarchy
INFO o.s.b.f.x.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [META-INF/cxf/cxf.xml]
INFO o.s.b.f.a.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO c.i.w.w.webapp - SRVE0292I: Servlet Message - [customerservice-springboot-2.0.0-SNAPSHOT]:.Initializing Spring embedded WebApplicationContext
INFO o.s.w.c.ContextLoader - Root WebApplicationContext: initialization completed in 3654 ms
INFO o.s.b.w.s.ServletRegistrationBean - Mapping servlet: 'dispatcherServlet' to [/]
INFO o.s.b.w.s.ServletRegistrationBean - Mapping servlet: 'CXFServlet' to [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'errorPageFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'characterEncodingFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'httpPutFormContentFilter' to: [/*]
INFO o.s.b.w.s.FilterRegistrationBean - Mapping filter: 'requestContextFilter' to: [/*]
INFO o.s.w.s.m.m.a.RequestMappingHandlerAdapter - Looking for #ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext#67e7ebcd: startup date [Wed Jul 19 19:36:12 UTC 2017]; root of context hierarchy
INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
INFO o.s.w.s.m.m.a.RequestMappingHandlerMapping - Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO o.s.w.s.h.SimpleUrlHandlerMapping - Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
INFO o.a.c.e.ServerImpl - Setting the server's publish address to be /
INFO o.s.j.e.a.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
INFO c.a.s.CustomerServiceApplication - Started CustomerServiceApplication in 14.955 seconds (JVM running for 271.749)
INFO o.a.c.e.S.e.o.i.l.E.i.w.j.2.0.c.0.17.cl170220170523-1818(id=171)] - Setting the server's publish address to be /
If I enable logging.level.org.springframework.beans.factory.support=TRACE in application.properties, I see the dependency injection working during application startup:
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating shared instance of singleton bean 'customerService'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'customerService'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'customerService' to allow for resolving potential circular references
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'customerService' [...]
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Creating instance of bean 'com.test.CustomerServiceRest'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'customerService'
DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'com.test.CustomerServiceRest'
However, when I make REST requests, I can see that a new instance of CustomerServiceRest is created on each request (System.out.println in the constructor) and the #Inject-able dependencies are null (resuting in a NullPointerException). So I thought maybe adding #Singleton to CustomerServiceRest would work, but a new object is still created on each request.
Does anyone know how to either use a single web service bean or to ensure that Spring injects all the dependencies? The vanilla JAX-RS application JAR can't itself take on any Spring dependencies.
This kind of issue occurred in one of the spring project
However we have used the #Qualifier("name") on the Class declaration and the same qualifier has been used while auto wiring with the #Inject
I was able to solve this by not using Liberty's CXF (e.g. using servlet & jsp features instead of the webProfile feature [which brings in Liberty's jaxrs feature]), and adding exclude = { DispatcherServletAutoConfiguration.class } to the #SpringBootApplication annotation. This is only needed for my type of use case (e.g. microservices) where the DispatcherServlet is mounted as the default servlet on / and the CXFServlet is mounted with cxf.path=/ (thus creating a /* URL mapping). For other cases where Spring MVC is mixed with CXF but the CXF services are at a non-root URL mapping, the exclude is not necessary. I'm still investigating how to get this to work with Liberty's CXF and I'll update this answer if I find out.
I deployed your code on Tomcat 8.5.x with JDK 1.8 and CustomerService was injected successfully.
Do you have any chance to test your war under Tomcat. At least to understand if it is an issue about the code or app server. Sometimes embedded libraries inside WebSphere/Weblogic are overriding jars coming from your war packages and similar problems occur.