not able to open spring default hal browser or any other resource inside jar in tomcat if unpackwar is set to false - spring

Hi I am using spring data rest provided HAL browser to view my spring data rest HAL based api .So far things have been good when I am running it via eclipse or as a spring boot app for testing in my local .Though when I deploy on aws on a tomcat container (as a spring boot war) I get this weird error as below when I browse to the roor or the address of the hal browser /browser/index.html#
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Aug 24 07:05:46 UTC 2015
There was an unexpected error (type=Internal Server Error, status=500).
Jar URL cannot be resolved to absolute file path because it does not reside in the file system: war:jar:file:/deployment/wars/hfds.1.3.war!/WEB-INF/lib/spring-data-rest-hal-browser-2.4.0.BUILD-SNAPSHOT.jar
I am still not able to find a valid justification on why its not being able to find the provided hal browser though things work fine in local .Am I missing something can someone please help .Is this a bug with spring framework or otherwise
UPDATE
This seems to be an environment specific issue as in windows environmnet I get the url file:/.... whil ein linux I get war:jar:file which causes the issue due to this code section in org.springframework.util.ResourceUtils
public static File getFile(URL resourceUrl, String description) throws FileNotFoundException {
Assert.notNull(resourceUrl, "Resource URL must not be null");
if (!URL_PROTOCOL_FILE.equals(resourceUrl.getProtocol())) {
throw new FileNotFoundException(
description + " cannot be resolved to absolute file path " +
"because it does not reside in the file system: " + resourceUrl);
}
try {
return new File(toURI(resourceUrl).getSchemeSpecificPart());
}
catch (URISyntaxException ex) {
// Fallback for URLs that are not valid URIs (should hardly ever happen).
return new File(resourceUrl.getFile());
}
}

Hi so with the help of Andy finally figured out that the workaround is to set unpackwar to true to make the HAL browser work .Not sure this is a mandate yet so have raised an issue for spring boot at https://github.com/spring-projects/spring-boot/issues/3826 to look further .But as of now setting upackwar=true works just fine .
UPDATE
This has been fixed in the 4.2.2 and greater spring version via https://jira.spring.io/browse/SPR-13393

Related

Spring boot, tomcat, rest api 404

I am using Kotlin + Gradle and trying to build a war file to deploy on Tomcat. My application is from the https://start.spring.io plus a simple controller and build the war file using ./gradlew bootWar
#SpringBootApplication
class ServletInitializer : SpringBootServletInitializer() {
override fun configure(application: SpringApplicationBuilder): SpringApplicationBuilder {
return application.sources(DemoApplication::class.java)
}
}
#RestController
class TomcatController {
#GetMapping("/hello")
fun sayHello(): Collection<String> {
return IntStream.range(0, 10)
.mapToObj { i: Int -> "Hello number $i" }
.collect(Collectors.toList())
}
}
when I try to access it I get
Type Status Report
Message The requested resource [/demo-0.0.1-SNAPSHOT/hello] is not available
Description The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.
I am super stuck. What am I doing wrong? If I add a html file to the src/main/webapp/index.html it shows up for some reason only the rest api can't be reached.
Spring Boot applications come with a built in Servlet. You are probably already using this feature when launching the application inside your IDE.
This basically means that you can just run your .jar file on any web server and it will be ready to go without setting up an extra tomcat instance.
However, if you want to build a Spring Boot application as a war file and deploy it to an external tomcat, you need to follow some extra steps as explained in this article.
Assuming from what you posted so far: the path that is returned shows another route before your actual controller route "/demo-0.0.1-SNAPSHOT/hello" is this "/demo-0.0.1-SNAPSHOT" the path that your application runs on ? If not it should be included in your controller (assuming you havent set it elsewhere for e.g. in your application.properties).
for e.g. http://localhost:8080/ would be the basepath and either http://localhost:8080/demo-0.0.1-SNAPSHOT/hello or http://localhost:8080/hello would point to your controller. Also your startup logs (for Tomcat and Spring) might give away more about the issue.

Spring boot server using jetty is not forwarding to index.html by default when running in eclipse since spring-boot-starter-parent 2.1.12-RELEASE

UPDATE:
This problem exists in jetty from 9.4.25.v20191220, i have set the version back to 9.4.24 it correctly serves. Whether this is a bug or change of configuration I don't know.
Maybe someone can help, i appreciate this is all configuration issues but I've only had this issue having upgrade spring-boot-starter-parent to 2.1.13-RELEASE from 2.1.10-RELEASE.
Using #SpringBootApplication and everything else default, except with the following WebMvcConfigurer (found in another post here)
#Configuration
public class WebApplicationConfiguration implements WebMvcConfigurer
{
#Override
public void addViewControllers(ViewControllerRegistry registry)
{
registry
.addViewController("/{spring:\\w+}")
.setViewName("forward:/");
registry
.addViewController("/**/{spring:\\w+}")
.setViewName("forward:/");
registry
.addViewController("/{spring:\\w+}/**{spring:?!(\\.js|\\.css|\\.svg)$}")
.setViewName("forward:/");
}
}
Using Jetty, and with an angular project present at \src\resources\public\ including a index.html in the public directory.
In the previous spring version I could navigate to localhost:8080 and it would direct automatically to localhost:8080/list this is setup up as the redirect within the angular project index file.
But now using 2.1.13 i have to explicitly go to localhost:8080/index.html which does work, redirects to /list and i can navigate the website, but if i refresh the page or if i went explicitly to :8080/list i get whitelabel error 500
I've tried:
1.
Adding various other view controller rules:
registry.addViewController("/").setViewName("forward:/index.html");
registry.addViewController("/").setViewName("forward:index.html");
registry.addViewController("/**").setViewName("forward:index.html");
... But I don't think these are the problem anyway.
2.
Viewed ResourceHandlerRegistry to see the default resource locations, so it should pick up my index.html file.
3.
Adding spring.resources.static-locations=classpath:/public/xxx/**
I then get by going to localhost:8080/xxx/ or localhost:8080/xxx/index.html whitelabel 404
I upgraded spring due to security vulnerabilities, so currently tempted to go back to 2.1.10 or 11, and pull only the dependency versions required to mitigate vulnerabilities. I'd just like to understand what is going wrong, and obviously don't enjoy being defeated.
Does anyone know if there is changelogs for versions of spring that would shed any light to what has changed? I guess it could be due to any number of dependent projects though.
So it turns out that whatever the issue was it is fixed in jetty 9.4.27.v20200227.
Spring Boot releases from 2.1.10 contained new Jetty version for each release, with now release currently using 9.4.27.
Using spring boot 2.1.13-RELEASE with 9.4.27.v20200227, returns forwarding to what is expected with localhost:8080 loading /list

WebSocket cannot connect to endpoint when running Spring-Boot 2.2 with lazy bean initialization?

I'm having trouble getting the client to connect to a WebSocket endpoint when the Spring-Boot 2.2 application is started in lazy-init mode.
I was able to get this Spring.io tutorial to work. It uses spring-boot-starter-parent version 2.1.6. I changed the pom.xml to use spring-boot-starter-parent version 2.2.0 and got it to work also.
But when I set spring.main.lazy-initialization=true in application.properties, the client does not connect to the server via WebSocket anymore when I click on the "Connect" button. In Chrome Developer Tool > Network > WebSocket, I see that the client sends a CONNECT request, but it never receives a "CONNECTED" response.
I've uploaded my project file to GitHub here:
https://github.com/hirokiterashima/spring-boot-stomp-messaging-websocket. The first commit is the 'complete' directory of the original project in the Spring.io tutorial, which uses Spring-Boot 2.1.6: https://github.com/spring-guides/gs-messaging-stomp-websocket/tree/master/complete. The second commit contains my changes to pom.xml to use Spring-Boot 2.2.0 and addition of application.properties file to enable lazy initialization. As you can see, all I did in the second commit was change to Spring Boot 2.2.0, updated the jQuery webjars dependency, and enabled lazy initialization. If you comment-out the spring.main.lazy-initialization line in application.properties, it will work.
Did anybody else come across a similar issue? What can I do to make this work?
Thanks for your help!
just register the following #Bean:
#Bean
public LazyInitializationExcludeFilter stompWebSocketHandlerMappingLazyInitializationExcludeFilter() {
return LazyInitializationExcludeFilter.forBeanTypes(HandlerMapping.class);
}
or
#Bean
public LazyInitializationExcludeFilter stompWebSocketHandlerMappingLazyInitializationExcludeFilter() {
return ((beanName, beanDefinition, beanType) -> beanName.equals("stompWebSocketHandlerMapping"));
}

automatic configuration of Spring Social’s ConnectController not working

I have followed the steps given in the below site to create a simple spring boot application that access the facebook data using maven and spring boot.
http://spring.io/guides/gs/accessing-facebook/
which is also same as http://www.technicalkeeda.com/spring/spring-social-facebook-integration-example but in gradle.
The problem i am facing is when i am trying to run the application, I have am seeing that url is successfully redirected to "/connect/facebook" but it doesnt load the facebookConnect.html instead it throws error
as shown below:
"
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Tue Mar 10 19:24:41 IST 2015
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'GET' not supported
"
I have also tried using the same code given in the site and also used my facebook appId and appSecret in it , which i had generated by giving a random host name in the facebook app, still i get same error.
I have also tried adding the random host name which i created to the /etc/hosts file in the windows.
Could anyone please help me why i am not able to see the .html page that has to be rendered by the ConnectController automatically ?
I finally got the answer.
it is we need to additional parameter in the application.properties file which is
"spring.social.auto_connection_views=true
along with the id and secret.
spring.social.facebook.appId=
spring.social.facebook.appSecret=
this property was not mentioned in the tutorials. finally this worked. :)
"
Had the exact same issue. spring.social.auto-connection-views: true in the application.yml (or .parameter equivalent) does indeed solve it, but then the default facebookConnect.html and facebookConnected.html are being used.
I solved it by removing the above application parameter and simply adding Thymeleaf tempting engine to the pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
And then you can use your own facebookConnect.html and facebookConnected.html located at src/main/resources/templates/connect/
Hope it can help.

Force Spring to always report exceptions as JSON

How do I force Spring to always convert uncaught exception to JSON instead of HTML page?
This is what I get when request is made from Chrome's REST client plugin:
{
timestamp: 1425041457798
status: 404
error: "Not Found"
exception: "com.some.my.Exception"
message: "/rrr does not exist"
path: "/test/rrr"
}
But this is what I get when I access it from browser or from Jersey API (you see parsed HTML):
Whitelabel Error PageThis application has no explicit mapping for /error, so you are seeing this as a fallback.Fri Feb 27 13:37:27 CET 2015There was an unexpected error (type=Not Found, status=404).No message available
I know this can be done somehow by setting the request headers but I want JSON response to be the only variant.
First we need add some exception resolver for exception that trows inside controllers. I prefer extend ResponseEntityExceptionHandler and add own method, but there is a great article on spring.io: http://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc
After that if you still get following page you can override org.springframework.boot.autoconfigure.web.ErrorController. There are an example: BasicErrorController. But this works only if you use spring boot application with embedded container. For example, if you will create war file form spring boot project and will deploy under tomcat, you will get standard tomcat error page.
So this mean that ErrorController is not common solution.
In my case i throws exceptions inside filters, that why /error page shown. So solution will be write own filter that converts exceptions to JSON representation. This solution should work for every container/server, and you can get more information about exception.

Resources