Could not synchronize database state with session Error in Grails Hibernate - spring

I have registered a MySecurityEventListener in my Grails app to set a login count after a user has been logged in.
MySecurityEventListener class:
class MySecurityEventListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent>, LogoutHandler {
/**
* Handler for after login.
*/
#Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
User.withNewSession {
User user = User.get(event.authentication.principal.id)
user.lastLoginDate = new Date() // set the last login date
user.loginCount += 1 // increase the login count
user.isLoggedIn = true
user.save(flush: true)
}
}
/**
* Handler for after logout.
*/
#Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
User.withNewSession {
User user = User.get(authentication.principal.id)
user.isLoggedIn = false
user.save(flush: true)
}
}
}
Sometimes when a user loggs in I get the following error:
| Error 2013-07-03 13:40:56,306 [http-nio-8080-exec-1]
ERROR events.PatchedDefaultFlushEventListener -
Could not synchronize database state with session Message:
Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [demo.User#ffd93c5639b54405bf]
Line | Method
->> 38 | doCall in demo.MySecurityEventListener$_onApplicationEvent_closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 33 | onApplicationEvent in demo.MySecurityEventListener
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
2013-07-03 13:40:56,551 [http-nio-8080-exec-1] INFO cpr.SessionSupport - Session created
2013-07-03 13:40:56,554 [http-nio-8080-exec-2] INFO cpr.SessionSupport - Session created
| Error 2013-07-03 13:40:56,554 [http-nio-8080-exec-1] ERROR [/demo].[gsp] - Servlet.service() for servlet [gsp] in context with path [/demo] threw exception
Message: Object of class [demo.User] with identifier [ffd93c5639b54405bf]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [demo.User#ffd93c5639b54405bf]
Line | Method
->> 38 | doCall in demo.MySecurityEventListener$_onApplicationEvent_closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 33 | onApplicationEvent in demo.MySecurityEventListener
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
Caused by StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [demo.User#ffd93c5639b54405bf]
->> 38 | doCall in demo.MySecurityEventListener$_onApplicationEvent_closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 33 | onApplicationEvent in demo.MySecurityEventListener
| 1145 | runWorker . . . . in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . in java.lang.Thread
How do I have to fix this error?

withTransaction provides access to the underlying transaction. If needed a control over transaction rollback you can use it.
withSession uses the default session provided by SessionFactory. If needed a control over sesion then use it.
Looking at your example, I would vouch for withTransaction (the simplest one).

Related

Grails 2.4.5 Error net.sf.ehcache.CacheException: javax.management.MalformedObjectNameException Invalid character ':' in value part of property

I get this error below when running a Grails 2.4.5 project (full stacktrace)
Error |
2021-11-28 01:27:44,302 [localhost-startStop-1] ERROR context.GrailsContextLoaderListener - Error initializing the application: Error creating bean with name 'ehCacheManagementService': Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: net.sf.ehcache.CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
Message: Error creating bean with name 'ehCacheManagementService': Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: net.sf.ehcache.CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
Line | Method
->> 266 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run in java.lang.Thread
Caused by CacheException: net.sf.ehcache.CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
->> 246 | init in net.sf.ehcache.management.ManagementService
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 266 | run in java.util.concurrent.FutureTask
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run . . . in java.lang.Thread
Caused by CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
->> 76 | createObjectName in net.sf.ehcache.management.Cache
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 64 | <init> in ''
| 107 | getCache in net.sf.ehcache.management.CacheManager
| 126 | getCaches in ''
| 237 | init . . in net.sf.ehcache.management.ManagementService
| 266 | run in java.util.concurrent.FutureTask
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run . . . in java.lang.Thread
Caused by MalformedObjectNameException: Invalid character ':' in value part of property
->> 618 | construct in javax.management.ObjectName
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1382 | <init> in ''
| 73 | createObjectName in net.sf.ehcache.management.Cache
| 64 | <init> in ''
| 107 | getCache in net.sf.ehcache.management.CacheManager
| 126 | getCaches in ''
| 237 | init . . in net.sf.ehcache.management.ManagementService
| 266 | run in java.util.concurrent.FutureTask
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run . . . in java.lang.Thread
Error |
2021-11-28 01:27:44,339 [localhost-startStop-1] ERROR context.GrailsContextLoaderListener - Error initializing Grails: Error creating bean with name 'ehCacheManagementService': Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: net.sf.ehcache.CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
Message: Error creating bean with name 'ehCacheManagementService': Invocation of init method failed; nested exception is net.sf.ehcache.CacheException: net.sf.ehcache.CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
Line | Method
->> 266 | run in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run in java.lang.Thread
Caused by CacheException: net.sf.ehcache.CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
->> 246 | init in net.sf.ehcache.management.ManagementService
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 266 | run in java.util.concurrent.FutureTask
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run . . . in java.lang.Thread
Caused by CacheException: javax.management.MalformedObjectNameException: Invalid character ':' in value part of property
->> 76 | createObjectName in net.sf.ehcache.management.Cache
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 64 | <init> in ''
| 107 | getCache in net.sf.ehcache.management.CacheManager
| 126 | getCaches in ''
| 237 | init . . in net.sf.ehcache.management.ManagementService
| 266 | run in java.util.concurrent.FutureTask
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run . . . in java.lang.Thread
Caused by MalformedObjectNameException: Invalid character ':' in value part of property
->> 618 | construct in javax.management.ObjectName
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 1382 | <init> in ''
| 73 | createObjectName in net.sf.ehcache.management.Cache
| 64 | <init> in ''
| 107 | getCache in net.sf.ehcache.management.CacheManager
| 126 | getCaches in ''
| 237 | init . . in net.sf.ehcache.management.ManagementService
| 266 | run in java.util.concurrent.FutureTask
| 1149 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 624 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 748 | run . . . in java.lang.Thread
Error |
2021-11-28 01:27:44,345 [localhost-startStop-1] ERROR core.StandardContext - Error listenerStart
Error |
2021-11-28 01:27:44,347 [localhost-startStop-1] ERROR core.StandardContext - Context [/soctrack-web] startup failed due to previous errors
|Server running. Browse to http://localhost:8080/soctrack-web
I am not sure what's causing the error, I get a successful "maven clean/package/install".
However, doing a "grails compile", I get a deprecated warning (as show below) from the cache-ehcache plugin, I am assuming that might be the reason why I am getting this error, but not sure how to solve it.
Note: C:\Users\kgeoffroy\Documents\dev\soc-track-upgrade\SOCScheduleServiceWEB\target\plugins\cache-ehcache-1.0.5\src\java\grails\plugin\cache\ehcache\G
railsEhCacheManagerFactoryBean.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
I will try to see if there are higher version of that plugin. So far I am constricted to a nexus mirror repository for the most part, so I haven't been able to find a higher version to test.
I have the sample dependencies inside my pom.xml
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>cache-ehcache</artifactId>
<version>1.0.5</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>hibernate4</artifactId>
<version>4.3.8.1</version>
<scope>runtime</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>tomcat</artifactId>
<version>7.0.55.2</version>
<scope>provided</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>cache</artifactId>
<version>1.1.8</version>
<scope>compile</scope>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>cache-headers</artifactId>
<version>1.1.7</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>org.grails.plugins</groupId>
<artifactId>cached-resources</artifactId>
<version>1.1</version>
<type>zip</type>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.8.1</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
According to an open issue https://github.com/grails-plugins/grails-cache-ehcache/issues/41, it might be a possible bug, but no solution or work around was provided.
I am doing an upgrade from Grails 2.2.0 to 2.4.5, I have updated the Datasource.groovy to point out to the right hibernate4 ehCache class:
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
// cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider' //Outdated class
// http://grails-plugins.github.io/grails-cache-ehcache/guide/usage.html
cache.region.factory_class = 'grails.plugin.cache.ehcache.hibernate.BeanEhcacheRegionFactory' // For Hibernate before 4.0
cache.region.factory_class = 'grails.plugin.cache.ehcache.hibernate.BeanEhcacheRegionFactory4' // For Hibernate before 4.0 and higher
}
config.groovy:
/*https://github.com/grails/grails-core/releases/tag/v2.4.5
* ehcache 2.9.0 is more strict about the configuration.
* ehcache is used in the spring-security-core plugin for caching users.
* There is a problem reported as GRAILS-12120.
* As a workaround to the "net.sf.ehcache.CacheException:
* Another unnamed CacheManager already exists in the same VM.
* " error you can add this config to Config.groovy:*/
beans {
cacheManager {
shared = true
}
}
I am trying to understand where that MalformedObjectNameException: Invalid character ':' in value part of property is coming from since the project didn't configure any ehcache, it just used some classes from the cache plugin. Here is a sample cache service implementation below:
GrailsEhCacheCache not recognized by IntelliJ GrailsCacheManager not recognized by IntelliJ
import grails.plugin.cache.GrailsCacheManager
import grails.plugin.cache.ehcache.GrailsEhcacheCache
import org.springframework.transaction.annotation.Transactional
class ChatCacheService
{
static transactional = false
static final String CHAT_CACHE_NAME = Chat.canonicalName
static final String CHAT_HASHES_CACHE_NAME = "${CHAT_CACHE_NAME}.Hashes"
GrailsCacheManager grailsCacheManager
ChatMessageCacheService chatMessageCacheService
FilterService filterService
GrailsEhcacheCache getChatCache()
{
grailsCacheManager.getCache(CHAT_CACHE_NAME) as GrailsEhcacheCache
}
GrailsEhcacheCache getChatHashesCache()
{
grailsCacheManager.getCache(CHAT_HASHES_CACHE_NAME) as GrailsEhcacheCache
}
void addNewChat(String chatChannelName, Chat chat)
{
chatMessageCacheService.createChatMessageCache(chatChannelName, chatCache)
chat.channelName = chatChannelName
refreshChat(chatCache, chat)
}
void refreshChat(Chat chat)
{
refreshChat(chatCache, chat)
}
void refreshChat(GrailsEhcacheCache chatCache, Chat chat)
{
chat.updateChatTimestamp()
chatCache.put(chat.channelName, chat)
// >>> Chat Cache Event listener will update hash, except during initialization
}
void refreshChatHash(Chat chat)
{
ChatHash chatHash = chat.generateHashCode(chatMessageCacheService.getCacheChatMessages(chat.channelName))
chatHashesCache.put(chat.channelName, chatHash)
}
Chat retrieveChat(String chatChannelName)
{
Chat chat = chatCache.get(chatChannelName)?.get() as Chat
chat
}
synchronized Chat retrieveNonPurgeableChat(String chatChannelName)
{
Chat chat = retrieveChat(chatChannelName)
if (!chat)
{
addNewChat(chatChannelName, new NonPurgeableChat())
chat = retrieveChat(chatChannelName)
}
chat
}
List<ChatChatMessage> getCacheChatMessages(String channelName)
{
chatMessageCacheService.getCacheChatMessages(channelName) //.sort { -it.id }
}
ChatChatMessage addNewChatMessageCache(String channelName, ChatMessage chatMessage)
{
Chat chat = retrieveChat(channelName)
chatMessageCacheService.addNewChatMessageCacheToTop(channelName, chatMessage)
refreshChat(chat) // refresh chat
}
void removeChat(String chatChannelName)
{
GrailsEhcacheCache chatCache = grailsCacheManager.getCache(CHAT_CACHE_NAME) as GrailsEhcacheCache
chatCache.evict(chatChannelName)
chatMessageCacheService.destroy(chatChannelName)
}
#Transactional(readOnly = true)
List<Chat> retrieveAllGeneralAndGroupChats()
{
List<Chat> generalAndGroupChats = []
List<ChatMessageType> generalAndGroupChatTypes = [
ChatMessageType.findByDescription(ChatType.GROUP.name()),
ChatMessageType.findByDescription(ChatType.GENERAL.name())
]
chatCache.allKeys.each { key ->
Chat chat = (Chat) chatCache.get(key).get()
if (generalAndGroupChatTypes.find { it?.description == chat?.chatTypeDescription })
{
generalAndGroupChats.add(chat)
}
}
generalAndGroupChats
}
void purgeOldMessagesFromChats()
{
chatCache.allKeys.findAll { String channelName -> !ChatService.isEventChat(channelName) }.each { String chatChannelName ->
Chat chat = (Chat) chatCache.get(chatChannelName).get()
if (!(chat instanceof NonPurgeableChat))
{
if (chatMessageCacheService.purgeOldMessages(chatChannelName) > 0)
{
refreshChat(chatCache, chat)
}
}
}
}
String getChatCacheHash(String channelName)
{
((ChatHash) chatHashesCache.get(channelName)?.get())?.hash
}
String synchronizeChat(UserProfile userProfile, String chatChannelName, String chatTimestamp, String selectedFilter)
{
String response = null
Chat chatToSynchronize = retrieveChat(chatChannelName)
if (chatToSynchronize && (chatTimestamp != getChatCacheHash(chatToSynchronize.channelName) || filterChanged(userProfile, selectedFilter)))
{
response = chatToJson(chatToSynchronize, filterService.getCurrentFilterForUsername(userProfile?.userId), selectedFilter, userProfile)
}
response
}
Boolean filterChanged(UserProfile userProfile, String selectedFilter) {
Boolean filterChanged = Boolean.FALSE
if (userProfile && userProfile?.groupChatFilterOption != selectedFilter
&& (userProfile?.groupChatFilterOption == SOCTrackConstants.DASHBOARD_FILTER || selectedFilter == SOCTrackConstants.DASHBOARD_FILTER)) {
filterChanged = Boolean.TRUE
}
filterChanged
}
String chatToJson(Chat chat, List<EventFilter> userFilters, String selectedFilter, UserProfile userProfile)
{
List<ChatChatMessage> chatChatMessages = chatMessageCacheService.getCacheChatMessages(chat.channelName)
// Apply dashboard filters
if (selectedFilter == SOCTrackConstants.DASHBOARD_FILTER) {
chatChatMessages = chatChatMessages.findAll{ChatChatMessage chatMessage ->
includeChatMessage(chatMessage, userFilters)
}
}
Map<String, Collection<String>> chatMessagesAndTimestamp = [:]
chatMessagesAndTimestamp['messages'] = chatChatMessages.collect { ChatChatMessage chatMessage ->
chatMessage.messageAsHtml = chatMessage.messageAsHtmlClone
if (! userProfile?.shouldHighlightGroupMessage(chatMessage.id, chatMessage.enteredDate, chatMessage.messageType) ||
chatMessage.enteredBy.equals(userProfile?.userId)) {
chatMessage.messageAsHtml = chatMessage.messageAsHtml.replaceAll("groupChatUnreadHighlight","")
}
if(chatMessage.lastResponseId > 0) {
if (!userProfile?.shouldHighlightGroupMessage(chatMessage.lastResponseId, chatMessage.lastResponseDate, chatMessage.messageType) ||
chatMessage.lastResponseBy.equals(userProfile?.userId)) {
chatMessage.messageAsHtml = chatMessage.messageAsHtml.replaceAll("groupChatResponseUnreadHighlight", "")
}
}
chatMessage.messageAsHtml
}.findAll { it }
chatMessagesAndTimestamp['chatTimestamp'] = getChatCacheHash(chat.channelName) // chat.chatTimestamp
JSON messagesAsJson = new JSON(chatMessagesAndTimestamp)
messagesAsJson.toString()
}
Boolean includeChatMessage (ChatChatMessage chatChatMessage, List<EventFilter> userFilters) {
boolean displayRow = true
if (userFilters) { //at least one filter to satisfy
boolean satisfiedAllAndFilters
boolean satisfiedAnOrFilter
List<EventFilter> andFilters = userFilters.findAll { eventFilter ->
eventFilter.filterOperationType == FilterOperationType.AND
}
List<EventFilter> orFilters = userFilters.findAll { eventFilter ->
eventFilter.filterOperationType == FilterOperationType.OR
}
if (andFilters) {
satisfiedAllAndFilters = andFilters.collect { andFilter ->
andFilter.displayChatBasedOnFilter(chatChatMessage)
}.every{ it } //all 'AND' filters must be satisfied
}
if (orFilters) {
satisfiedAnOrFilter = orFilters.collect { orFilter ->
orFilter.displayChatBasedOnFilter(chatChatMessage)
}.any{ it } //at least one 'OR' filter must be satisfied
}
displayRow = satisfiedAllAndFilters || satisfiedAnOrFilter
}
displayRow
}
}
UPDATE: Custom Utility method used to createEHcache
synchronized static Cache createEhcache(String name, CacheManager cacheManager, CacheConfiguration baseCacheConfiguration, CacheEventListener cacheEventListener = null)
{
Ehcache ehcache
PersistenceConfiguration persistenceConfiguration
if (cacheManager.cacheExists(name))
{
ehcache = cacheManager.getCache(name)
ehcache.cacheConfiguration.overflowToDisk = false //overflowToDisk deprecated
// ehcache.cacheConfiguration.persistence(persistenceConfiguration.strategy("LOCALTEMPSWAP"))
ehcache.cacheConfiguration.diskPersistent = false // diskPersistent deprecated
// ehcache.cacheConfiguration.persistence(persistenceConfiguration.strategy("NONE"))
ehcache.cacheConfiguration.timeToLiveSeconds = 0
ehcache.cacheConfiguration.timeToIdleSeconds = 0
logger.warn "Cache $name already exists, configuration has been reset."
}
else
{
baseCacheConfiguration.name = name
// ehcache = new Cache(baseCacheConfiguration, null, null); //Runtime error (Ambiguous method overloading)
// RegisteredEventListeners registeredEventListeners = new RegisteredEventListeners(null);
// BootstrapCacheLoader bootstrapCacheLoader = new RMIBootstrapCacheLoader()
ehcache = new Cache(baseCacheConfiguration, null as RegisteredEventListeners, null as BootstrapCacheLoader)
cacheManager.addCache(ehcache)
cacheManager.cacheManagerPeerProviders?.get('RMI')?.registerPeer("${getEhcachePeerBaseUrl()}/$baseCacheConfiguration.name")
if (cacheEventListener)
{
ehcache.getCacheEventNotificationService().registerListener(cacheEventListener)
}
}
ehcache
}
Putting that line of code inside the Config.groovy file solved the issue and removed the exception: grails.cache.ehcache.cacheManagerName = 'default_grails_cache'.
Solution comes from https://github.com/grails-plugins/grails-cache-ehcache/issues/41#issuecomment-985049476.

Grails 4 with spring-security-oauth2-provider:4.0.0-RC1

I created a Grails 4.0.2 application with this plugins:
compile 'org.grails.plugins:spring-security-core:4.0.0'
compile 'org.grails.plugins:spring-security-oauth2-provider:4.0.0-RC1'
I followed the documentation: https://bluesliverx.github.io/grails-spring-security-oauth2-provider/v3/manual/index.html
After I'm trying to use the authentication by:
curl -X POST \
-d "client_id=my-client" \
-d "grant_type=password" \
-d "username=my-user" \
-d "password=my-password" \
-d "scope=read" http://localhost:8080/oauth/token
But I receive this error:
URI
/oauth/token
Class
java.lang.IllegalArgumentException
Message
There is no PasswordEncoder mapped for the id "null"
Trace
Line | Method
->> 244 | matches in org.springframework.security.crypto.password.DelegatingPasswordEncoder$UnmappedIdPasswordEncoder
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 198 | matches in org.springframework.security.crypto.password.DelegatingPasswordEncoder
| 90 | additionalAuthenticationChecks in org.springframework.security.authentication.dao.DaoAuthenticationProvider
| 166 | authenticate in org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider
| 175 | authenticate . . . . . . . . . in org.springframework.security.authentication.ProviderManager
| 123 | attemptAuthentication in org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter
| 212 | doFilter . . . . . . . . . . . in org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter
| 334 | doFilter in org.springframework.security.web.FilterChainProxy$VirtualFilterChain
| 105 | doFilter . . . . . . . . . . . in org.springframework.security.web.context.SecurityContextPersistenceFilter
| 334 | doFilter in org.springframework.security.web.FilterChainProxy$VirtualFilterChain
| 58 | doFilter . . . . . . . . . . . in grails.plugin.springsecurity.web.SecurityRequestHolderFilter
| 334 | doFilter in org.springframework.security.web.FilterChainProxy$VirtualFilterChain
| 215 | doFilterInternal . . . . . . . in org.springframework.security.web.FilterChainProxy
| 178 | doFilter in ''
| 193 | internalDoFilter .
I find this solution:
https://mkyong.com/spring-boot/spring-security-there-is-no-passwordencoder-mapped-for-the-id-null/
but I don't know how apply the solution on the grails project.
Anyone could help me?
Thank you,
Cristian
I too ran into this issue but I believe I found the answer.
Add this to the Client class that the oauth plugin init script generates:
static mapping = {
autowire true
}
Or add this to the runtime.groovy to enable service injection to all domain classes by default
grails-app/conf/runtime.groovy
grails.gorm.default.mapping = {
autowire true
}
As for the reason this is happneing. The Client Domain class tries to call this code before being inserted:
protected void encodeClientSecret() {
clientSecret = clientSecret ?: NO_CLIENT_SECRET
clientSecret = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(clientSecret) : clientSecret
}
But it fails to encode the password correctly since the spring security service is null.
The Grails documentation mentions that starting with Grails 3.3.0, services are not longer injected by default in Domain classes and need that mapping to be injected.
I temporary solved my question by setting in the resources.groovy
beans = {
userSecPasswordEncoderListener(UserSecPasswordEncoderListener)
passwordEncoder(NoOpPasswordEncoder) {
}

How can I retrieve the Geolocation from an IP address in Grails?

I want to retrieve the geolocation from an IP-address in a Grails app.
I tried hostip and geoip both raise exceptions and did not work for me. Is there any other way to get the geolocation?
When I use geoip I have:
config.groovy:
geoip.data.resource= "/WEB-INF/GeoLiteCity.dat"
geoip.data.cache="GEOIP_STANDARD"
In my controller:
GeoIpService geoIpService
index() {
def location = geoIpService.getLocation("85.176.52.75")
render location.countryName + " " + location.city
}
The exception is:
| Error 2013-07-26 14:04:22,236 [http-bio-8090-exec-1] ERROR
errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [GET] /test/home/index
Stacktrace follows:
Message: null
Line | Method
->> 199 | <init> in java.util.StringTokenizer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 221 | <init> in ''
| 624 | getLocationwithdnsservice in com.maxmind.geoip.LookupService
| 593 | getLocation in ''
| 42 | getLocation . . . . . . . in org.grails.geoip.service.GeoIpService
| 12 | index in test.HomeController
| 195 | 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
^ 722 | run . . . . . . . . . . . in java.lang.Thread
After downloading your sample grails app from github, and after debugging it for a while, I found out what the problem is. Well, there are 2 problems really:
Your configuration for the geoip plugin is incorrect
The documentation for the geoip plugin makes it look like the configuration you have is correct, when it is not.
If you take a look at the documentation for the plugin: http://grails.org/plugin/geoip you will see that it talks about the configuration for the geoip.data.cache as follows:
geoip.data.cache - There are 4 possible values for this:
0 - GEOIP_STANDARD
1 - GEOIP_MEMORY_CACHE
2 - GEOIP_CHECK_CACHE
4 - GEOIP_INDEX_CACHE
So what it is actually looking for is the integer values, not the strings beside them. For example, 0 is used for GEOIP_STANDARD, so you configure it with:
geoip.data.cache=0
When I changed the configuration of your sample app to the above, I no longer get the exceptions.

grails mail: inline images working on localhost and not in test environment

I'm adding inline images to my mails on localhost with:
inline 'footerImage', 'image/jpg', new File('./web-app/images/mailAssets/suchebottomre.gif').readBytes()
Which works fine.
When I deploy to my test environment I get this error:
Class
java.io.FileNotFoundException
Message
cannot use ./web-app/images/mailAssets/alert_header_pre.png as an attachment as it does not exist
with this log:
Line | Method
->> 331 | inline in grails.plugin.mail.MailMessageBuilder
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 20 | doCall in de.docinsider.web.NotifierService$_contactUser_closure1
| 39 | sendMail . in grails.plugin.mail.MailService
| 13 | contactUser in de.docinsider.web.NotifierService
| 7 | doCall . . in de.docinsider.web.SendController$_closure1
| 195 | 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
^ 722 | run in java.lang.Thread
How can this be avoided?
I also thaught about implementing a resourceloader with:
import org.springframework.context.ResourceLoaderAware
import org.springframework.core.io.ResourceLoader
class SendController implements ResourceLoaderAware {
#Autowired
ResourceLoader resourceLoader
def notifierService
def index() { }
def welcome = {
notifierService.contactUser(params.username, params.email, params.message)
render view:"/send/feedback", model:[name:params.username, message:params.message]
}
void setResourceLoader(ResourceLoader resourceLoader) {
resourceLoader = resourceLoader
}
}
This does also not work.
With:
inline 'headerImage', 'image/jpg', resourceLoader.getResource('/images/mailAssets/header_top.png')
inline 'footerImage', 'image/jpg', resourceLoader.getResource('/images/mailAssets/footer_bottom.gif')
In the service.
I know this is an old thread, however I bumped into this same issue and found out that the server does not know the real path to the image, instead it uses the string as real path "./web-app/images/mailAssets/alert_header_pre.png".
Reading this post will help you to get the real path.
Instead of:
inline 'footerImage', 'image/jpg', new File('./web-app/images/mailAssets/suchebottomre.gif').readBytes()
Use this:
inline 'footerImage', 'image/jpg', resourceLoader.getResource("/images/mailAssets/suchebottomre.gif").getFile()
You will need to import org.springframework.core.io.Resource or org.springframework.core.io.ResourceLoader and your controller implement implements org.springframework.context.ResourceLoaderAware and declare ResourceLoader resourceLoader
Tested on:
Prod server: glassfish.
Dev: Grails 2.3.7.

Grails 2.0.1 : async messaging: `jmsConnectionFactory` compilation error

I have resource.groovy
beans = {
jmsConnectionFactory(org.apache.activemq.ActiveMQConnectionFactory) { brokerURL = 'vm://localhost' }
}
and on run it says
Running Grails application
| Error 2012-02-24 18:02:13,490 [pool-6-thread-1] ERROR spring.GrailsRuntimeConfigurator - [RuntimeConfiguration] Unable to load beans from resources.groovy
Message: No such property: org for class: resources
Line | Method
->> 3 | doCall in resources$_run_closure1
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 736 | invokeBeanDefiningClosure in grails.spring.BeanBuilder
| 569 | beans . . . . . . . . . . in ''
| 736 | invokeBeanDefiningClosure in ''
| 569 | beans . . . . . . . . . . in ''
| 511 | invokeMethod in ''
| 303 | innerRun . . . . . . . . in java.util.concurrent.FutureTask$Sync
| 138 | run in java.util.concurrent.FutureTask
| 886 | runTask . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
| 908 | run in ''
^ 662 | run . . . . . . . . . . . in java.lang.Thread
| Error 2012-02-24 18:02:16,537 [pool-6-thread-1] ERROR context.GrailsContextLoader - Error executing bootstraps: Error creating bean with name 'delayedCreateMessageJmsListenerContainer': Cannot resolve reference to bean 'jmsConnectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'jmsConnectionFactory' is defined
Message: Error creating bean with name 'delayedCreateMessageJmsListenerContainer': Cannot resolve reference to bean 'jmsConnectionFactory' while setting bean property 'connectionFactory'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'jmsConnectionFactory' is defined
It worked all well before upgrade, after updating to 2.0.1 it failed with this error, I am using groovy compiler 1.8.6
I have always configured ActiveMQ in Grails as follows:
BuildConfig.groovy
dependencies {
compile 'org.apache.activemq:activemq-core:5.5.0'
}
resources.groovy
import org.springframework.jms.connection.SingleConnectionFactory
import org.apache.activemq.ActiveMQConnectionFactory
beans = {
jmsConnectionFactory(SingleConnectionFactory) {
targetConnectionFactory = { ActiveMQConnectionFactory cf ->
brokerURL = 'vm://localhost'
}
}
}
It may be a ClassNotFound error in disguise. Try adding an import statement:
import org.apache.activemq.ActiveMQConnectionFactory
and see if you get a ClassNotFoundError, if so then it's just a matter of tracking down the missing dependency.

Resources