I created a grails plugin in which some domain classes, controllers and views were added. After creating the plugin, I imported it in a grails application by using "grails.plugin.location.'...' = '.....'" in BuildConfig.groovy.
Everything is okay when the application starts up. And, everything is nice when online modifying the view GSPs in the plugin.
But, when I modified any controller in the plugin, the grails cannot find the view files corresponding to the modified controller in the plugin. Tomcat reported "HTTP Status 404" error. And, everything becomes okay again after restarting grails.
I am using Grails 1.3.3 and Groovy 1.7.2.
After googling, I found it was an unresolved bug. Please refer to the following URL:
http://jira.codehaus.org/browse/GRAILS-5869
In the bug page, there is a workaround reported. You can add annotation for the controller class of your plugin to make everything okay. Following is an example:
import org.codehaus.groovy.grails.plugins.metadata.GrailsPlugin
#GrailsPlugin(name='...', version='...')
class ... {
....
}
Related
In my custom Grails plugin, how can I set up a JSON view for a non-domain class and get client apps to use it by default?
I have a view file in the plugin:
/views/com/mycompany/myplugin/myclass/_myClass.gson
When I do grails install, I can see that this .gson file is in the generated JAR. However, the client app is not using it.
What can I do to make it work?
Are there any settings or steps that can make troubleshooting easier?
I am using Grails 3.2.4.
Update:
When I copy the view into a client app, using the exact same path, the view is getting invoked. It's only when the view is defined in the plugin that the view cannot be found.
The framework seems to be trying to look up the plugin as a class from the classloader:
myclientproject_com_mycompany_myplugin_myclass__myClass_gson
How do I get my plugin to add this class to the classpath?
For my use case, what I actually needed was a custom converter.
See:
In JSON views, how do I flatten an object out as a single string?
This obviated the need for my plugin to publish a view.
I have a fairly complicated grails plugin dependency structure within my project and I am having problems overriding classes from the security plugin.
My structure is a little something like this:
Web App
|_ Audit Plugin
|_ Spring Security Core Plugin
|_ Security Wrapper Plugin
|_ Audit Plugin
|_ Spring Security Core Plugin
The reason it is like this is audit is shared between some apps which have the security wrapper, and some what don't, which is why it pulls in Security-Core (it needs at least the ability to get the current principal).
Similarly the wrapper is shared between multiple web apps therefore we put it in a plugin. My problem comes after upgrading Spring-Security-Core to version 2.
My wrapper has a customer auth.gsp and LoginController.groovy. In the older version of security this was fine, as the plugin templated those and made them available in the source of the installing plugin.
However now these files are internal to the plugin, and although I know you can override them within the main app, when trying to override them within another plugin I get some bizarre results.
The Spring-Security-Core version of the login page always overrides my custom login page. I cannot get mine to take precedence.
The second problem is that the LoginController.groovy from the Spring-Security-Core plugin sometimes takes precedence over my one from the wrapper. It seems almost random between builds as to which one will be in use.
Is there any correct way to go about making sure my views and controllers take precedence?
OK playing around with things I found a solution that seems to work for me:
Firstly I couldn't change the order in which the plugins load because the security wrapper does a lot with spring beans and it has to load after the core plugin for this to work. So after a bit of digging in the (DefaultSecurityConfig.groovy) I noticed that you can set the following properties:
grails.plugin.springsecurity.failureHandler.defaultFailureUrl = '/login/authfail? login_error=1'
grails.plugin.springsecurity.failureHandler.ajaxAuthFailUrl = '/login/authfail?ajax=true'
grails.plugin.springsecurity.auth.loginFormUrl = '/login/auth'
So I created a custom controller and login page which have a different name to the ones use in the core plugin and changed these properties to point to my locations.
To neaten this up, in the UrlMappings for the wrapper (named: SecWrapperUrlMappings) I put a mapping from /login/** to /seclogin/**.
Make sure that these new locations aren't locked down so that people can access them and that seems to work well. I now reliable know, whichever order they load in my login page and login controller are used.
In Grails-4.013 and spring-security-core-4.0.4, I did the following trick.
In my custom plugin instead of LoginController and LogoutController I named them as SigninController and SignoutController respectively. And in UrlMappings.groovy of App mapped them like..
static mappings = {
"/login/$action?"(controller: "signin")
"/logout/$action?"(controller: "signout")
....
....
}
Can anyone confirm that the webflow plugin is working in 2.0.0M1? I've installed the plugin but my "*Flow" actions don't seem to be treated differently then my other actions. I've additionally tried rebuilding grails-core from GitHib (2.0.0.BUILD-SNAPSHOT) and the behavior is the same.
Here's the action in question:
def baselineFlow() {
showQuestion {
on("checkout").to "enterPersonalDetails"
on("continueShopping").to "displayCatalogue"
}
}
When I go to controllerName/baseline it acts as if baseline.gsp isn't there (404 on controllerName/baseline) as opposed to trying to resolve baseline/showQuestion.gsp I do have a controllerName/baseline/showQuestion.gsp in place in views. The same action works in 1.3.7.
This looks like a bug. I suggest you create an issue in the Grails bug tracker. Attach your application to the issue and provide instructions for reproducing the error. In my experience, the Grails team are very good at resolving reported bugs. If you do it now, it should be fixed for the final release of 2.0.0
I have a plugin with domain, controller and view pages. (Using grails 1.3.6)
I run the plugin as standalone, the views work fine. URL: http://localhost:8080/sample-plugin/gp/list. I am able to view the list page.
I installed the plugin into a main application i.e. plugin-test. Start as run-app within STS and browse to http://localhost:8080/plugin-test/gp/list. I am able to view the list page.
I bundle the application as war i.e. plugin-test.war and deploy to tomcat. When I browse to http://localhost:8181/plugin-test/gp/list I get a 404 error! I am not sure what I am doing wrong.
I have been trying to resolve it for quite sometime now and still no luck. The same main application works fine in STS but not in tomcat.
HTTP Status 404 - /plugin-test/WEB-INF/grails-app/views/gp/list.jsp
type Status report
message /plugin-test/WEB-INF/grails-app/views/gp/list.jsp
description The requested resource (/plugin-test/WEB-INF/grails-app/views/gp/list.jsp) is not available.
Please help.
Thank you.
Jay Chandran.
This sounds worryingly familiar, as I spent a while figuring out this (or a very similar) issue. I ended up raising this Grails bug report:
Plugin layout not found in war when installed from BuildConfig.groovy
Have you installed the plugin as using the new BuidConfig dependency technique? The JIRA documents my workaround.
Sharing some of my lessons learned after experiencing the same exact issue (1.3.7):
Double check your HTML source to make sure that your template really isn't being included. Mine was being included, but my CSS/image URLs were wrong (only while running as a war)...so I wrongly assumed that my template wasn't there.
Don't use the ui performance tags for referencing your static content...doesn't appear to work, even if the plugin attribute is specified.
Don't name your layout main.gsp. You're guaranteed to have conflicts.
Don't use absolute=true on your g:resource tags. This doesn't appear to append the pluginContextPath to the absolute url, even if you specify dir="${pluginContextPath}"
Don't use pluginContextPath, as it's no longer required: http://grails.org/doc/latest/guide/single.html#6.3%20Tag%20Libraries (search "Plugin Paths")
In your g:resource tags in your plugin layout, make sure you specify the plugin attribute. Set it to the name of your plugin.
Move your static images/css from your plugin to a web server. If each application using your plugin has its own copy, your users aren't going to benefit from caching when bouncing between apps.
Note that all of the above applies to the layout gsp in your plugin project, not your consuming application.
Wonder if anyone has come accross this problem. I have created a demo portlet using the grails portlet and liferay plugins.
After installing the grails plugins in a project i simply ran the following commands
grails create-portlet MyFirst
grails generate-portlet-views MyFirst
grails liferay-deploy
The portlet deploys fine. However when i try to add the portlet to a page then i get the following stacktrace. Anyone have any ideas ?
23:04:52,134 ERROR [jsp:165] javax.servlet.ServletException: File "/WEB-INF/grails-app/views/myfirst/render.jsp" not found
I am running liferay version 5.2.3 that has tomcat version 6.0.18 embedded. I am also using JVM 1.6
thanks in advance.
The current versjon of the Grails portlet plugin (0.7) doesn't support portletnames with capital cases. Change MyFirst to myfirst and it will work like a charm (well, almost ;)
Regards
Armaz
It looks like it's not able to find render.gsp (the default gsp for a porltet if no mode specific view is found).
What did generate-portlet-views generate for you?
Take a closer look to your stacktrace - it attempts to look for render.jsp, not gsp. render.jsp is the default template LR attempts to find if it does not find what it is looking for depending on the action.
Read Armaz's answer, he is correct. You must change template folder name to lower case: myFirst => myfirst.
The next problem you might experience is solved here: Grails Liferay portlet not invoking action ;)