Use grails plugin datasource - grails

I'm using Grails 2.2.4 to build a plugin. The plugin is an access manager and need to access some datasources (more than one). As the Grails manual specify in Providing Basic Artefacts, the DataSource.groovy is not bundled with the plugin.
Is there a way to "copy" the datasources defined on the plugin DataSource.groovy file to the application's DataSource.groovy file that uses the plugin?
I really don't want to manually define the plugin datasources on every application that uses the plugin.
============
Full stacktrace (requested in comments)
2013-12-11 11:39:33,055 ERROR org.codehaus.groovy.grails.web.context.GrailsConte
xtLoader - Error initializing the application: groovy.lang.MissingMethodExceptio
n: No signature of method: portal.Aplicacao.methodMissing() is applicable for ar
gument types: () values: []
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMetho
dException: No signature of method: portal.Aplicacao.methodMissing() is applicab
le for argument types: () values: []
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.
java:308)
at grails.util.Environment.executeForEnvironment(Environment.java:301)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java
:277)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExec
utor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor .java:908)
at java.lang.Thread.run(Thread.java:662)
Caused by: groovy.lang.MissingMethodException: No signature of method: portal.Ap
licacao.methodMissing() is applicable for argument types: () values: []
at portal.PortalService.criaAplicacaoNoPortal(PortalService.groovy:233)
at BootStrap$_closure1.doCall(BootStrap.groovy:16)
... 8 more

You can use the platform-core plugin, and then define the dataSources as application config in the doWithConfig section of your plugin, like so:
def doWithConfig = { config ->
// ...
application {
Environment.executeForCurrentEnvironment {
development {
dataSource_myDatasource {
dbCreate = "create-drop"
url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
// other datasource configuration here...
}
}
}
test {
dataSource_myDatasource {
// test datasource
dbCreate = "create-drop"
url = "jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
// ...
}
}
}
}
}
}

Related

How to configure a custom maven repository in Grails 2.2?

I am trying to get dependency resolution to work in Grails 2.2 from a custom repository which has username password.
I have tried adding the following in my BuildConfig.groovy
grails.project.dependency.resolver = "maven"
grails.project.ivy.authentication = {
repositories {
mavenRepo('https://maven.companyname.com/repository/repository-name') {
auth([
username: 'myusername',
password: 'mypassword'
])
}
}
}
But I get error like
Caused by: groovy.lang.MissingMethodException: No signature of method: groovy.util.ConfigSlurper$_parse_closure5.auth() is applicable for argument types: (java.util.LinkedHashMap) values:
I tried looking at https://grails.github.io/grails2-doc/2.2.0/guide/single.html#dependencyRepositories but it does not tell me more information. It does say that I need to put the credentials in settings.groovy but is that absolutely necessary? I tried putting the credentials inside mavenRepo closure but that did not work. Any ideas?
Grails 2 - quite some time ago…
This way it is working here.
BuildConfig.groovy:
…
grails.project.dependency.resolver = "ivy"
grails.project.dependency.resolution = {
repositories {
mavenRepo "https://repo.example.com/myrepo"
}
…
~/.grails/settings.groovy:
…
grails.project.ivy.authentication = {
credentials {
realm = "My Realm"
host = "repo.example.com"
username = "user"
password = "secret"
}
}
…

Configure ActiveMQ broker in grails

Using Jms plugin for grails and add dependencies for ActiveMQ worked perfect. No problems.
Now I want to go beyond and perform some customization and fine tuning to make ActiveMQ behaves as I need, so I need to configure the broker instance.
e.g. I want to use JDBC storage.
How is possible to do that with grails and the vm embedded broker?
I've actually followed the reference documentation for the JMS grails plugin ... I add jms plugin and activemq dependencies and place this on resources:
jmsConnectionFactory(SingleConnectionFactory) {
targetConnectionFactory = { ActiveMQConnectionFactory cf ->
//brokerURL = 'vm://localhost'
brokerURL = 'tcp://localhost:61616?jms.useAsyncSend=true'
}
}
As I've said this is fine ... but I need more tuning here, so I've tried to go adding this in the resources, so I can access the broker to fine tuning:
/* Establish the broker */
amq.broker(useJmx: false, persistent: true) {
amq.transportConnectors() {
amq.transportConnector(uri: "tcp://localhost:61616")
}
}
amqConnectionFactory(ActiveMQConnectionFactory) {
brokerURL = "vm://localhost"
}
jmsConnectionFactory(SingleConnectionFactory) {
targetConnectionFactory = ref(amqConnectionFactory)
}
But I start to have dependency problems like:
2015-03-18 13:44:14 - spring.RuntimeSpringConfigUtilities [RuntimeConfiguration] Unable to load beans from resources.groovy
org.springframework.beans.FatalBeanException: NamespaceHandler class [org.apache.xbean.spring.context.v2.XBeanNamespaceHandler] for namespace [http://activemq.apache.org/schema/core] not found; nested exception is java.lang.ClassNotFoundException: org.apache.xbean.spring.context.v2.XBeanNamespaceHandler
So I start adding dependencies:
compile 'org.apache.activemq:activemq-spring:5.7.0'
compile 'org.springframework:spring-beans:4.1.1.RELEASE'
compile 'org.apache.xbean:xbean-spring:4.1'
But still have problems:
java.lang.NoClassDefFoundError: org/springframework/core/OrderComparator$OrderSourceProvider
At this point I get the feeling that I am doing something wrong since I see too much complexity.
Is there a best way to do this?
In order to be able to configure ActiveMQ you'll need:
Dependencies:
compile 'org.apache.activemq:activemq-core:5.7.0'
compile 'org.apache.activemq:activemq-spring:5.7.0'
compile 'org.springframework:spring-beans:4.0.6.RELEASE'
compile 'org.apache.xbean:xbean-spring:4.1'
Resources.groovy:
xmlns amq:"http://activemq.apache.org/schema/core"
...
/* Establish the broker */
amq.broker(useJmx: false, persistent: true) {
amq.transportConnectors() {
amq.transportConnector(uri: "tcp://localhost:61616")
}
//HERE YOU CAN CONFIGURE BROKER
}
amqConnectionFactory(ActiveMQConnectionFactory) {
brokerURL = "vm://localhost"
}
jmsConnectionFactory(SingleConnectionFactory) {
targetConnectionFactory = ref(amqConnectionFactory)
}
The above answer of Rafael is very useful just a small change you need to do if you are working with Grails 3.2.+ it took me few hrs to figure it out.
Depedencies (add them in build.gradle)
compile 'org.grails.plugins:jms:2.0.0.RC2'
compile 'org.apache.activemq:activemq-core:5.7.0'
compile 'org.apache.activemq:activemq-spring:5.14.5'
compile 'org.apache.xbean:xbean-spring:4.1'
Resources.groovy (should look something like)
import org.apache.activemq.ActiveMQConnectionFactory
import org.springframework.jms.connection.SingleConnectionFactory
beans = {
....
xmlns amq:"http://activemq.apache.org/schema/core"
amq.broker(useJmx: false, persistent: true) {
amq.transportConnectors() {
amq.'transportConnector'(uri: "tcp://localhost:61616")
// optional if you want to do something with mqtt
amq.'transportConnector'(uri:'mqtt://0.0.0.0:61612')
}
}
jmsConnectionFactory(SingleConnectionFactory) {
targetConnectionFactory = { ActiveMQConnectionFactory cf ->
brokerURL = 'vm://localhost'
}
}
...
}

Grails custom test - No signature of method: org.codehaus.groovy.grails.test.runner.phase.IntegrationTestPhaseConfigurer.prepare()

I'm trying to follow Luke Daley's instructions on http://ldaley.com/post/615966534/custom-grails-test to add a custom test type, which should behave as an integration spec (grails-2.4.4, btw).
I've put my specs under test/apint and my _Events.groovy loooks like below:
eventAllTestsStart = {
phasesToRun << "apint"
}
def apintSpecsSuffix = "spec"
def apintSpecsDirectory = "apint"
def apintSpecsTestType = new GrailsSpecTestType(apintSpecsSuffix, apintSpecsDirectory)
apintTests = [apintSpecsTestType]
apintTestPhasePreparation = {
integrationTestPhasePreparation()
}
apintTestPhaseCleanUp = {
integrationTestPhaseCleanUp()
}
When I run grails test-app apint: I get the following error message:
Fatal error running tests: No signature of method: org.codehaus.groovy.grails.test.runner.phase.IntegrationTestPhaseConfigurer.prepare() is applicable for argument types: () values: []
Possible solutions: prepare(groovy.lang.Binding, java.util.Map), prepare(groovy.lang.Binding, java.util.Map), grep(), grep(java.lang.Object), every(), println() (Use --stacktrace to see the full trace)
.Tests FAILED
Any ideas why this is happening or how to fix it?
Thanks!

grails bootstrap error writing to mysql

I'm using spring security within a simple app. The app runs fine locally when connecting to amazon RDS instance. When I upload my app to elastic beanstalk the creation of a role fails in Bootstrap:
def init = { servletContext ->
println log.name
log.debug("hello 1")
def adminRole = new Role(authority: 'ROLE_ADMIN')
log.debug("hello 2")
if (!adminRole.save(flush: true, failOnError: true)) {
log.debug("hello 3")
adminRole.errors.each {
println it
log.error(it)
}
}
2013-12-17 23:25:33,311 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error initializing the application: groovy.lang.MissingMethodException: No signature of method: com.nrfa.Role.save() is applicable for argument types: () values: []
Possible solutions: save(), save(boolean), save(java.util.Map), wait(), last(), any()
org.codehaus.groovy.runtime.InvokerInvocationException: groovy.lang.MissingMethodException: No signature of method: com.nrfa.Role.save() is applicable for argument types: () values: []
Possible solutions: save(), save(boolean), save(java.util.Map), wait(), last(), any()
at grails.util.Environment.evaluateEnvironmentSpecificBlock(Environment.java:308)
at grails.util.Environment.executeForEnvironment(Environment.java:301)
at grails.util.Environment.executeForCurrentEnvironment(Environment.java:277)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
Caused by: groovy.lang.MissingMethodException: No signature of method: com.nrfa.Role.save() is applicable for argument types: () values: []
Possible solutions: save(), save(boolean), save(java.util.Map), wait(), last(), any()
at BootStrap$_closure1.doCall(BootStrap.groovy:15)
... 9 more
If it were a database connectivity issue - which it may be - I would have thought the error would have been 'hey, can't connect to the database'. Not the non-descriptive error of can't find Role.save().
EDIT:
Full bootstrap:
import com.nrfa.Role
import com.nrfa.User
import com.nrfa.UserRole
class BootStrap {
def springSecurityService
def init = { servletContext ->
println log.name
log.debug("hello 1")
def adminRole = new Role(authority: 'ROLE_ADMIN')
log.debug("hello 2")
if (!adminRole.save(flush: true, failOnError: true)) {
log.debug("hello 3")
adminRole.errors.each {
println it
log.error(it)
}
}
log.debug("hello 4")
def userRole = new Role(authority: 'ROLE_USER').save(flush: true, failOnError: true)
def testUser = new User(username: 'me', password: 'password')
testUser.save(flush: true, failOnError: true)
UserRole.create testUser, userRole, true
assert User.count() == 1
assert Role.count() == 2
assert UserRole.count() == 1
}
def destroy = {
}
}
EDIT: Include BuildConfig.Groovy:
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.
//runtime 'mysql:mysql-connector-java:5.1.27'
runtime 'org.slf4j:slf4j-api:1.7.5'
}
plugins {
build ":hibernate:$grailsVersion"
runtime ":jquery:1.8.3"
runtime ":resources:1.2"
runtime ":mysql-connectorj:5.1.22.1"
compile ':spring-security-core:2.0-RC2'
// Uncomment these (or add new ones) to enable additional resources capabilities
//runtime ":zipped-resources:1.0"
//runtime ":cached-resources:1.0"
//runtime ":yui-minify-resources:0.1.5"
build ":tomcat:$grailsVersion"
build ":database-migration:1.3.2"
compile ':cache:1.0.1'
// runtime ":mysql-connectorj:5.1.22.1"
}
That error is usually indicative of the hibernate plugin not being installed or working. Can you see the expanded war on the remote server? I'm not familiar with the workings of beanstalk itself so maybe something is in conflict there.
Adding "runtime 'mysql:mysql-connector-java:5.1.27'" in dependencies and remove it from plugins?

Expired activiti jobs throwing exception while server startup - Grails

This is with regard to activiti workflow timer jobs in grails application.
While starting the grails app with expired jobs, exception is thrown for normal grails features such as log and methods of domain classes.
For eg:
Caused by: groovy.lang.MissingPropertyException: No such property: log for class: com.service.common.UtilityService
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:49)
at org.codehaus.groovy.runtime.callsite.PogoMetaClassGetPropertySite.getProperty(PogoMetaClassGetPropertySite.java:50)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callGroovyObjectGetProperty(AbstractCallSite.java:239)
at com.service.common.UtilityService.insertToQueue(UtilityService.groovy:370)
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:597)
at org.activiti.engine.impl.javax.el.BeanELResolver.invoke(BeanELResolver.java:479)
... 71 more
This happens in dev environment running the app from Spring STS. We are using activiti plugin 5.8.2 for grails (1.3.6)
After the web-app is started up completely, the jobs (schedule to a time after startup) run properly and no missing property exception is thrown.
Even though we can fix the of missing property issue for log by using private static final log = LogFactory.getLog(this) instead, then any reference to domain classes throw an error, like using get or find method.
eg:
Caused by: groovy.lang.MissingMethodException: No signature of method: static com.domain.wr.WorkRequest.read() is applicable for argument types: (java.lang.String) values: [44700]
Possible solutions: getId(), getAt(java.lang.String), setId(java.lang.Long), grep(java.lang.Object), each(groovy.lang.Closure), find(groovy.lang.Closure)
at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1357)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1343)
at groovy.lang.ExpandoMetaClass.invokeStaticMethod(ExpandoMetaClass.java:1082)
at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:50)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:124)
at com.service.common.UtilityService.insertToQueue(UtilityService.groovy:373)
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:597)
at org.activiti.engine.impl.javax.el.BeanELResolver.invoke(BeanELResolver.java:479)
... 71 more
Activiti Configuration
Config.groovy
// Added by the Grails Activiti plugin:
activiti {
processEngineName = "activiti-engine-default"
databaseType = "oracle"
deploymentName = appName
history = "audit" // "none", "activity", "audit" or "full"
sessionUsernameKey = "username"
useFormKey = true
deploymentResources = ["classpath:activiti/escalation/WorkRequest.bpmn20.xml"]
}
Config.properties
activiti.processEngineName =activiti-engine-default
activiti.databaseSchemaUpdate =true
activiti.jobExecutorActivate =true
activiti.mailServerHost = "mail1.net"
activiti.mailServerPort = 25
activiti.mailServerUsername = ""
activiti.mailServerPassword = ""
activiti.mailServerDefaultFrom = ""
This is killing my application as a downtime makes the workflow unusable with timer tasks.
I had more or less the same problem, and in our case was caused by Activiti starting jobs execution before Spring injection being finished. That's why it only happens at startup: the job is accessing properties that are not there yet.
You can confirm that you are in the same situation by increasing the RETRIES_ in the ACT_RU_JOB table after the app has finished bootstraping and see if the jobs execute successfully.
If this is your case, I think the only option is to upgrade the plugin and if still fails, create a bug.
This issue got solved.
1) Edit Config.groovy and disable activiti during startup
activiti {
processEngineName = "activiti-engine-default"
databaseType = "oracle"
disabled = true
deploymentName = appName
sessionUsernameKey = "username"
useFormKey = true
deploymentResources = []
}
2) add the initialization of Activiti Objects in the init method of User BootStrap
def init = { servletContext ->
org.springframework.context.ApplicationContext ctx = ServletContextHolder.getServletContext().getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT)
def bb = new grails.spring.BeanBuilder(ctx)
bb.beans {
//println "Activiti Process Engine Initialization..."
customDbIdGenerator(com.mycompany.activiti.customDbIdGenerator){
idBlockSize=CH.config.activiti.idBlockSize?:100
}
processEngineConfiguration(org.activiti.spring.SpringProcessEngineConfiguration) {
processEngineName = CH.config.activiti.processEngineName?:ActivitiConstants.DEFAULT_PROCESS_ENGINE_NAME
databaseType = CH.config.activiti.databaseType?:ActivitiConstants.DEFAULT_DATABASE_TYPE
databaseSchemaUpdate = CH.config.activiti.databaseSchemaUpdate ? CH.config.activiti.databaseSchemaUpdate.toString() : ActivitiConstants.DEFAULT_DATABASE_SCHEMA_UPDATE
deploymentName = CH.config.activiti.deploymentName?:ActivitiConstants.DEFAULT_DEPLOYMENT_NAME
deploymentResources = CH.config.activiti.deploymentResources?:ActivitiConstants.DEFAULT_DEPLOYMENT_RESOURCES
jobExecutorActivate = CH.config.activiti.jobExecutorActivate?:ActivitiConstants.DEFAULT_JOB_EXECUTOR_ACTIVATE
history = CH.config.activiti.history?:ActivitiConstants.DEFAULT_HISTORY
mailServerHost = CH.config.activiti.mailServerHost?:ActivitiConstants.DEFAULT_MAIL_SERVER_HOST
mailServerPort = CH.config.activiti.mailServerPort?:ActivitiConstants.DEFAULT_MAIL_SERVER_PORT
mailServerUsername = CH.config.activiti.mailServerUsername
mailServerPassword = CH.config.activiti.mailServerPassword
mailServerDefaultFrom = CH.config.activiti.mailServerDefaultFrom?:ActivitiConstants.DEFAULT_MAIL_SERVER_FROM
dataSource = ref("dataSource")
transactionManager = ref("transactionManager")
idGenerator= ref("customDbIdGenerator")
}
processEngine(org.activiti.spring.ProcessEngineFactoryBean) {
processEngineConfiguration = ref("processEngineConfiguration")
}
runtimeService(processEngine:"getRuntimeService")
repositoryService(processEngine:"getRepositoryService")
taskService(processEngine:"getTaskService")
managementService(processEngine:"getManagementService")
identityService(processEngine:"getIdentityService")
historyService(processEngine:"getHistoryService")
formService(processEngine:"getFormService")
activitiService(org.grails.activiti.ActivitiService) {
runtimeService = ref("runtimeService")
taskService = ref("taskService")
identityService = ref("identityService")
formService = ref("formService")
}
}
println "## Registering Beans ##";
bb.registerBeans(ctx);
ctx.getBean("processEngine");
println "Bean Count2 "+ctx.getBeanDefinitionCount();
}
Please note that DB Id Generator used is custom and can be replaced by the default one.

Resources