Grails 5 application is not finding GSP files in .war, grails run-app is fine - grails

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

Related

How to stop Swagger UI from loading Petstore

I've been updating my company's projects to the latest versions of all the packages. When I try to run swagger (http://localhost:4000/swagger/?url=/swagger/swagger.json), it now redirects me to the Petstore.
After searching Google for an answer, it seems like I need to set the following parameter:
queryConfigEnabled=true
According to the Swagger documentation, I can set the parameter in the following ways:
Swagger UI accepts configuration parameters in four locations.
From lowest to highest precedence:
The swagger-config.yaml in the project root directory, if it exists, is baked into the application
configuration object passed as an argument to Swagger UI (SwaggerUI({ ... }))
configuration document fetched from a specified configUrl
configuration items passed as key/value pairs in the URL query string
I tried the following URL
http://localhost:4000/swagger/?queryConfigEnabled=true&url=http://localhost:4000/swagger/swagger.json
but that still redirected me to the Petstore.
I then tried to create a swagger-config.yaml file in the project root directory with the following contents:
queryConfigEnabled: "true"
url: "/swagger/swagger.json"
dom_id: "#swagger-ui"
validatorUrl: "https://validator.swagger.io/validator"
That didn't work either. I even tried to copy the config file to the project /src folder to see if that made a difference.
I tried other things like using a swagger-config.json file instead, copying the config file to the app root in the docker image, setting the configURL to point to the config file, setting the docker environment CONFIG_URL to point to the swagger config file. None of these solutions worked. I'm still being redirected to the Petstore.
As a last resort, I modified the dist/swagger-initializer.js file and added the queryConfigEnabled parameter.
That worked.
Obviously, if I delete the /node_modules folder and re-run npm install, that change will go away.
What am I doing wrong? How do I fix this?

ASP.NET MVC project with a section written in Angular2: a build error occurs when using MvcBuildViews

Ok it could be a singular combination...
INTRODUCTION
I have an existing ASP.NET MVC 5 project.
It contains a private "Admin" area. I'm planning to change this area migrating it to Angular2 (+ WebAPI) :)
Due to some business requirements, I can't change the architecture of the original "Main" website (separating the Admin section into another website) so I must host inside it the new "Admin" area written in Angular2.
Main website url: http://www.example.com
Admin area url: http://www.example.com/admin
This is also true for the Visual Studio Project:
I created a folder "admin" and put all Angular2 stuff in it.
All works fine...
THE ISSUE
My ASP.NET project uses the MvcBuildViews parameter to build the MVC views on Release mode.
Now when I run the build in Release mode I receive this error:
\node_modules\selenium-webdriver\lib\test\data\web.config(29): error
ASPCONFIG: It is an error to use a section registered as
allowDefinition='MachineToApplication' beyond application level. This
error can be caused by a virtual directory not being configured as an
application in IIS.
The error doesn't have sense for me...
MSBUILD has analyzed a web.config file inside the "node_modules".
The node_modules folder has been created in the project root folder after "npm install" (necessary to prepare angular2's stuff).
These folder should be ignored by msbuild... IMHO
HEY... node_modules IT IS NOT included in the VS project. MSBUILD is scanning the folder because it is only present inside the project...
WORKAROUNDS
Give up the MvcBuildViews... but I think this setting is very useful to detect errors during development phase
Hide the node_modules folder. This is the current workaround I'm using. I've added this pre-build event attrib +h "$(ProjectDir)node_modules"
Some other solution?
I've googled with no success...
I had the same issue recently. I found the solution to this issue in the following article:
Excluding node_modules folder from ASP.NET compilation
The article suggest to replace the AspNetCompiler task in your csproj for a direct call to aspnet_compiler.exe which support excluding folders. In the article, it does so by hardcoding the path to that .exe file. Which for most of the cases is Ok.
You may also use $(FrameworkDir) and $(FrameworkVersion) to avoid hardcoding the path or if you are unsure where the aspnet_compiler.exe may be:
<Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
<Exec Command="$(FrameworkDir)\$(FrameworkVersion)\aspnet_compiler.exe -v temp -p $(WebProjectOutputDir) -x node_modules"/>
</Target>

Grails 2.4 won't read config file from /opt

Please note: Although I'm using the Grails Shiro plugin I believe this to be a core Grails problem, having nothing to do with the plugin whatsoever.
Mac (Yosemtie) and Grails 2.4.5 here. Here's the top 2 lines from my Config.groovy:
String configFileAbsPath = System.getProperty('configFileAbsPath')
grails.config.locations = [ "file:${configFileAbsPath}" ]
So to run locally I do something like:
grails -DconfigFileAbsPath=/Users/myuser/tmp/myapp.properties run-app
When I run this exact invocation, my app starts up and behaves just fine.
However, in non-local environments I want my config file to live under /opt/myapp/myapp.properties. So on my local machine I create a /opt/myapp directory, and then ran chmod -R 777 /opt/myapp. I then copy myapp.properties to it and run:
grails -DconfigFileAbsPath=/opt/myapp/myapp.properties run-app
This produces the following stack trace:
| Error Error generating web.xml file (NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)
groovy.lang.MissingPropertyException: No such property: shiro for class: java.lang.String
at ShiroGrailsPlugin$_closure4_closure30_closure34.doCall(ShiroGrailsPlugin.groovy:248)
at ShiroGrailsPlugin$_closure4_closure30_closure34.doCall(ShiroGrailsPlugin.groovy)
at ShiroGrailsPlugin$_closure4_closure30.doCall(ShiroGrailsPlugin.groovy:243)
at ShiroGrailsPlugin$_closure4_closure30.doCall(ShiroGrailsPlugin.groovy)
at ShiroGrailsPlugin$_closure4.doCall(ShiroGrailsPlugin.groovy:242)
I seriously doubt that the location of an external config file, or the file permissions set on the config file (or its parent dir) would break the Grails Shiro plugin. I think this is just a misleading Grails/Groovy exception. Most likely some kind of security exception is causing something to not load/populate correctly (and fail silently), and then when Grails Shiro kicks in during run-app, its missing something that should be there and is causing run-app to die.
Any ideas as to what is going on, or what the fix is?
Update: Running grails clean, grails clean-all and/or grails refresh-dependencies prior to invoking grails run-app do not help/solve this error either.
I generally prefer to have .groovy file for external config rather than .properties because I can write printlns into it to check whether the file is loaded or not.

Grails. ehcache throws `Cache foo already exist` during startup

Have such ehcache configuration:
<ehcache>
<terracottaConfig url="192.168.1.4:9510"/>
<defaultCache
maxElementsInMemory="50"
eternal="false"
timeToIdleSeconds="20"
timeToLiveSeconds="20"
overflowToDisk="false"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="foo"
maxElementsInMemory="50000"
eternal="true">
<terracotta />
</cache>
</ehcache>
It does not work, application just does not conntects to terracotta server, however during startup it throws such Exception:
net.sf.ehcache.ObjectExistsException: Cache foo already exists.
When I enabled ehcache debug logs, I don't see that my ehcache.xml is loaded somewhere (althrough another ehcache.xml which sits on the classpath inside some jar file is loaded). What could be a problem?
My grails version is 2.1.1, ehcache.xml sits on grails-app/conf directory.
UPDATE 1
One more explanation. cache named foo is used in ehcache.xml and in the code as referece (actually in Apache Camel route as to('cache://foo'). When I rename foo in code to bar (e.g. route now looks like to('cache://bar') it throws the exception that Cache bar already exists. So, exception comes not from ehcache.xml configuration file, but from code referencing that cache by name. Any suggestions would be highly appreciated.
UPDATE 2
Seems the exception is thrown because there are 2 places inside camel routes where cache://foo is referenced. When 2nd reference is reached it throws that exception. So the main question is, why ehcache.xml is not seen by the application on startup? It should warm up and prepare cache://foo for future use.
UPDATE 3
It apparently worked before on grails 1.3.7. And now it does not work on grails 2.1.1
When I run grails with -noreloading option it works well. Must be some classpath issue.

Grails - trying to deploy a nojars application into glassfish 3.0.1

Because of memory constraint i am trying to build a grails app with smaller memory footprint. I build the war with this argument "--nojars". I created a war file without all the jar and when i deploy within the glassfish i encounter this error
Exception while loading the app : java.lang.Exception: java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: java.lang.IllegalArgumentException: java.lang.ClassNotFoundException: org.codehaus.groovy.grails.web.util.Log4jConfigListener
It seems like the application fail to find where is the jar file.
I had already indicates the path to the library before deploying the application in glassfish.
did i miss out somethinng?
It is commonly recommended to use GlassFish's Common Classloader. That means putting the shared JARS into the $domain-dir/lib folder (but not into a subfolder of that).
You're probably trying to use the Application Classloader with the asadmin deploy --libraries command. This is more complicated and error-prone. If you don't need different versions of the same JARs with different web applications, you should definitely go for the Common Classloader as specified above.
Also see The Classloader Hierarchy for a reference.
EDIT Updated as per the questioner's comment:
The domain/domain1/lib folder definitely works (I've tested that). To validate that, put log4j.jar into that folder and add a test.jsp to domain1/applications/$applicationName, that just contains:
<% out.println(
org.apache.log4j.Logger.getLogger(this.getClass())); %>
If that works but your other code does not, there may be another point to consider: Are you using Log4J's Logger.getLogger(..) or Apache Commons' LogFactory.getInstance(..) in your code?
See the article Taxonomy of class loader problems encountered when using Jakarta Commons Logging for related issues. - I'd also like to advise you to post your complete stacktrace.

Resources