Is grailsApplication is predefined - grails

I have a sample code where they used def grailsAppication like
class ViewSourceController {
def grailsApplication
def controllerClass = grailsApplication.getArtefactByLogicalPropertyName(
"Controller", controllerName)
}
is grailsApplication is predefined one, will it search in application's directory for required files, I want to know about its usage

grailsApplication is a Spring bean of type GrailsApplication that is created by the framework. According to the docs, GrailsApplication is:
the main interface representing a running Grails application. This interface's main purpose is to provide a mechanism for analysing the conventions within a Grails application as well as providing metadata and information about the execution environment.
Refer to the docs for more information about the methods provided by GrailsApplication.

GrailsApplication is an interface of grails and This interface's main purpose is to provide a mechanism for analysing the conventions within a Grails application as well as providing metadata and information about the execution environment.
The GrailsApplication interface interacts with ArtefactHandler instances which are capable of analysing different artefact types (controllers, domain classes etc.) and introspecting the artefact conventions
Implementors of this inteface should be aware that a GrailsApplication here is only initialised when the initialise() method is called. In other words GrailsApplication instances are lazily initialised by the Grails runtime.

Related

How to enable Serilog minimum level overrides without particular convention of calling ForContext?

This article on Serilog minimum level overrides states:
The first argument of Override is a source context prefix, which is normally matched against the namespace-qualified type name of the class associated with the logger.
For this so-called "normal" behavior, wouldn't I need to manually set the .ForContext<>() differently for each class my logger is called from? In other words, how are namespace-specific minimum log levels supposed to work without a specific convention of how .ForContext is set?
If that makes sense, then how can I set ForContext automatically without calling it with a different argument everywhere?
For this so-called "normal" behavior, wouldn't I need to manually set
the .ForContext<>() differently for each class my logger is called
from?
Yes, you would. A common way of doing it is by using the Log.ForContext<T>() on each class, in a member variable that gets shared across the different methods of your class (so that all logs get written with the same context). e.g.
public class SomeService
{
private readonly ILogger _log = Log.ForContext<SomeService>();
// ...
}
public class SomeRepository
{
private readonly ILogger _log = Log.ForContext<SomeRepository>();
// ...
}
If you are using an IoC container such as Autofac, you can have the .ForContext<>() call happen automatically when classes are resolved by the IoC container (by using constructor injection, for example).
If you are using Autofac specifically, you could use AutofacSerilogIntegration that takes care of that. There might be similar implementations for other IoC containers (or you'd have to implement your own).
If you are using Microsoft's Generic Host, then you'll need to configure it to use a custom ServiceProviderFactory which will be responsible for creating the instances and making the call to .ForContext<>()... An easy route is to integrate Autofac with Microsoft's Generic Host and then leverage the AutofacSerilogIntegration I mentioned above.

Injecting grails-app classes in Grails

Please note: Although my specific question at hand involves the Grails Shiro plugin, I believe this to be a core Grails question at heart. And so any battle weary Grails veteran should be able to answer this, regardless of their experience with Grails Shiro.
Using the Grails Shiro plugin (via grails shiro-quick-start) produces a Shiro realm class under grails-app/realms. For instance, running:
grails shiro-quick-start --prefix=com.example.me.myapp.Mongo
...will produce:
myapp/
grails-app/
realms/
com/
me/
myapp/
MongoDbRealm.groovy
Where MongoDbRealm is the Shiro realm.
package com.example.me.myapp
class MongoDbRealm {
FizzClient fizzClient // How to inject?
BuzzClient buzzClient // How to inject?
FooFactory fooFactory // How to inject?
// lots of auth-centric, generated code here...
}
Let's pretend that MongoDbRealm is very complicated and needs to be injected with lots of complicated objects such as service clients and factories, etc. How do I properly inject MongoDbRealm?
Will #PostConstruct work here? Can I inject Grails services into it like I do with controllers? Something else?
Again, I would imagine that dependency injection works the same here (with Grails Shiro and my MongoDbRealm) as in any other class defined under grails-app. I just don't understand how grails-app/* dependency injection works.
Plugins that support defining classes under grails-app typically do so by defining a new type of artifact, and specify an ArtefactHandler implementation to manage that. The Grails ArtefactHandlerAdapter class implements that interface and provides a lot of common functionality, so that's often used, and is used in the plugin's RealmArtefactHandler class.
Dependency injection would be configured in the newInstance method. You can see where I did this for one of my plugins here. Since the Shiro plugin doesn't override that method from the base class, it looks like dependency injection isn't supported.
Note that using #PostConstruct (or implementing InitializingBean) would work if the realm classes were registered as Spring beans, but it doesn't look like that's the case in this plugin.
I try to avoid using the Holders class since in most cases it's straightforward to use DI instead of pulling in dependencies explicitly, but it looks like you will need to use that approach here, e.g. fizzClient = Holders.applicationContext.fizzClient (assuming that is registered as the "fizzClient" bean).

adding loggers to Grails classes

I use the following approach to access a logger instance from classes in a Grails app:
In Grails artefacts (controllers, services, domain classes, etc.) I simply use the logger that is added by Grails, e.g.
class MyController {
def someAction() {
log.debug "something"
}
}
For classes under src/groovy I annotate them with #groovy.util.logging.Slf4j, e.g.
#Slf4j
class Foo {
Foo() {
log.debug "log it"
}
}
The logger seems to behave properly in both cases, but it slightly bothers me that the class of the loggers differs. When I use the annotation, the class of the logger is org.slf4j.impl.GrailsLog4jLoggerAdapter, but when I use the logger that's automatically added to Grails artefacts the class is org.apache.commons.logging.impl.SLF4JLog.
Is there a recommended (or better) approach to adding loggers to Grails classes?
I don't see any problem with what you described. SLF4J isn't a logging framework, it's a logging framework wrapper. But aside from some Grails-specific hooks in the Grails class, they both implement the same interface and delegate eventually to the same loggers/appenders/etc. in the real implementation library, typically Log4j.
What I'm pretty sure is different though is the log category/name, because you need to configure the underlying library based on what the logger names become. With annotations the logger name is the same as the full class name an package. With the one Grails adds, there's an extra prefix based on the artifact type. I always forget the naming convention but a quick way to know the logger name is to log it; add this in your class where it will be accessed at runtime:
println log.name
and it will print the full logger name (using println instead of a log method avoids potential misconfiguration issues that could keep the message from being logged
I like to keep things simple and consistent and know that being used, so I skip the wrapper libraries and use Log4j directly. Access the logger is easy. Import the class
import org.apache.log4j.Logger
and then add this as a class field:
Logger log = Logger.getLogger(getClass().name)
This can be copy/pasted to other classes since there's no hard-coded names. It won't work in static scope, so for that I'd add
static Logger LOG = Logger.getLogger(this.name)
which also avoids hard-coding by using Groovy's support for "this" in static scope to refer to the class.
Have you tried the #Log4j (for log4j) instead.
#Log4j (for log4j)
How can i use 'log' inside a src/groovy/ class

Change AccessDecisionManager to UnanimousBased in Grails Spring Security Plugin

We're using the Grails spring security plugin:
http://grails.org/plugin/spring-security-core
I simply want to change the default access decision manager from the default AffirmativeBased to UnanimousBased. I do not see it documented anywhere in the plugin manual:
http://grails-plugins.github.io/grails-spring-security-core/docs/manual/
Does anyone know if it's possible to change this?
I added one additional voter, "myVoter" which is detected and working fine.
grails.plugins.springsecurity.voterNames = [
'myVoter', 'authenticatedVoter', 'roleVoter',
]
Based on Burt Beckwith's "Hacking the Grails Spring Security Plugin" [http://www.slideshare.net/gr8conf/hacking-the-grails-spring-security-plugins], it should be possible to simply provide a different implementation of the accessDecisionManager bean. Something like this:
accessDecisionManager(org.springframework.security.access.vote.UnanimousBased)
in resources.groovy
When I tried this, I had trouble with the constructor syntax in the bean definition. The access decision manager wants a list of voters in the constructor and I couldn't quote figure out how to get my voters defined in config.groovy as parameters to the constructor. I was about to derive my own decision manager (with parameterless constructor) from UnanimousBased when I stumbled upon the source code for AuthenticatedVetoableDecisionManager in the Grails Spring Security Plugin. This class splits the voters in half... anything deriving from AuthenticatedVoter will immediately fail if any are denied (e.g. AUTHENTICATED_FULLY family), but all other voters will pass if any are granted (e.g. RoleVoter). I wanted the AuthenticatedVoter functionality for my custom voter so I simply derived from AuthenticatedVoter (making sure to override all of the interface methods so I didn't accidentally get any base class functionality) and stuck with the default decision manager.

Using CDI to inject a Data Access Object

Assuming I have a data access object that I've already written, I'd like to be able to use CDI to inject that into say, a service class. Furthermore, I have two implementations of that DAO.
My understanding of CDI is that I'd have to annotate my DAO implementation class so that CDI would know which implementation to inject.
The problem is, the DAO is in a .jar file. By annotating it with CDI annotations, I'm using JavaEE imports in a non-JavaEE class.
For example, let's say I have the following class
public class BusinessService {
#Inject #SomeMybatisQualifier AccountDAO accountDao;
...
}
The #Inject annotation comes from javax.inject.Inject. Now, this service class is dependent on a JavaEE environment.
Can someone please explain to me what I'm missing? How do I inject a non-annotated class into another non-annotated class? This is fairly simple with Spring.
I agree with LightGuard if there's enough classes. But for a couple, why not just produce them with #Produces?
Here's a decent example of implementing your own producer:
Depedency inject request parameter with CDI and JSF2
You should be able to write return new MyObject(); and you can add whatever qualifiers you want
Not sure what's unclear but here's the gist of things: For CDI to scan a jar for beans it must have a beans.xml. Else it will not be scanned and thus not available for injects.A String is not available either. If you try to inject a String say;
#Inject
String myString;
CDI will have no clue what to give you just like your jar. But I know what String I want (a requestparam) and I can let CDI know as well. How? Well I supply a qualifier #RequestParam to my producer (see example again) and now when I want to use it in client code I do it like this:
#Inject
#RequestParam
String myString;
You can do the same thing. Have a producer and just create a new instance of whatever you need and then return it. Now CDI will know just how to dependency inject that particular bean.
Now say you have 40 classes. Then it gets messy to produce them and you want to make sure it gets scanned instead. Then you write your own little extension, observe when CDI is about to scan and instruct it to scan additional jars. Such extension is probably easy to write but I don't know the details because I have not written any extensions like it
By far, the easiest thing would be to create a CDI extension to add the classes in the jar (because there's no beans.xml in that jar so it won't be picked up by CDI) and add additional qualifiers to the metadata.

Resources