How to properly remove H2 from Grails - grails

I am trying to minimalize my Grails (2.4.2) app and cull out a lot of stuff that create-app generates that I'm just not going to use.
One of these things is H2. I'm just not going to use it, and besides, if I needed an embedded DB, I'd prefer to use HSQLDB.
So I made the following changes to my BuildConfig:
...
// Remove the DB console for all environments, not just dev.
grails.dbconsole.enabled = false
...
grails.project.dependency.resolution = {
inherits("global") {
excludes 'h2'
}
...
}
Now, when I do a run-app, I get the following error:
... <huge stacktrace omitted for brevity>
Caused by: org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: org.h2.Driver
... 4 more
Caused by: java.sql.SQLException: org.h2.Driver
... 4 more
Caused by: java.lang.ClassNotFoundException: org.h2.Driver
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.Class.forName(Class.java:270)
... 4 more
Error |
Forked Grails VM exited with error
What's going on and how do I fix this error while properly removing H2 and any of its configs/references?
Update, my DataSources.groovy file
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
}
// 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
}
}
}
}

In your grails-app/conf/DataSources.groovy you probably have some references to the h2 Driver, e.g.
dataSource {
pooled = true
jmxExport = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
Remove the dataSource configuration completely if you're not using any DB. If you're using a different DB, replace the h2 driver class name with the class name of the driver for your DB.

Related

how to set hikari connection properties in datasource.groovy

In springboot2.X i am able to set hikari connection pool config like maxLifeTime in application.ymal easily.
Similarly i want to to it in groovy. Is it inside dBProperties?
i am using groovy 2.5.4 and grails 2.4.4
dataSource {
pooled = true
dbCreate = "update"
url = "jdbc:mysql://localhost:3306/my_database"
driverClassName = "com.mysql.jdbc.Driver"
dialect = org.hibernate.dialect.MySQL5InnoDBDialect
username = "username"
password = "password"
type = "com.zaxxer.hikari.HikariDataSource"
properties {
....
....
dbProperties {
maxLifeTime=200000
}
}
}
You can add it as bean in conf/spring/resources.groovy
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import grails.util.Holders
// Place your Spring DSL code here
beans = {
dataSource(HikariDataSource) { bean ->
def ds = Holders.config.dataSource
def hp = new Properties()
hp.username = ds.username
hp.password = ds.password
hp.jdbcUrl = ds.url
hp.driverClassName = ds.driverClassName
hp.connectionTimeout = ds.hikariConnectionTimeout
hp.maximumPoolSize = ds.hikariMaximumPoolSize
hp.maxLifetime = ds.hikariMaxLifetime
hp.idleTimeout = ds.hikariIdleTimeout
hp.minimumIdle = ds.hikariMinimumIdle
hp.connectionTestQuery = "SELECT 1"
HikariConfig hc = new HikariConfig(hp)
bean.constructorArgs = [hc]
}
}
With these added you can define your properties in your Datasoure.groovy like this
dataSource {
dbCreate = "update"
url = "jdbc:postgresql://localhost:5432/db"
username = "username"
password = "password"
hikariMinimumIdle = 5
hikariMaximumPoolSize = 30
hikariIdleTimeout = 600000
hikariConnectionTimeout = 30000
hikariMaxLifetime = 1800000
}

How do I configure Jasypt to use a ZeroSaltGenerator?

I'm using Grails 1.3.7 with Jasypt and I have the below in my Config.groovy:
jasypt {
algorithm = "PBEWithMD5AndTripleDES"
password = "password"
keyObtentionIterations = 1
saltSizeBytes = 0
}
How can I set the salt property to ZeroSaltGenerator?
In Config.groovy, change your config for jasypt to:
jasypt {
algorithm = "PBEWithMD5AndTripleDES"
password = "password"
keyObtentionIterations = 1
saltGenerator = new org.jasypt.salt.ZeroSaltGenerator()
}
If you want to use ZeroSaltGenerator then you have to make following changes:
Inside your config.groovy:
jasypt {
encryptorRegisteredName = "gormEncryptor"
}
And in your resources.groovy:
beans = {
hibernateStringEncryptor(HibernatePBEStringEncryptor) {
registeredName = "gormEncryptor"
algorithm = "PBEWithMD5AndTripleDES"
password = "password"
keyObtentionIterations = 1
saltGenerator = new org.jasypt.salt.ZeroSaltGenerator()
}
}
And it will generate the same encrypted values everytime.

How do you use environment variables inside of Config.groovy

Inside of Config.groovy i have setup a few environment variables:
def appName = grails.util.Metadata.current.getApplicationName()
def casUrl = "https://login.cas.server/cas"
environments {
development {
grails.logging.jul.usebridge = true
host.address = "12.34.56.78"
host.port = "8080"
}
test {
grails.logging.jul.usebridge = true
host.address = "http://staging.server.somewhere.com/"
host.port = ""
}
production {
grails.logging.jul.usebridge = false
host.address = "http://www.production.com"
host.port = ""
}
}
I'm trying to use those values inside the same configuration file (Config.groovy) like so:
grails.plugin.springsecurity.cas.loginUri = '/login'
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.cas.serverUrlPrefix = '${casUrl}'
grails.plugin.springsecurity.cas.proxyCallbackUrl = "/secure/receptor"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
However, the only thing that is getting resolved is the appName variable, everything else is null. Is this something that can be done? It looks like it was used in this post here Grails: Spring Security CAS Working in 2.2.3 but I cant seem to get them to resolve.
If I do something like
def appName = grails.util.Metadata.current.getApplicationName()
def casUrl = "https://login.umt.edu/cas"
host.address = "MyAddress"
environments {
...
The configSlurper resolves that host.address inside the CAS config, why can't I access the enviornment variables?
See the answer here under Basic Configuration.
However, you can't nest after using the dot notation. In other words, this won't work
// Won't work!
foo.bar {
hello = "world"
good = "bye"
}
So try to use nesting like this
foo {
bar {
hello = "world"
good = "bye"
}
}
Move the properties that depend on host.address and host.port inside each environment block:
environments {
development {
grails.logging.jul.usebridge = true
host.address = "12.34.56.78"
host.port = "8080"
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
}
test {
grails.logging.jul.usebridge = true
host.address = "http://staging.server.somewhere.com/"
host.port = ""
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
}
production {
grails.logging.jul.usebridge = false
host.address = "http://www.production.com"
host.port = ""
grails.plugin.springsecurity.cas.serviceUrl = "${host.address}:${host.port}/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=${host.address}:${host.port}/${appName}/"
}
}
You can get rid of the host.address and host.port variables altogether:
environments {
development {
grails.logging.jul.usebridge = true
grails.plugin.springsecurity.cas.serviceUrl = "http://12.34.56.78:8080/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=http://12.34.56.78:8080/${appName}/"
}
test {
grails.logging.jul.usebridge = true
grails.plugin.springsecurity.cas.serviceUrl = "http://staging.server.somewhere.com/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=http://staging.server.somewhere.com/${appName}/"
}
production {
grails.logging.jul.usebridge = false
grails.plugin.springsecurity.cas.serviceUrl = "http://www.production.com/${appName}/j_spring_cas_security_check"
grails.plugin.springsecurity.logout.afterLogoutUrl = "${casUrl}/logout?url=http://www.production.com/${appName}/"
}
}

Datasource avanced properties

I just wondering is this is a valid DataSource configuration:
development {
properties {
maxActive = 50
maxIdle = 25
minIdle = 5
initialSize = 8
minEvictableIdleTimeMillis = 1000 * 15 * 60
timeBetweenEvictionRunsMillis = 1000 * 15 * 60
maxWait = 10000
validationQuery = "/* ping */"
}
dataSource {
username = "test"
password = "test"
dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:mysql://params"
}
}
If i have this, do the dataSource use the properties listed above?
If you want to centralize your properties, you can define the datasource without an enviornment first:
dataSource {
properties {
}
}
development {
dataSource {
}
}
properties is part of the datasource bean (of type BasicDataSource). Using DSL makes it easier not to use the accessor methods explicitly to set/get the members.
So I think you have to stick to
development{
dataSource{
......
properties{
.......
}
}
}

JdbcSQLException for a grails app with h2 database?

I'm getting a JdbcSQLException whenever I try to deploy my app to a server, though running locally works fine. I have no idea what this error is and can't seem to find the answer on google.
Code throwing the error:
class ResultService {
def recentStoryRuns() {
StoryRun.list(sort: "batch.dateCreated", order: "desc")
}
}
Full stacktrace:
org.h2.jdbc.JdbcSQLException: Table "STORY_RUN" not found; SQL statement:
select this_.id as id3_1_, this_.version as version3_1_, this_.batch_id as batch3_3_1_, this_.batch_iteration as batch4_3_1_, this_.browser_string as browser5_3_1_, this_.easybresult_id as easybres6_3_1_, this_.failed_scenarios as failed7_3_1_, this_.last_parse_error as last8_3_1_, this_.passed_scenarios as passed9_3_1_, this_.result_parsed_story_status as result10_3_1_, this_.status as status3_1_, this_.story as story3_1_, this_.total_scenarios as total13_3_1_, this_.xml as xml3_1_, storyrunba1_.id as id2_0_, storyrunba1_.version as version2_0_, storyrunba1_.batch_id as batch3_2_0_, storyrunba1_.browsers_string as browsers4_2_0_, storyrunba1_.date_created as date5_2_0_, storyrunba1_.iterations as iterations2_0_, storyrunba1_.site_profile as site7_2_0_, storyrunba1_.stories_string as stories8_2_0_ from story_run this_ inner join story_run_batch storyrunba1_ on this_.batch_id=storyrunba1_.id order by storyrunba1_.date_created desc [42102-164]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:329)
at org.h2.message.DbException.get(DbException.java:169)
at org.h2.message.DbException.get(DbException.java:146)
at org.h2.command.Parser.readTableOrView(Parser.java:4753)
at org.h2.command.Parser.readTableFilter(Parser.java:1080)
at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1686)
at org.h2.command.Parser.parseSelectSimple(Parser.java:1793)
at org.h2.command.Parser.parseSelectSub(Parser.java:1680)
at org.h2.command.Parser.parseSelectUnion(Parser.java:1523)
at org.h2.command.Parser.parseSelect(Parser.java:1511)
at org.h2.command.Parser.parsePrepared(Parser.java:405)
at org.h2.command.Parser.parse(Parser.java:279)
at org.h2.command.Parser.parse(Parser.java:251)
at org.h2.command.Parser.prepareCommand(Parser.java:217)
at org.h2.engine.Session.prepareLocal(Session.java:415)
at org.h2.engine.Session.prepareCommand(Session.java:364)
at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1121)
at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:71)
at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:267)
at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:281)
at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
at kindlingtests.ResultService.recentStoryRuns(ResultService.groovy:6)
at kindlingtests.HomeService.results(HomeService.groovy:19)
at kindlingtests.ModelFields$_closure1.doCall(ModelFields.groovy:13)
at kindlingtests.ModelFields.<init>(ModelFields.groovy:12)
at kindlingtests.HomeService.setControllerModelFields(HomeService.groovy:9)
at kindlingtests.HomeService.setControllerModelFields(HomeService.groovy:8)
at kindlingtests.HomeController.index(HomeController.groovy:14)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:680)
[edit]
As requested, my DataSource.groovy:
dataSource {
pooled = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:mem:devDb;MVCC=TRUE"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:prodDb;MVCC=TRUE"
pooled = true
properties {
maxActive = -1
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
}
}

Resources