I have created a service where in its init method it tries to load an object from the database, but this error is thrown:
Caused by IllegalStateException: Method on class [pruebainitservice.Conf] was used outside of a Grails application. If running in the context of a test using the mocking API or bootstrap Grails correctly.
->> 15 | init in pruebainitservice.ConfService
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 262 | run in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . in java.lang.Thread
| Error Forked Grails VM exited with error
I have created an example project, that basically does this; it just contains a domain class, a service, a controller with an action and its view. You can download from here https://github.com/okelet/grails-test-service-init.
Does anyone know why this happens?
Grails version: 2.3.8
Groovy Version: 2.1.8 JVM: 1.7.0_55 Vendor: Oracle Corporation OS: Linux
Regards and thanks in advance.
looks like #PostConstruct annotation is using it's own ClassLoader, hence the exception.
I'd use InitializingBean interface to do the init you need:
class SomeService implements InitializingBean {
#Override
void afterPropertiesSet() throws Exception {
doStuffHere()
}
}
UPDATE:
the only solution I could find was to call the init-method from BootStrap:
class SomeService {
void init(){
log.debug("Cargando configuraciĆ³n...")
def confs = Conf.findAll()
// the rest
}
}
and
class BootStrap {
def confService
def init = { servletContext ->
confService.init()
}
def destroy = {
}
}
Related
I tried to use oauth plugin 2.6.1 on a Grails 2.4.4 blank application.
I followed instruction on documentation for quickstart, however when I start the application I have that stacktrace:
Message: Error creating bean with name 'grails.plugin.databasemigration.DbdocController': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'instanceControllerTagLibraryApi': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.codehaus.groovy.grails.plugins.web.api.ControllerTagLibraryApi.setTagLibraryLookup(org.codehaus.groovy.grails.web.pages.TagLibraryLookup); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gspTagLibraryLookup': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uk.co.desirableobjects.oauth.scribe.OauthTagLib': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oauthService': Invocation of init method failed; nested exception is uk.co.desirableobjects.oauth.scribe.exception.InvalidOauthProviderException: [:] configured as an API for facebook does not appear to be a valid Class. It should be a class extending from the org.scribe.builder.Api class
Line | Method
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'instanceControllerTagLibraryApi': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.codehaus.groovy.grails.plugins.web.api.ControllerTagLibraryApi.setTagLibraryLookup(org.codehaus.groovy.grails.web.pages.TagLibraryLookup); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gspTagLibraryLookup': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uk.co.desirableobjects.oauth.scribe.OauthTagLib': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oauthService': Invocation of init method failed; nested exception is uk.co.desirableobjects.oauth.scribe.exception.InvalidOauthProviderException: [:] configured as an API for facebook does not appear to be a valid Class. It should be a class extending from the org.scribe.builder.Api class
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by BeanCreationException: Could not autowire method: public void org.codehaus.groovy.grails.plugins.web.api.ControllerTagLibraryApi.setTagLibraryLookup(org.codehaus.groovy.grails.web.pages.TagLibraryLookup); nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gspTagLibraryLookup': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uk.co.desirableobjects.oauth.scribe.OauthTagLib': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oauthService': Invocation of init method failed; nested exception is uk.co.desirableobjects.oauth.scribe.exception.InvalidOauthProviderException: [:] configured as an API for facebook does not appear to be a valid Class. It should be a class extending from the org.scribe.builder.Api class
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'gspTagLibraryLookup': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uk.co.desirableobjects.oauth.scribe.OauthTagLib': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oauthService': Invocation of init method failed; nested exception is uk.co.desirableobjects.oauth.scribe.exception.InvalidOauthProviderException: [:] configured as an API for facebook does not appear to be a valid Class. It should be a class extending from the org.scribe.builder.Api class
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'uk.co.desirableobjects.oauth.scribe.OauthTagLib': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'oauthService': Invocation of init method failed; nested exception is uk.co.desirableobjects.oauth.scribe.exception.InvalidOauthProviderException: [:] configured as an API for facebook does not appear to be a valid Class. It should be a class extending from the org.scribe.builder.Api class
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'oauthService': Invocation of init method failed; nested exception is uk.co.desirableobjects.oauth.scribe.exception.InvalidOauthProviderException: [:] configured as an API for facebook does not appear to be a valid Class. It should be a class extending from the org.scribe.builder.Api class
->> 262 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
Caused by InvalidOauthProviderException: [:] configured as an API for facebook does not appear to be a valid Class. It should be a class extending from the org.scribe.builder.Api class
->> 48 | afterPropertiesSet in uk.co.desirableobjects.oauth.scribe.OauthService
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 262 | run in java.util.concurrent.FutureTask
| 1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . in java.lang.Thread
The error seems quite clear, but I don't understand if it's a configuration problem.
This is my configuraton in Config.groovy:
oauth {
providers {
twitter {
api = TwitterApi
key = 'my-key'
secret = 'my-secret'
}
}
}
Make sure you have imported the class FacebookApi in your Config.groovy
I'm new to Grails and I need to make some calculations when a "has-many" attribute changes, and I think the best place to do this is in the setter of the attribute, given that my attribute is a list the best place should be in the addTo and the removeFrom methods, I tried to override them but didn't worked.
So is this the best way of doing it? what's wrong with my code?
Here's the code:
Cicle.groovy
class Cicle {
String machine
int cicleValue
static hasMany = [measurements:Measurement]
static constraints = {
machine blank:false
cicleValue nullable:false
}
public void addToMeasurements(Measurement measurement){
super.addToMeasurements(measurement)
updateCalculations()
}
public void updateCalculations(){
int sumCicles = 0
measurements.each{ measurement ->
sumCicles += measurement.cicleValue
}
cicleValue = sumCicles / measurements.size()
this.save(failOnError: true)
}
}
This is the exception I get:
No signature of method: com.rpc.mock.app.Cicle.addToMeasurements() is applicable for argument types: (com.rpc.mock.app.Measurement) values: [com.rpc.mock.app.Measurement : (unsaved)]
Possible solutions: addToMeasurements(com.rpc.mock.app.Measurement), addToMeasurements(java.lang.Object), getMeasurements(). Stacktrace follows:
Message: No signature of method: com.rpc.mock.app.Cicle.addToMeasurements() is applicable for argument types: (com.rpc.mock.app.Measurement) values: [com.rpc.mock.app.Measurement : (unsaved)]
Possible solutions: addToMeasurements(com.rpc.mock.app.Measurement), addToMeasurements(java.lang.Object), getMeasurements()
Line | Method
->> 16 | addToMeasurements in com.rpc.mock.app.Cicle
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 43 | $tt__save in com.rpc.mock.app.MeasurementController
| 200 | 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
^ 744 | run . . . . . . . in java.lang.Thread
Thanks
As you're dealing with domain objects, GORM supports the registration of events as methods that get fired when certain events occurs such as deletes, insertsand updates:
beforeInsert - Executed before an object is initially persisted to the database
beforeUpdate - Executed before an object is updated
beforeDelete - Executed before an object is deleted
beforeValidate - Executed before an object is validated
afterInsert - Executed after an object is persisted to the database
afterUpdate - Executed after an object has been updated
afterDelete - Executed after an object has been deleted
onLoad - Executed when an object is loaded from the database
Then, you can add updateCalculations() in your domain object like that:
static constraints = {
machine blank:false
cicleValue nullable:false
}
def beforeUpdate() { updateCalculations() }
As a general good design practice, it's better to keep logic implementation out from domains object and Grails allows to inject services into domains (POGO).
So, I've just created a brand new grails app, created one Domain with a few fields, and then a controller and a set of views based from the domain (using grails built in generate commands).
I then attempt to run this and get the following error, any clues?: -
| Error 2013-10-24 12:08:11,643 [localhost-startStop-1] ERROR context.GrailsContextLoader - Error executing bootstraps: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Can not set java.lang.String field test.PC.MyName to java.lang.Class
Message: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Can not set java.lang.String field test.PC.MyName to java.lang.Class
Line | Method
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Can not set java.lang.String field test.PC.MyName to java.lang.Class
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Can not set java.lang.String field test.PC.MyName to java.lang.Class
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by IllegalArgumentException: Can not set java.lang.String field test.PC.MyName to java.lang.Class
->> 6 | doCall in test.PC$__clinit__closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 334 | innerRun in java.util.concurrent.FutureTask$Sync
| 166 | run . . . in java.util.concurrent.FutureTask
| 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 603 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
At the risk over overfilling this with data, a quick google suggests this could be something to do with my datasource? If so my datasource file looks like so which is the standard template for when a project is first generated so should work..? : -
dataSource {
pooled = 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'
}
// 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"
}
}
test {
dataSource {
dbCreate = "update"
url = "jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000"
pooled = true
properties {
maxActive = -1
minEvictableIdleTimeMillis=1800000
timeBetweenEvictionRunsMillis=1800000
numTestsPerEvictionRun=3
testOnBorrow=true
testWhileIdle=true
testOnReturn=true
validationQuery="SELECT 1"
}
}
}
}
It also mentions failures with the bootstrap, again I've included it here but its the standard file created on setup and unmodified...?
class BootStrap {
def init = { servletContext ->
}
def destroy = {
}
}
Domain code is: -
package test
class PC {
static constraints = {
MyName()
MyVal1()
MyVal2()
}
String MyName
String MyVal1
String MyVal2
}
Java and Groovy naming convention is to start class names uppercase and variables and instances lowercase. To take advantage of Grails convention, it is recommended to follow the same convention as java and groovy. Grails does some magics based on the variable names, for example, Grails matches domain fields to their database fields by their name or Grails bean autowiring is based on bean's name, therefore, creating variables with UpperCase might have confused it in your case.
I have special case of domain classes structure where three classes presents and they are connected to chain: Event <- Room <- Projector. (All relation ships are one-to-one)
The implementation looks like:
class Event {
Room room
static constraints = {
room(nullable:false)
}
}
class Room {
Projector projector = new Projector()
static belongsTo = [event: Event]
static constraints = {
projector(nullable:false)
}
}
class Projector {
String something = "Something"
static belongsTo = [room: Room]
static constraints = {
room(nullable:false)
}
}
When I want to create Event with new Room I expect that the Projector will be created by default:
class TestController {
def index() {
Room room = new Room()
Event event = new Event(room: room)
event.save(flush: true, failOnError: true)
render event
}
}
I receive following exception
| Error 2012-07-11 16:09:12,541 [http-bio-8080-exec-3] ERROR errors.GrailsExceptionResolver - TransientObjectException occurred when processing request: [GET] /Test/room/index
object references an unsaved transient instance - save the transient instance before flushing: Projector. Stacktrace follows:
Message: object references an unsaved transient instance - save the transient instance before flushing: Projector
Line | Method
->> 46 | onApplicationEvent in org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 18 | index in RoomController
| 1110 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
It seems that cascading over three classes doesn't save default values. Is there any solution for that? Or what am I doing wrong?
There is an open jira for your issue at http://jira.grails.org/browse/GRAILS-4613?attachmentOrder=desc
Personally I would handle the creation of objects in my controller instead of doing it in the domain. You need to be able to call projector.save(flush:true).
This question is in follow up to this post Grails one to many relationship view
The example suggested there is not working and throwing following exception at run time
null id in blog.omarello.Phone entry (don't flush the Session after an exception occurs). Stacktrace follows:
Message: null id in blog.omarello.Phone entry (don't flush the Session after an exception occurs)
Line | Method
->> 43 | doCall in blog.omarello.ContactController$_closure4$$ENLORkU6
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 886 | runTask in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run . . in ''
^ 662 | run in java.lang.Thread
I think rather then making the example work can any one help me understand how can I create a GSP which can let me save multiple instances of same domain class. For example, a GSP which can let me insert multiple Book instances at once?
Once again, examine the project I linked on github. It is a demonstration of some of the one of the better practices for doing this. Particularly, look at the question/index, as this is what the view can look like. The actual saving piece is done in the QuestionService, used by the QuestionController. This project does exactly what you're trying to do. Review it.
Change the Contact class in the phone example as follows and it should work fine.
package blog.omarello
import org.apache.commons.collections.list.LazyList;
import org.apache.commons.collections.FactoryUtils;
class Contact {
static constraints = {
firstName(blank:false)
lastName(blank:false)
}
String firstName
String lastName
String nickName
List phones = LazyList.decorate(new ArrayList(),
FactoryUtils.instantiateFactory(Phone.class));
// List phones = new ArrayList()
static hasMany = [ phones:Phone ]
static mapping = {
phones cascade:"all-delete-orphan"
}
// def getPhonesList() {
// return LazyList.decorate(
// phones,
// FactoryUtils.instantiateFactory(Phone.class))
// }
def String toString() {
return "${lastName}, ${firstName}"
}
}