GrailsApplication src/classes - grails

According to Grails API, we can retrieve all domain classes definition through GrailsApplication as such
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
AH.application.domainClasses
I have classes defined under src/groovy and would like to do the same. I tried using the follwing code but in vain
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
AH.application.allClasses
According to Grails API, call to getAllClasses should return all classes loaded by Grails class loader
Class[] getAllClasses()
Retrieves all java.lang.Class instances loaded by the Grails class loader
Am i missing something

Any Java or Groovy code can be placed in the src directory and does not have to integrate with Grails. The Grails class loader only loads Grails specific classes such as pluggins, controllers, and domain classes that your grails application knows about at run-time. In order to find out about classes located in your src directory you will need to know the package name your interested in and then iterate through everything contained in that package.

.
Well the classes under 'src' are not registered with grails classLoader. But you can use the "in context class loader" to get those classes easily using one single line of code (Java Style though)
Class fetchedClass = Class.forName(
"Class Full Name Here",
true,
Thread.currentThread().getContextClassLoader()
)
.
.
Thats It .. :) All Done!! Easily.
.
.
Example to get the class "com.myPackage.dto.AddressDTO"
We will Do:
EXAMPLE: get class "com.myPackage.dto.AddressDTO"
Class fetchedClass = Class.forName(
"com.myPackage.dto.AddressDTO",
true,
Thread.currentThread().getContextClassLoader()
)

Related

Grails run-command ask for application class argument

I'm using grails 3.2.9 version. And trying to create custom command. I need a command because I need to have access to spring beans. So the code is simply like this:
class MyTestCommand implements GrailsApplicationCommand {
boolean handle() {
def bean = applicationContext.getBean('myBean')
bean.doSomething()
return true
}
When I run it as
grails run-command my-test
I'm getting an error: "Missing application class name and script name arguments"
I'am able to add application class as last param and everything seems works, but the question is, why I should add it? Does grails doesn't know about its Main Application class? I did some research about and there is no answers, in each examples i se only command name without Application class. But as I understand from this source we should pass main class always. Am I missed something?

grails 2.5+ Duplicate class definition error when implementing serializable on a controller

Upgrading a legacy system of grails. One of the controllers implements Serializable. This is throwing the following error in newer versions of grails:
Invalid duplicate class definition of class com.regional.ScheduleController :
The source contains at least two definitions of the class.
One of the classes is an explicit generated class using the class statement,
the other is a class generated from the script body based on the file name.
Solutions are to change the file name or to change the class name.
The solution mentioned would break (previous) grails convention. Anyone know how to handle this in grails 2.5+?
EDIT
Serializable is not the issue. I tried removing it and got the same error.
I found this explanation from another question:
IN groovy.. class B{} is a class structure and defines a class B.
Scripts are classes too.
Now you may create a B.groovy, with the content "class B{}; def b = new B()".
There would be one class named B, and a script with the very same name.
This is a conflict.
However this does not explain why it runs fine below grails 2.5 and not above it. And I can't find a def conflict like the one mentioned above in that controller.
ANSWER:
One of the imports was what was actually failing- in a way that caused groovy to generate a class definition based on the current file name. When it hit the class definition, there was already an auto generated class name to collide with.

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

Groovy File Name and Class Name different

I am developing application using grails which uses groovy.I changed one of the domain class name say class A to class B.However this does not change the file name unlike the case with Java.Why is it so.My guess would be the A.groovy file is treated as groovy script and class name is a Java class?Please clarify..thanks
If you rename a class, you need to need to rename the source file in which that class is defined. If you are using an IDE's refactoring support, the IDE should do that for you. Regardless, the file name should be changed either by you or by your tools.

How to create/use shared domain properties/methods in Grails 2?

before Grails 2.x we used an abstract class to model shared domain properties. This worked perfect but now when using Grails 2.x is see no way of creating shared domain properties and methods. When i use an abstract class and let my domain classes extend that abstract class i get one big database table.
Is there a alternative way of creating shared domain properties / methods?
Docs says that you need to move your base class into the /src/groovy at this case

Resources