Grails 3 db migrations - grails

Just upgraded from grails 2.3.11 to 3.2.0.M2
Have a problem with dbm-gorm-diff and other dbm-* scripts
My app has multiproject structure. Domain classes placed in separate plugin.
Build.gradle
buildscript {
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "org.grails.plugins:hibernate5:6.0.0.M2"
classpath "org.grails.plugins:database-migration:2.0.0.RC4"
}
}
version "0.1"
group "core"
apply plugin:"eclipse"
apply plugin:"idea"
apply plugin:"org.grails.grails-plugin"
apply plugin:"org.grails.grails-plugin-publish"
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencyManagement {
imports {
mavenBom "org.grails:grails-bom:$grailsVersion"
}
applyMavenExclusions false
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.grails:grails-dependencies"
compile "org.grails.plugins:hibernate5"
compile "org.grails.plugins:cache"
compile "org.hibernate:hibernate-core:5.1.0.Final"
compile "org.hibernate:hibernate-ehcache:5.1.0.Final"
console "org.grails:grails-console"
profile "org.grails.profiles:plugin:3.2.0.M2"
provided "org.grails:grails-plugin-services"
provided "org.grails:grails-plugin-domain-class"
provided 'javax.servlet:javax.servlet-api:3.1.0'
runtime "org.grails.plugins:database-migration:2.0.0.RC4"
runtime "mysql:mysql-connector-java:5.1.39"
testCompile "org.grails:grails-plugin-testing"
}
grailsPublish {
// TODO: Provide values here
user = 'user'
key = 'key'
githubSlug = 'app/core'
license {
name = 'Apache-2.0'
}
title = "Core"
desc = "***"
developers = ["***"]
portalUser = ""
portalPassword = ""
}
sourceSets {
main {
resources {
srcDir "grails-app/migrations"
}
}
}
application.yml
grails:
profile: plugin
codegen:
defaultPackage: core
spring:
transactionManagement:
proxies: false
info:
app:
name: '#info.app.name#'
version: '#info.app.version#'
grailsVersion: '#info.app.grailsVersion#'
spring:
groovy:
template:
check-template-location: false
---
grails:
plugin:
databasemigration:
updateOnStart: true
updateOnStartFileNames:
- changelog.groovy
- changelog-part-2.groovy
hibernate:
cache:
queries: false
use_second_level_cache: true
use_query_cache: false
region.factory_class: 'org.hibernate.cache.ehcache.EhCacheRegionFactory'
dataSource:
dbCreate: none
driverClassName: "com.mysql.jdbc.Driver"
dialect: "org.hibernate.dialect.MySQL5InnoDBDialect"
url: "jdbc:mysql://localhost:3306/project?zeroDateTimeBehavior=convertToNull&autoreconnect=true&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8"
username: "root"
password: "root"
properties:
jmxEnabled: true
initialSize: 5
maxActive: 50
minIdle: 5
maxIdle: 25
maxWait: 10000
maxAge: 600000
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1
validationQueryTimeout: 3
validationInterval: 15000
testOnBorrow: true
testWhileIdle: true
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
Stacktrace
2016-08-16 18:57:06.731 WARN 5736 --- [ main] o.s.mock.web.MockServletContext : Couldn't determine real path of resource class path resource [src/main/webapp/WEB-INF/sitemesh.xml]
java.io.FileNotFoundException: class path resource [src/main/webapp/WEB-INF/sitemesh.xml] cannot be resolved to URL because it does not exist
at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:187) ~[spring-core-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.core.io.AbstractFileResolvingResource.getFile(AbstractFileResolvingResource.java:48) ~[spring-core-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.mock.web.MockServletContext.getRealPath(MockServletContext.java:458) ~[spring-test-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.grails.web.sitemesh.Grails5535Factory.<init>(Grails5535Factory.java:78) [grails-web-sitemesh-3.2.0.M2.jar:3.2.0.M2]
at org.grails.web.servlet.view.SitemeshLayoutViewResolver.loadSitemeshConfig(SitemeshLayoutViewResolver.java:105) [grails-web-gsp-3.2.0.M2.jar:3.2.0.M2]
at org.grails.web.servlet.view.SitemeshLayoutViewResolver.init(SitemeshLayoutViewResolver.java:67) [grails-web-gsp-3.2.0.M2.jar:3.2.0.M2]
at org.grails.web.servlet.view.SitemeshLayoutViewResolver.onApplicationEvent(SitemeshLayoutViewResolver.java:146) [grails-web-gsp-3.2.0.M2.jar:3.2.0.M2]
at org.grails.web.servlet.view.SitemeshLayoutViewResolver.onApplicationEvent(SitemeshLayoutViewResolver.java:42) [grails-web-gsp-3.2.0.M2.jar:3.2.0.M2]
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:166) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:382) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:336) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:877) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:544) [spring-context-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-1.4.0.RC1.jar:1.4.0.RC1]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:369) [spring-boot-1.4.0.RC1.jar:1.4.0.RC1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:313) [spring-boot-1.4.0.RC1.jar:1.4.0.RC1]
at grails.boot.GrailsApp.run(GrailsApp.groovy:55) [grails-core-3.2.0.M2.jar:3.2.0.M2]
at grails.ui.command.GrailsApplicationContextCommandRunner.run(GrailsApplicationContextCommandRunner.groovy:55) [grails-console-3.2.0.M2.jar:3.2.0.M2]
at grails.ui.command.GrailsApplicationContextCommandRunner.main(GrailsApplicationContextCommandRunner.groovy:102) [grails-console-3.2.0.M2.jar:3.2.0.M2]
2016-08-16 18:57:07.035 INFO 5736 --- [ main] .c.GrailsApplicationContextCommandRunner : Started GrailsApplicationContextCommandRunner in 21.719 seconds (JVM running for 23.484)
2016-08-16 18:57:07.035 INFO 5736 --- [ main] grails.boot.GrailsApp : Application starting in environment: development
Command execution error: Bean named 'sessionFactory' must be of type [org.springframework.beans.factory.FactoryBean], but was actually of type [org.hibernate.internal.SessionFactoryImpl]
2016-08-16 18:57:07.185 INFO 5736 --- [ Thread-7] g.u.s.DevelopmentWebApplicationContext : Closing grails.ui.support.DevelopmentWebApplicationContext#2abc224d: startup date [Tue Aug 16 18:56:48 MSK 2016]; root of context hierarchy
2016-08-16 18:57:07.382 INFO 5736 --- [ Thread-7] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase -2147483648
2016-08-16 18:57:07.406 INFO 5736 --- [ Thread-7] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
Can you help me?

Already found it. This is known issue - https://github.com/grails-plugins/grails-database-migration/issues/81

Discussed here: Grails 3 schemaExport contains warning with FileNotFoundException that looks for sitemesh.xml
You can ignore it. Still a problem in Grails 4.

Related

java.io.FileNotFoundException: class path resource [/data/nroot/client_key.p12] cannot be opened because it does not exist

I have updated the Spring-rabbit version from 1.7 to 2.2.8 to support SSL connection. the below exception is throwing when i mentioned external paths to key store & trust store i.e., outside the jar file.
2:40:53,853 |-ERROR in com.axon.log.dropwizard.AxonAMQPAppender[rabbitmq] - Failed to create customized Rabbit ConnectionFactory. org.springframework.amqp.AmqpIOException: java.io.FileNotFoundException: class path resource [/data/nroot/client_key.p12] cannot be opened because it does not exist
at org.springframework.amqp.AmqpIOException: java.io.FileNotFoundException: class path resource [/data/nroot/client_key.p12] cannot be opened because it does not exist
at at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:70)
at at org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean.setUpSSL(RabbitConnectionFactoryBean.java:743)
at at org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean.createInstance(RabbitConnectionFactoryBean.java:706)
at at org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean.createInstance(RabbitConnectionFactoryBean.java:80)
at at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:142)
at at org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean.afterPropertiesSet(RabbitConnectionFactoryBean.java:691)
at at org.springframework.amqp.rabbit.logback.AmqpAppender.createRabbitConnectionFactory(AmqpAppender.java:710)
at at org.springframework.amqp.rabbit.logback.AmqpAppender.start(AmqpAppender.java:675)
at at com.axon.log.dropwizard.AmqpAppenderFactory.build(AmqpAppenderFactory.java:373)
at at io.dropwizard.logging.DefaultLoggingFactory.configure(DefaultLoggingFactory.java:143)
at at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:83)
at at io.dropwizard.cli.Cli.run(Cli.java:78)
at at io.dropwizard.Application.run(Application.java:93)
at at com.infa.products.axon.bulkupload.BulkUploadApplication.main(BulkUploadApplication.java:62)
Caused by: java.io.FileNotFoundException: class path resource [/data/nroot/client_key.p12] cannot be opened because it does not exist
at at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180)
at at org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean.configureKeyManagers(RabbitConnectionFactoryBean.java:776)
at at org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean.setUpSSL(RabbitConnectionFactoryBean.java:725)
at ... 12 common frames omitted
12:40:53,853 |-INFO in ch.qos.logback.classic.AsyncAppender[async-rabbitmq] - Attaching appender named [rabbitmq] to AsyncAppender.
12:40:53,853 |-INFO in ch.qos.logback.classic.AsyncAppender[async-rabbitmq] - Setting discardingThreshold to 51
i have updated only spring-rabbit to 2.2.8.RELEASE. i have tried to update dependencies to latest, but ran into couple of other issues. then i have updated only spring-rabbit version to support SSL connection.
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.25'
compile 'com.google.code.gson:gson:2.8.1'
compile group: 'io.dropwizard', name: 'dropwizard-logging', version: '1.1.0'
compile group: 'net.logstash.logback', name: 'logstash-logback-encoder', version: '4.11'
compile group: 'ch.qos.logback.contrib', name: 'logback-json-classic', version: '0.1.2'
compile group: 'ch.qos.logback.contrib', name: 'logback-jackson', version: '0.1.5'
compile group: 'org.springframework.amqp', name: 'spring-rabbit', version: '2.2.8.RELEASE'
compile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.0.1'
compile group: 'io.jsonwebtoken', name: 'jjwt', version: '0.8.0'
compile group: 'org.bitbucket.b_c', name: 'jose4j', version: '0.5.5'
}
YML config entry:
- type: rabbitmq
host: localhost
port: 5671
username: guest
password: =AXON:CIPHER:AES:128=CrYVHt53/OWVCgAXXrrZ2ufouJwnIdKQzF9VQlSR7NaDE1XpEGPyCznCL57Gpx+RKhrIKR+ytURDzrPv7qw8Rw==
exchange: axon_log_java
routingKey: log_routing_key
appName: Unison
enabled: true
secure: true
tlsVersion: TLSv1.2
keyStorePassword: MySecretPassword
trustStorePassword: MySecretPassword
clientKeyPath: /data/nroot/client_key.p12
trustStorePath: /data/nroot/rabbitstore
keyStoreType: PKCS12
trustStoreType: JKS
verifyHostname: false
==========
Yml properties setting to AMQPAppender:
#JsonTypeName("rabbitmq")
public class AmqpAppenderFactory extends AbstractAppenderFactory {
........
..............
...........
#Override
public Appender build(LoggerContext context, String applicationName, LayoutFactory layoutFactory, LevelFilterFactory levelFilterFactory, AsyncAppenderFactory asyncAppenderFactory) {
JsonLayout layout = new JsonLayout();
layout.setJsonFormatter(new JacksonJsonFormatter());
layout.setAppendLineSeparator(true);
layout.setTimestampFormatTimezoneId("UTC");
layout.setIncludeContextName(includeContextName);
//LayoutWrappingEncoder<ILoggingEvent> layoutEncoder = new LayoutWrappingEncoder<>();
//layoutEncoder.setLayout(layout);
final AxonAMQPAppender amqpAppender= new AxonAMQPAppender();
amqpAppender.setName(appenderName);
amqpAppender.setContext(context);
amqpAppender.setLayout(layout);
amqpAppender.setDeclareExchange(isDeclareExchange());
amqpAppender.setVirtualHost(getVHost());
amqpAppender.setHost(getHost());
amqpAppender.setContentType("application/json");
amqpAppender.setDurable(isDurable());
amqpAppender.setGenerateId(isGenerateId());
amqpAppender.setExchangeType(getExchangeType());
amqpAppender.setMaxSenderRetries(getMaxRetry());
amqpAppender.setPassword(getPassword());
amqpAppender.setUsername(getUsername());
amqpAppender.setPort(getPort());
amqpAppender.setRoutingKeyPattern(getRoutingKey());
amqpAppender.setExchangeName(getExchange());
amqpAppender.setApplicationId(getAppName());
amqpAppender.addFilter(levelFilterFactory.build(threshold));
**amqpAppender.setUseSsl(isSecure());
amqpAppender.setSslAlgorithm(getTlsVersion());
amqpAppender.setKeyStore(getClientKeyPath());
amqpAppender.setKeyStorePassphrase(getKeyStorePassword());
amqpAppender.setKeyStoreType(getKeyStoreType());
amqpAppender.setTrustStore(getTrustStorePath());
amqpAppender.setTrustStorePassphrase(getTrustStorePassword());
amqpAppender.setTrustStoreType(getTrustStoreType());
amqpAppender.setVerifyHostname(isVerifyHostname());**
String command = System.getProperty("centralized.logging");
if(false == getEnabled() || "false".equals(command)){
NullAppender nullAppender = new NullAppender();
nullAppender.setContext(context);
return wrapAsync(nullAppender,asyncAppenderFactory);
}
**amqpAppender.start();**
return wrapAsync(amqpAppender,asyncAppenderFactory);
}
}
AMQPAppender class:
public class AxonAMQPAppender extends AmqpAppender {
public static String APP_ID = "";
public static String SOURCE = "";
#Override
public Message postProcessMessageBeforeSend(Message message, Event event)
{
String body = new String(message.getBody());
//some line of code
return message;
}
}
I have resolved my issue.
By default its look for classpath or if we specify classpath: i.e., ClasspathResourceLoader
for external file paths need to specify file: i.e., its usesFileUrlResourceLoader

How to configure quartz plugin in grails 3?

Recently I tried configuring my grails app for use with quartz scheduler. Unfortunately I failed configuring JDBC job store. The quartz plugin seems to ignore quartz.properties file, where table prefix is defined as Z_STAFF_SCHEDULER. Application startup fails with exception:
Caused by: org.springframework.scheduling.SchedulingException: Could
not start Quartz Scheduler; nested exception is
org.quartz.SchedulerConfigException: Failure occured during job
recovery. [See nested exception:
org.quartz.impl.jdbcjobstore.LockException: Failure obtaining db row
lock: Table 'testing.qrtz_locks' doesn't exist [See nested exception:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table
'testing.qrtz_locks' doesn't exist]]
Here is the relevant code in application.groovy:
quartz {
autoStartup = true
jdbcStore = true
waitForJobsToCompleteOnShutdown = true
exposeSchedulerInRepository = false
props {
scheduler.skipUpdateCheck = true
}
}
environments {
test {
quartz {
jdbcStore = false
autoStartup = false
}
}
}
grails.config.locations = ["classpath:conf/quartz.properties"]
and this is my config in quartz.properties:
#============================================================================
# Configure Main Scheduler Properties
#============================================================================
org.quartz.scheduler.instanceName = StaffScheduler
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 25
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = false
org.quartz.jobStore.dataSource = development
org.quartz.jobStore.tablePrefix = Z_STAFF_SCHEDULER_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 20000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.development.driver = com.mysql.jdbc.Driver
org.quartz.dataSource.development.URL = jdbc:mysql://localhost:3306/testing?useSSL=false
org.quartz.dataSource.development.user = testing
org.quartz.dataSource.development.password = nopass
org.quartz.dataSource.development.maxConnections = 10
org.quartz.dataSource.development.validationQuery = select 1
Anyone out there who can help me please?
I'm using grails 3.2.3 and quartz plugin 2.0.9
I finally found the solution myself. Every option for the quartz plugin can be configured in application.yml itself. See http://www.quartz-scheduler.org/documentation/quartz-2.2.x/configuration/ for a list of supported parameters.
You do not need any further files. Here's an extract from my application.yml as an example:
quartz:
autoStartup: true
jdbcStore: true
scheduler:
instanceName: 'staff_scheduler'
instanceId: 'AUTO'
threadPool:
class: 'org.quartz.simpl.SimpleThreadPool'
threadCount: 25
threadPriority: 5
jobStore:
misfireThreshold: 60000
class: 'org.quartz.impl.jdbcjobstore.JobStoreTX'
driverDelegateClass: 'org.quartz.impl.jdbcjobstore.StdJDBCDelegate'
useProperties: false
dataSource: 'development'
tablePrefix: 'Z_STAFF_SCHEDULER_'
isClustered: true
clusterCheckinInterval: 20000
dataSource:
development:
driver: 'com.mysql.jdbc.Driver'
URL: 'jdbc:mysql://localhost:3306/testing?useSSL=false'
user: 'testing'
password: 'nopass'
maxConnections: 28
validationQuery: 'select 1'

Debug statements aren't showing src/groovy classes

I have the following in my config.groovy
// default for all environments
log4j = { root ->
appenders {
rollingFile name:'stacktrace', file:"${logDirectory}/app_stack.log".toString(), maxFileSize:'100KB'
}
error 'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework', 'org.hibernate'
debug 'com.my.code'
root.level = org.apache.log4j.Level.INFO
}
I get debug statements printed to the logs for all classes except for my groovy files placed in package com.my.code I don't get the debug statements printed. Only the info statements are being printed to the log.
Here is an example for one of the groovy classes in src/groovy
#Log4j
class SomeTest {
def someMethod() {
log.info("This will print")
log.debug("This will not print")
println log.isDebugEnabled() //prints false
print log.isInfoEnabled() //prints true
}
}
Question
How can I turn on debugging for all class under package com.my.code ? I'm on grails 2.3.5. When I change root.level to org.apache.log4j.Level.DEBUG then the debug statements do show up but that turns on DEBUG for ALL other classes as well
Here's a configuration that will log all code in packages com.my.code at the DEBUG level, and all other packages at the ERROR level.
The logs will be sent to the console and a file named appLog.txt.
log4j = {
appenders {
def logPattern = '%d{dd-MM-yyyy HH:mm:ss,SSS} %5p %c{2} - %m%n'
console name: 'consoleAppender', layout: pattern(conversionPattern: logPattern)
file name: "fileAppender", file: "appLog.txt"
}
root {
// define the root logger's level and appenders, these will be inherited by all other loggers
error 'consoleAppender', 'fileAppender'
}
def appNamespaces = [
'com.my.code',
'grails.app.conf.com.my.code',
'grails.app.filters.com.my.code',
'grails.app.taglib.com.my.code',
'grails.app.services.com.my.code',
'grails.app.controllers.com.my.code',
'grails.app.domain.com.my.code'
]
appNamespaces.each { debug it }
}
In grails 2.x apps I used next format (with regards to your config):
debug rollingFile 'com.my.code'
Furthermore, if you need to set different log level for a bunch of packages:
debug rollingFile: ['com.example','com.otherpackage']

Grails logging from controller

I'm having a hard time to get Grails 2.4.5 to log my custom messages from my controllers into a specific file. This is what I have in the config part:
log4j = {
/*
* Log levels
off
fatal
error
warn
info
debug
trace
all
*/
appenders {
console name:'stdout', threshold: org.apache.log4j.Level.INFO
rollingFile name: 'applog', maxFileSize: 1024, file: (System.getProperty('catalina.base') ?: 'target') + '/logs/' + appName + '.log',
layout: pattern(conversionPattern: "[%d{HH:mm:ss:SSS}] %-5p %c{2}: %m%n")
environments {
development {
rollingFile name: 'grailsfile', maxFileSize: 4096, file: 'target/logs/grails.log'
file name: 'rootlog', file: 'target/logs/root.log'
}
}
}
root { error 'stdout'}
environments {
development {
debug additivity: false, 'grails.app'
root { error 'stdout', 'rootlog'} //override the root
warn additivity: false, grailsfile:
['org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails.web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework',
'org.hibernate',
'net.sf.ehcache.hibernate']
debug additivity: false, applog:
['grails.app.controllers', 'grails.app.domain', 'grails.app.services']
}
// production {
// root { error() }
// warn "grails.app.controllers"
// warn "grails.app.domain"
// warn "grails.app.services"
// warn additivity: false, applog: 'grails.app'
// }
}
}
in the controller:
println "Debug log enabled?: " + log.debugEnabled
log.debug "First piggy wrote to Debug"
log.info "Second piggy wrote to Info"
log.error "And the third piggy wrote to Error"
That shows me "Debug log enabled?: true" on console. But the message are not logged anywhere.
The Grails internals log to "grailsfile" and also errors go to "rootlog". But appName.log stays empty.
Any hint what I am having wrong?
UPDATE
To simplify my request I have only configured the most important now. I want the lines
log.debug "First piggy wrote to Debug"
log.info "Second piggy wrote to Info"
log.error "And the third piggy wrote to Error"
End up in the appender applog (file)
So the log4j now only has:
log4j = {
appenders {
console name:'stdout'//, threshold: org.apache.log4j.Level.INFO
rollingFile name: 'applog', maxFileSize: 1024, file: (System.getProperty('catalina.base') ?: 'target') + '/logs/' + appName + '.log',
layout: pattern(conversionPattern: "[%d{HH:mm:ss:SSS}] %-5p %c{2}: %m%n")
}
environments {
development {
debug 'grails.app'
debug additivity: false
applog: ['grails.app.controllers', 'grails.app.domain', 'grails.app.services']
}
}
}
But Still I get my log lines (and also errors from other sources) into console while my custom log file stays empty.
So I simply want to get (ONLY) my log lines into the applog appender as a first step. Any hint how to achieve this?
If you are running the app in development mode, then all your logs with error level and higher are going to target/logs/root.log
It is configured here:
file name: 'rootlog', file: 'target/logs/root.log' ...
root { error 'stdout', 'rootlog'} //override the root
That's because development closure overrides your global configuration.
If you want to see all the logs in appName.log, you should set lower logging level and change appender like this:
root { info 'stdout', 'applog'} //override the root
meanwhile I could figure out that this property made the trouble for my custom log messages:
def appName = grails.util.Metadata.current.'app.name'
...
file: (System.getProperty('catalina.base') ?: 'target') + '/logs/' + appName + '.log',
changing to this works:
log4jFileName = (System.properties.'catalina.base') + "/logs/${appName}.log"
...
file: "${config.log4jFileName}",

Neo4j database for Grails app without using Neo4j GORM plugin

I want to make a web-app using Grails framework for the server part and Neo4j database for storage. I found the Neo4j GORM plugin on Grails site, but unfortunately after numerous attempts I could not make it work properly. If i solve one error I get more, i can't even set a basic app to work. So I would like to write my own code for handling CRUD operations. I would like to override the default CRUD operations for domain classes. For example when I save a Person entity, i would use the REST API offered by Neo4j database to store the entity there etc. Would this be an acceptable solution? If yes, then how should I proceed about overriding the CRUD methods for domain classes?
Problem i had with GORM plugin: I followed the steps described in the documentation : http://projects.spring.io/grails-data-mapping/neo4j/manual/guide/gettingStarted.html . I created a simple Grails web-app, included the Neo4j-GORM plugin dependency. The application started.
If I try to access 'org.grails.datastore.gorm.neo4j.Neo4jController' I get some strange errors:
Here are the errors I get in the console:
015-01-04 14:11:22,460 [http-bio-8080-exec-2] ERROR errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [GET] /ANewHope/neo4j/node
Cannot invoke method getNodeById() on null object. Stacktrace follows:
Message: Cannot invoke method getNodeById() on null object
Line | Method
->> 30 | doCall in org.grails.datastore.gorm.neo4j.Neo4jController$_closure2
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 198 | doFilter in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Here is my BuildConfig.groovy:
grails.servlet.version = "3.0" // Change depending on target container compliance (2.5 or 3.0)
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.work.dir = "target/work"
grails.project.target.level = 1.6
grails.project.source.level = 1.6
//grails.project.war.file = "target/${appName}-${appVersion}.war"
grails.project.fork = [
// configure settings for compilation JVM, note that if you alter the Groovy version forked compilation is required
// compile: [maxMemory: 256, minMemory: 64, debug: false, maxPerm: 256, daemon:true],
// configure settings for the test-app JVM, uses the daemon by default
test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true],
// configure settings for the run-app JVM
run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
// configure settings for the run-war JVM
war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
// configure settings for the Console UI JVM
console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]
]
grails.project.dependency.resolver = "maven" // or ivy
grails.project.dependency.resolution = {
// inherit Grails' default dependencies
inherits("global") {
// specify dependency exclusions here; for example, uncomment this to disable ehcache:
// excludes 'ehcache'
}
log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
checksums true // Whether to verify checksums on resolve
legacyResolve false // whether to do a secondary resolve on plugin installation, not advised and here for backwards compatibility
repositories {
inherits true // Whether to inherit repository definitions from plugins
grailsPlugins()
grailsHome()
mavenLocal()
grailsCentral()
mavenCentral()
// uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories
//mavenRepo "http://repository.codehaus.org"
//mavenRepo "http://download.java.net/maven/2/"
//mavenRepo "http://repository.jboss.com/maven2/"
mavenRepo 'http://m2.neo4j.org/releases'
}
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.
// runtime 'mysql:mysql-connector-java:5.1.29'
// runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
test "org.grails:grails-datastore-test-support:1.0.2-grails-2.4"
}
plugins {
// plugins for the build system only
build ":tomcat:7.0.55"
// plugins for the compile step
compile ":neo4j:2.0.0-M02"
compile ":scaffolding:2.1.2"
compile ':cache:1.1.8'
compile ":asset-pipeline:1.9.9"
// plugins needed at runtime but not for compilation
// runtime ":hibernate4:4.3.6.1" // or ":hibernate:3.6.10.18"
//runtime ":database-migration:1.4.0"
runtime ":jquery:1.11.1"
// Uncomment these to enable additional asset-pipeline capabilities
//compile ":sass-asset-pipeline:1.9.0"
//compile ":less-asset-pipeline:1.10.0"
//compile ":coffee-asset-pipeline:1.8.0"
//compile ":handlebars-asset-pipeline:1.3.0.3"
}
}
Here is DataSource.groovy:
dataSource {
pooled = true
jmxExport = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
//hibernate {
// cache.use_second_level_cache = true
// cache.use_query_cache = false
//// cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' // Hibernate 3
// cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
// singleSession = true // configure OSIV singleSession mode
// flush.mode = 'manual' // OSIV session flush mode outside of transactional context
//}
//grails {
// neo4j {
// type = "embedded"
// location = "C:\\data\\neo4j"
// params = []
// }
//}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
properties {
// See http://grails.org/doc/latest/guide/conf.html#dataSource for documentation
jmxEnabled = true
initialSize = 5
maxActive = 50
minIdle = 5
maxIdle = 25
maxWait = 10000
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
validationQuery = "SELECT 1"
validationQueryTimeout = 3
validationInterval = 15000
testOnBorrow = true
testWhileIdle = true
testOnReturn = false
jdbcInterceptors = "ConnectionState"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}
}
}
}
After this I tried to specify the location as suggested in the documentation and added the following to DataSource.groovy:
grails {
neo4j {
type = "embedded"
location = "C:\\data\\neo4j"
params = []
}
}
The result was the same. After failed attempts I decided to try some other solution.
I want to use Neo4j for my Bachelor Thesis project, and my professor suggested me to use it with Grails. I like both Neo4j and Grails, but unfortunately I got into this problem when I tried to use them together.
If you don't want to use the GORM plugin, you could for instance use the Neo4j-JDBC driver from Grails to send parameterized Cypher Statements to the server. Much like you would do with a relational database.
There is also a new ORM in the works but it is still very much work in progress. You can find it here: https://github.com/neo4j/neo4j-ogm
As powerful as the GORM is, it isn't right for every project. I often elect to use something else, however, grails expects that anything in the domain directory is going to be using the GORM. If you want to use a different API you should just put your classes in src/groovy. If you still want to be able to use constraints for validation, you can apply the #Validatable annotation to the class. Details on that can be found in the Validation Grails docs. I would then just put all of your code to interface with the Neo4j REST API into a Grails Service.

Resources