1

I have an application that runs perfectly using grails run-app but fails when I try to run is using the embedded server. I use the following commands to build and run the .war.

./gradlew assemble
java -Dgrails.env=dev -jar build/libs/rideshare-services-3.0.war

Below is the error and the steps I've taken to try to determine what the issue is.

The browser shows 500 error page, and the log shows the following:

Servlet.service() for servlet [grailsDispatcherServlet] in context with path [] threw exception [Could not resolve view with name '/index' in servlet with name 'grailsDispatcherServlet'] with root cause
javax.servlet.ServletException: Could not resolve view with name '/index' in servlet with name 'grailsDispatcherServlet'
    at org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1384)
    at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1149)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1088)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
<snip>

However, spring security is enabled, and it renders its form fine with this path:

/login/auth

So I started poking around and assets can be accessed, for example:

/assets/advancedgrails.svg

Also, the built-in actuator paths all work fine:

/actuator/*

I found this question grails and debugging UrlMappings which seemed like it could help.

To test if the URL mapping were working I added a /test route in UrlMappings.groovy, mapped to a controller named 'member' and the 'index' action. I also added the logging as suggested:

<logger name="org.grails.web.mapping" level="ALL"/>

It resolved to the correct controller and action, but still failed to load the page, so I added a log statement to the action, and the controller definitely runs, but the view fails to load.

At which point, with the debug statement in the controller, I could confirm that even without the /test URL mapping, the controller fires if I use the standard controller/action URI /member/index. That confirmed that the configuration in UrlMapping.groovy was working.

So, thinking the .gsp files failed to be compiled, I searched and found this:
Grails 3 application works locally, but unable to resolve view when deployed to a remote Tomcat

But I already had the plugins suggested in the answer in my build, so I figured maybe they weren't be added to the .war so I unziped it.

The .war has the gsp files as well as a mapping file WEB-INF/classes/views.properties which included a mapping for the view that corresponds to the controller/action I was using to test (among all of the other mappings in the file):

/WEB-INF/grails-app/views/member/index.gsp=gsp_rideshare_services_memberindex_gsp

I then confirmed the referenced gsp_rideshare_services_memberindex_gsp files exist, and the do with the following being present WEB-INF/classes:

gsp_rideshare_services_memberindex_gsp_html.data
gsp_rideshare_services_memberindex_gsp_linenumbers.data
gsp_rideshare_services_memberindex_gsp.class
gsp_rideshare_services_memberindex_gsp$_run_closure1.class
gsp_rideshare_services_memberindex_gsp$_run_closure1$_closure3.class
gsp_rideshare_services_memberindex_gsp$_run_closure1$_closure3$_closure4.class
gsp_rideshare_services_memberindex_gsp$_run_closure2.class
gsp_rideshare_services_memberindex_gsp$_run_closure2$_closure5.class
gsp_rideshare_services_memberindex_gsp$_run_closure2$_closure6.class
gsp_rideshare_services_memberindex_gsp$_run_closure2$_closure7.class

The compiled .gsp files for all of my views seem to be here, and the source .gsp files are also in WEB-INF/classes, in the same folder structure as the project's grails-app/views directory.

So at this point I'm at a loss to understand why my views (gsp files) are not being found, although built-in views and plugin views are fine.

I will reiterate that the app runs perfectly well when run using 'grails run-app'.

1 Answers1

0

Maybe it is late but it might help someone along the way. Your application is failing in one environment and not on the other because the context-path is different obviously. Although this would not be the issue itself, this is just the reason for the behaviour to be different. An index action does not have a respective gsp and you are also not handling returning/redirecting from that action to account for the fact that you don't have a groovy server page to land to. The verbatim exception message says it all: Could not resolve view with name 'index' in servlet with name 'grailsDispatcherServlet']. If my assumptions are correct there should be two reasons for this, you're either redirecting to a controller that with action '/index' that doesn't exist, or you don't have a gsp to correspond with an index action that the client lands on for any reason. If my assumptions are correct the solution is easy, Search for where '/index' is being referenced and analyze if you are using a wrong controller + action combination.

MKOCH
  • 45
  • 1
  • 5
  • Thanks for your answer. I am quite sure you are correct in that Grails can's find the gsp that corresponds to the action. But I don't know why. The gsp files are there, and in the standard location (views). Everything is named correctly. – Scott McIntosh Feb 23 '23 at 15:32
  • Also the core issue, which may have gotten buried in all the explanation, is that it works fine using the 'grails run-app' command, and it works fine when I build and deploy a war file to a Tomcat server (which I discovered after creating this question). So clearly the path to my gsp files is being set incorrectly when running embedded. – Scott McIntosh Feb 23 '23 at 15:41
  • 1
    SOLVED: Your comment about the environment got me thinking, and actually there was a difference. In 'dev' the app was set to use a different port (8090) as there was a conflict on my local machine. For whatever reason this caused the built-in views to be found, but my views weren't. So, because you caused me to look at that again, I'm accepting the answer. – Scott McIntosh Feb 23 '23 at 16:22
  • This sounds like a bug. How did you define the port in your config? – Samuel Steward Feb 23 '23 at 16:25
  • I have an app running on an alternate port and don't have any problem, but I use the command line option. – Samuel Steward Feb 23 '23 at 16:29
  • I define it in application.yml in the development environment. server: port: 8090 – Scott McIntosh Feb 23 '23 at 16:31
  • Using the command line to define the port has that same issues. I used: 'java -Dgrails.env=dev -Dserver.port=8090 -jar build/libs/rideshare-services-3.0.war' – Scott McIntosh Feb 23 '23 at 16:39
  • 1
    If anyone is interested, it seems using the dev environment when running the application in the embedded server is broken. Running in test or prod works fine: 'java -Dgrails.env=prod -Dserver.port=8090 -jar build/libs/rideshare-services-3.0.wa – Scott McIntosh Feb 23 '23 at 17:47
  • 1
    I have confirmed this with a newly create app. It is even broken with the default port, if dev is used for the environment. – Samuel Steward Feb 23 '23 at 17:49
  • @SamuelSteward that is true for me as well. Thanks for sharing. – MKOCH Feb 23 '23 at 18:04