- References
- Sample Setup in grails-app/conf/Config.goovy file
This sample setup is modified based on the document(http://d.hatena.ne.jp/nobeans/20090323/1237826907, this documentation is written in Japanese).// log4 setup
log4j = {
appenders {
//override the setuf of the default console out
console(name:'stdout', layout:pattern(conversionPattern: '%d{HH:mm:ss} [%p] (%c{2}) %m%n'))
//override the setup of the default log
rollingFile(name:'file', file:'logs/debug.log', maxFileSize:'10MB', maxBackupIndex:5, layout:pattern(conversionPattern: '%d{HH:mm:ss} [%p] (%c{2}) %m%n'))
//override the setup of the default error stack
rollingFile(name:'stacktrace', file:'logs/stacktrace.log', maxFileSize:'10MB', maxBackupIndex:5, layout:pattern(conversionPattern: '%d{yyyy-MM-dd HH:mm:ss} [%p] (%c{2}) %m%n'))
//daily rolling log
appender new org.apache.log4j.DailyRollingFileAppender(name:'dailyRollingFile', datePattern:"'.'yyyy-MM-dd",layout:pattern(conversionPattern: '%d{HH:mm:ss} [%p] (%c{2}) %m%n'), file:'logs/daily.log');
}
root {
error 'stdout', 'file'
additivity = false
}
//controller
error 'org.codehaus.groovy.grails.web.servlet'
//gsp
error 'org.codehaus.groovy.grails.web.pages'
//layouts
error 'org.codehaus.groovy.grails.web.sitemesh'
//url mapping filter
error 'org.codehaus.groovy.grails."web.mapping.filter'
//url mapping
error 'org.codehaus.groovy.grails."web.mapping'
//core, classloader
error 'org.codehaus.groovy.grails.commons'
//plugins
error 'org.codehaus.groovy.grails.plugins'
//hibernate integration
error 'org.codehaus.groovy.grails.orm.hibernate'
error 'org.springframework'
//info 'org.springframework.security'
//hibernate
error 'org.hibernate'
//jetty
warn 'org.mortbay.log'
//error stack
error(
additivity:false
//,stdout:"StackTrace"
,stacktrace:"StackTrace"
)
//debug for my my app
//info dailyRollingFile:"grails.app.controller.TestController"
info(
additivity:false
//,stdout:"grails.app.controller"
,dailyRollingFile:"grails.app.controller"
)
info(
additivity:false
,dailyRollingFile:"grails.app.service"
)
info(
additivity:true
,dailyRollingFile:"grails.app.task"
)
}
2009年4月24日金曜日
[Grails]Grails1.1 Setup fo the Apache Log4j Logging
Sample Setup fo the Apache Log4j Logging on Grails 1.1, A new Log4j DSL is available on Grails 1.1.
2009年4月17日金曜日
[Grails]Grails Upgrade Steps from 1.0.x to 1.1
Grails Upgrade Steps from 1.0.x to 1.1
- References
- Upgrade Steps
- Backup all application files
- Add following statements into the grails-app/conf/Config.groovy file
//upgrade
grails.views.enable.jsessionid=false
//grails.project.plugins.dir="./plugins" - Create a file grails-app/conf/BuildConfig.groovy file if this file doesn't exist and add following statements into this file.
//upgrade
//grails.views.enable.jsessionid=false
grails.project.plugins.dir="./plugins" - if you use some plugins, you need to re-install plugins.
Remove all plugins files and cleanup files stored under plugins directorymv plugins/* /tmp/
- Run the upgrade command as follows
(After running this commands, grails will create a new plugin named hibernate-1.1 under the plugins directory automatically. we don't need to re-install this hibernate-1.1 plugin.)grails upgrade
- re-install plugins by using "grails install-plugins" command
(for example)
grails install-plugin /tmp/grails-quartz-0.3.1.zip
- TroubleShooting
- Plugins TroubleShooting
- quartz-0.3.1 plugin
- Error Description
After starting the grails application, following error appears while starting up the quartz plugin - Error Stack
2009-04-14 16:12:39,907 [main] ERROR context.ContextLoader - Context initialization failed
org.springframework.beans.factory.access.BootstrapException: Error executing bootstraps; nested exception is org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingPropertyException: No such property: startDelay for class: QuartzGrailsPlugin
at org.codehaus.groovy.grails.web.context.GrailsContextLoader.createWebApplicationContext(GrailsContextLoader.java:74)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:199)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:45) - Cause
This error raises from following statements of the configureJobBeans closure in the QuartzGrailsPlugin.groovy file because of the "this" clause.// registering triggers
jobClass.triggers.each {name, trigger ->
"${name}Trigger"(trigger.clazz) {
jobDetail = ref("${fullName}JobDetail")
trigger.properties.findAll {it.key != 'clazz'}.each {
this["${it.key}"] = it.value /* here */
}
}
} - Resolution
I changed this clause from "this" to "delegate", quartz plugin works fine.
- Error Description
- quartz-0.3.1 plugin
2009年4月7日火曜日
[grails]upgraded the plugin for grails to execute native query
I created and upgraded the grails plugin named native-query(Version 0.2) to execute native query statement like ORACLE's query hint, mysql match-against statement on the grails framework.
Installation Steps
Installation Steps
- download zip file named grails-native-query-0.2.zip via http://groups.google.com/group/taapps-sourcecode-libraries/web/grails-native-query-0.2.zip
- installing plugin into the grails application
grails install-plugin grails-native-query-0.2.zip
- use DomainObject.executeJdbcQuery method injected into the Domain Class
- Description
This executeJdbcQuery method is static method injected into the Domain Class object. - Return Value
This method returns the List object and each objects stored into the List are Domain Objects of the fetched rows. - Arguments
- Required String type, where, order by, match against clauses(No need to enter the "select * from " statement)
- Optional String type, select option like the "SQL_CALC_FOUND_ROWS(mysql)" or hint text(ORACLE)
- List object or Map object stored the bind values
- Required String type, where, order by, match against clauses(No need to enter the "select * from " statement)
- Example
Following examples are using the Domain Class named "Test", this is a test domain class.- use the standard select statement
def result=Test.executeJdbcQueryMap("where id=160") - use positonal parameter
def result=Test.executeJdbcQueryMap("where id=?",[160]) - use named map parameter
def result=Test.executeJdbcQueryMap("where id=:id",[id:160]) - use the positonal parameter wit
def result=Test.executeJdbcQueryMap("where id=?","SQL_CALC_FOUND_ROWS",[160]) - use the List object as the member of the positional parameters
def result=Test.executeJdbcQueryMap("where id in (?)","SQL_CALC_FOUND_ROWS",[[160,161,162,163,164]])
- use the standard select statement
- Description
- use NativeQueryUtil.executeJdbcQueryMap method to execute free sql statement(not need to be related to the Domain Class)
- Return Value
This method returns the List object and each objects stored into the List are Map object stored the fetched column name and the value, map key is column name - Arguments
- String type, Select statement
- List object or Map object stored the bind values
- String type, Select statement
- Example
- use the standard select statement
def result=NativeQueryUtil.executeJdbcQueryMap("select * from test where id=103") - use positional map
def result=NativeQueryUtil.executeJdbcQueryMap("select * from test where id=?",[103]) - use namedmap parameter
def result=NativeQueryUtil.executeJdbcQueryMap("select * from test where id=:id",[id:103]) - use the List object as the member of the positional parameters
def result=NativeQueryUtil.executeJdbcQueryMap("select * from test where id in (?)",[[103.104,105,106]])
- use the standard select statement
- Return Value
- use the NativeQueryUtil.executeNativeQuery method(execute sql statement via Hibernate's createQuery method)
- Description
This method executes the select statement via Hibernate's session.createQuery method. - Return Value
Domain Object or List object stored the domain objects of the fetched rows. - Arguments
- String Type, select statement
- Map type, mapping the table name and domain class
- List object or Map object stored the bind values
- Example
- def result=NativeQueryUtil.executeNativeQuery("select /* query */ tbl.* from test tbl where id=?",[tbl:Test],[101])
- def result=NativeQueryUtil.executeNativeQuery("select /* query */ tbl.* from test tbl where id=?",[tbl:Test],[101])
- Description
2009年4月4日土曜日
[Grails]Upgraded Split Write Database Connection Plugin for master/slave configuration(Alpha version 0.3)
Upgraded the Grails Split Write Database Connection Plugin for master-slave configuration (Alpha version 0.3, like the magic multi connection for rails framework, multiple datasource)
I fixed some bugs and added new methods, changed the source code as follows.
Version 0.3
http://groups.google.com/group/taapps-sourcecode-libraries/web/grails-split-write-db-0.3.zip
I fixed some bugs and added new methods, changed the source code as follows.
Version 0.3
- change the flush mode for the base session to avoid saving the changed domain class automatically into the base database. The flush mode for the base session is changed to the manual.
- add new methods named discardXXX, attachXXX, refreshXXX for the save session.
- added new CustomSavePersistentMethod and use this class when saving
- added new method validateAndDiscard and discardAll which sync between the base session and save session.
http://groups.google.com/group/taapps-sourcecode-libraries/web/grails-split-write-db-0.3.zip
2009年3月19日木曜日
[Grails]How to get the database table and column names mapped to the Domain Class
How to get the database table and column names mapped to the Domain Class
- References
- Grails FAQ "Q: How can I flush a Hibernate session multiple times within my controller?"
http://grails.org/FAQ - http://www.mail-archive.com/hibernate-devel@lists.sourceforge.net/msg06401.html
- Grails FAQ "Q: How can I flush a Hibernate session multiple times within my controller?"
- Description
the way to get the database table name and column names mapped to the domain classes
in grails application.
The example using in controller class is as follows. Following sample is using the controller class named TestController and domain class named SampleDomainClass.//import 3 classes
import org.hibernate.SessionFactory
import org.codehaus.groovy.grails.commons.DefaultGrailsApplication
import org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass
class TestController {
.....
//variables to handle the Hibernate sessonFactory and grails application
//please refer to the grails FAQ page if you know more details to get sessonFactory and grailsApplication objects
def sessionFactory
def grailsApplication
//starting the action closure named "index"
def index={
.....
//get the class object named the SampleDomainClass domain class
def domainClass=grailsApplication.getClassForName("SampleDomainClass")
//get hibernage meta data object
def hibernateMetaClass=sessionFactory.getClassMetadata(domainClass)
//get the table name mapped to the SampleDomainClass domain class
def tableName=hibernateMetaClass.getTableName()
println("table name=$tableName")
//creaate a new GrailsDomainClass object for the SampleDomainClass
def grailsDomainClass=new DefaultGrailsDomainClass(domainClass)
//get the domain properties which keeps the domain class properties defined in Domain Class
//grailsDomainClass.getProperties() is returned the GrailsDomainClassProperty[] objects
//please refer to the javadoc
//http://www.grails.org/doc/1.0.x/api/index.html?org/codehaus/groovy/grails/commons/DefaultGrailsDomainClass.html
def domainProps=grailsDomainClass.getProperties()
domainProps.each{prop->
//get the property's name
def propName=prop.getName()
//get the database column name mapped to the domain property name
//getPropertyColumnNames is returned the String array object
//please refer to the hibernate javadoc
//http://www.hibernate.org/hib_docs/v3/api/org/hibernate/persister/entity/AbstractEntityPersister.html
def columnProps=hibernateMetaClass.getPropertyColumnNames(propName)
if(columnProps && columnProps.length>0){
//get the column name, which is stored into the first array
def columnName=columnProps[0]
println("prop=$propName, columnName=$columnName")
}
}
.....
}
}
2009年2月7日土曜日
[Grails]can't override the methods(like save(), find()...) defined in domain class
References
- Grails Documentation
http://grails.org/doc/1.0.x/
- Can't override the standard methods (like the save(), find(), delete()..) and dynamic finders defined in domain class. For example, I define the original save() method into the domain class and start the grails jetty, System ignores my original save() method and overrides the save() method.
- According to the doWithDynamicMethods() method defined in HibernateGrailsPlugin.groovy file, the Clusure named "lazyInit" is defined, and this closure is called from the methodMissing methods.
When calling the methodMissing methods, System tries to initialize the domain class and inject various dynamic methods into the domain class.
When System initializes the Domain Class and calls the dynamic method at the first time,
Groovy calls the methodMissing method if System can't find the method definition in the domain class. And then, System injects and overrides the pre-defined and duplicated methods.
Please refer to the org.codehaus.groovy.grails.plugins.orm.hibernate.HibernateGrailsPlugin in source code.
- Change the method name like save()==>saveXXX(), we have to avoid to duplicate the method name(or change and override the methodMissing method definition?).
2009年2月6日金曜日
[Grails]NullPointerException sometimes occurs after upgrading the grails to the version 1.0.4
References
- bug information
http://jira.codehaus.org/browse/GRAILS-3493 - Content Negotiation
http://www.ibm.com/developerworks/java/library/j-grails09168/?S_TACT=105AGX90&S_CMP=EDU
- Following exception sometimes occurs after upgrading the grails to the version 1.0.4.
After starting up the grails jetty server, following exception occurs when accessing the application url. This exception occurs before executing the controller's beforeInterceptor() and any action method, this error is outputted by the grails HttpHeader parser program.java.lang.NullPointerException: Cannot invoke method toBigDecimal() on null object
at org.codehaus.groovy.runtime.NullObject.invokeMethod(NullObject.java:77)
at org.codehaus.groovy.runtime.InvokerHelper.invokePogoMethod(InvokerHelper.java:784)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:758)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:170)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethod0(ScriptBytecodeAdapter.java:198)
at org.codehaus.groovy.grails.web.mime.QualityComparator.compare(DefaultAcceptHeaderParser.groovy:122)
at java.util.Arrays.mergeSort(Arrays.java:1284)
at java.util.Arrays.sort(Arrays.java:1223)
at java.util.Collections.sort(Collections.java:159)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.sort(DefaultGroovyMethods.java:3509)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod.invoke(ReflectionMetaMethod.java:51)
at org.codehaus.groovy.runtime.metaclass.NewInstanceMetaMethod.invoke(NewInstanceMetaMethod.java:54)
.......
- This problem is caused by the Http Content Negotiation logic and the values of http headers. If the user accesses the url, the browser is sending the http headers and values of the client information as follows
(This output is sample http headers)accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Grails reads these http headers before executing the controller action, and DefaultAcceptHeaderParser program parses the http headers sent from the client. When the value of "accept" or "content type" http header is including the value "application/xhtml+xml" or "application/xml", Grails parses these http headers and tries to find the "q" parameter into the "accept" or "content-type" header.
accept-language: en-us,en;q=0.5
accept-encoding: gzip,deflate
accept-charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
keep-alive: 300
connection: keep-alive
While parsing the headers, the NullPointerException occurs because some client program doesn't have the "q" parameter value into the http header even though the accept header includes the value "application/xhtml+xml" or "application/xml".
- According to the http://jira.codehaus.org/browse/GRAILS-3493, this problem is fixed in grails 1.1.beta1. I tried to the grails 1.1.beta3, this problem is fixed.(but other error occurs.)
登録:
投稿 (Atom)