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.
Related
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) {
}
I want to register my eureka client that is in Grails 2.4.4 on a eureka server which is in spring boot.
I already have registered another eureka service from spring boot on the same eureka server and it is working fine.
When I run grails app, it gives me an error :
| Error 2018-02-21 17:29:39,765 [localhost-startStop-1] ERROR aws.ConfigClusterResolver - Cannot resolve to any endpoints from provided configuration: {defaultZone=[]}
| Error 2018-02-21 17:29:39,771 [localhost-startStop-1] ERROR transport.EurekaHttpClients - Initial resolution of Eureka server endpoints failed. Check ConfigClusterResolver logs for more info
| Error 2018-02-21 17:29:39,841 [localhost-startStop-1] ERROR discovery.DiscoveryClient - DiscoveryClient_UNKNOWN/pawan - was unable to refresh its cache! status = There is no known eureka server; cluster server list is empty
Message: There is no known eureka server; cluster server list is empty
Line | Method
->> 107 | execute in com.netflix.discovery.shared.transport.decorator.RetryableEurekaHttpClient
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 134 | getApplications in com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator
| 137 | execute . . . . . . . . . . . . in com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator$6
| 77 | execute in com.netflix.discovery.shared.transport.decorator.SessionedEurekaHttpClient
| 134 | getApplications . . . . . . . . in com.netflix.discovery.shared.transport.decorator.EurekaHttpClientDecorator
| 1051 | getAndStoreFullRegistry in com.netflix.discovery.DiscoveryClient
| 965 | fetchRegistry . . . . . . . . . in ''
| 414 | <init> in ''
| 269 | <init> . . . . . . . . . . . . . in ''
| 265 | <init> in ''
| 257 | <init> . . . . . . . . . . . . . in ''
| 31 | initializeEurekaClient in EurekaConfiguration
| 20 | doCall . . . . . . . . . . . . . in BootStrap$_closure1
| 327 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 320 | executeForEnvironment . . . . . in ''
| 296 | executeForCurrentEnvironment in ''
| 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
Here is my application.properties file:
#Grails Metadata file
#Grails Metadata file
#Grails Metadata file
#Grails Metadata file
#Fri Jan 19 17:25:36 IST 2018
app.grails.version=2.4.4
app.name=GrailsMicroservice
app.version=0.1
#app.port=8080
eureka.region = default
eureka.vipAddress = localhost
eureka.port = 1116eureka.name=Grails-Service
eureka.hostname=localhost
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://localhost:1116/eureka/
Any help will be appriciable.
Thanks !
Here are my findings that I have applied to this issue. However, I did lots of search on google to get it right back on the track.
Step 1: Create a file named eureka-client.properties
Step 2: Now remove your configuration code from application.properties file and paste it into the newly created file.
Step 3: Pass your eureka port there and of course serviceId in this file.
Configuration CODE:
app.grails.version=2.4.4
app.name=GrailsMicroservice
app.version=0.1
#app.port=8080
eureka.region = default
eureka.vipAddress = localhost
eureka.port = 1116
eureka.name=Grails-Service
eureka.hostname=localhost
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://localhost:1116/eureka/
Now save the changes and run your application. It will connect to your Eureka server. After refreshing your Eureka home page, you will find it there.
Not sure if it's a TYPO in your question or a genuine error but the line eureka.port = 1116eureka.name=Grails-Service should be:
eureka.port = 1116
eureka.name=Grails-Service
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).
I have spent a lot of time to resolve this problem. I'm begginer in GRAILS and GROOVY.
I have legacy oracle database schema named "tms_dev". This schema has some tables (for example checktypes table). Also I have domain class Checktype and ChecktypesController class - controller generated by GRAILS.
This class has list method:
def list(Integer max) {
params.max = Math.min(max ?: 10, 100)
[checktypesInstanceList: Checktypes.list(params), checktypesInstanceTotal: Checktypes.count()]
}
Also I configured Datasource.groovy file to work with oracle with such contents
dataSource {
pooled = true
driverClassName = "oracle.jdbc.OracleDriver"
dialect = "org.hibernate.dialect.Oracle10gDialect"
username = "TMS_DEV"
password = "password"
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = false
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory'
}
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop','update'
url = "jdbc:oracle:thin:#server_name:1522:sid_name"
}
}
production {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop','update'
url = "jdbc:oracle:thin:#server_name:1522:sid_name"
}
}
I run my application. And click "tst7.ChecktypesController" refence on the main page.
As a result I have exception:
| Error 2012-08-27 14:41:03,469 [http-bio-8080-exec-9] ERROR util.JDBCExceptionReporter - Table "CHECKTYPES" not found; SQL statement:
select * from ( select this_.CHECKTYPECODE as CHECKTYP1_21_0_, this_.active as active21_0_, this_.availabilitychecktype as availabi3_21_0_, this_.checktypecode as checktyp1_21_0_, this_.checktypedescr as checktyp4_21_0_, this_.TARGETTYPECODE as TARGETTY5_21_0_ from CHECKTYPES this_ ) where rownum <= ? [42102-164]
| Error 2012-08-27 14:41:03,547 [http-bio-8080-exec-9] ERROR errors.GrailsExceptionResolver - JdbcSQLException occurred when processing request: [GET] /Tst7/checktypes/list
Table "CHECKTYPES" not found; SQL statement:
select * from ( select this_.CHECKTYPECODE as CHECKTYP1_21_0_, this_.active as active21_0_, this_.availabilitychecktype as availabi3_21_0_, this_.checktypecode as checktyp1_21_0_, this_.checktypedescr as checktyp4_21_0_, this_.TARGETTYPECODE as TARGETTY5_21_0_ from CHECKTYPES this_ ) where rownum <= ? [42102-164]. Stacktrace follows:
Message: Table "CHECKTYPES" not found; SQL statement:
select * from ( select this_.CHECKTYPECODE as CHECKTYP1_21_0_, this_.active as active21_0_, this_.availabilitychecktype as availabi3_21_0_, this_.checktypecode as checktyp1_21_0_, this_.checktypedescr as checktyp4_21_0_, this_.TARGETTYPECODE as TARGETTY5_21_0_ from CHECKTYPES this_ ) where rownum <= ? [42102-164]
Line | Method
->> 329 | getJdbcSQLException in org.h2.message.DbException
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 169 | get in ''
| 146 | get . . . . . . . . . . . in ''
| 4753 | readTableOrView in org.h2.command.Parser
| 1080 | readTableFilter . . . . . in ''
| 1686 | parseSelectSimpleFromPart in ''
| 1793 | parseSelectSimple . . . . in ''
| 1680 | parseSelectSub in ''
| 1523 | parseSelectUnion . . . . in ''
| 1022 | readTableFilter in ''
| 1686 | parseSelectSimpleFromPart in ''
| 1793 | parseSelectSimple in ''
| 1680 | parseSelectSub . . . . . in ''
| 1523 | parseSelectUnion in ''
| 1511 | parseSelect . . . . . . . in ''
| 405 | parsePrepared in ''
| 279 | parse . . . . . . . . . . in ''
| 251 | parse in ''
| 217 | prepareCommand . . . . . in ''
| 415 | prepareLocal in org.h2.engine.Session
| 364 | prepareCommand . . . . . in ''
| 1121 | prepareCommand in org.h2.jdbc.JdbcConnection
| 71 | <init> . . . . . . . . . in org.h2.jdbc.JdbcPreparedStatement
| 267 | prepareStatement in org.h2.jdbc.JdbcConnection
| 281 | prepareStatement . . . . in org.apache.commons.dbcp.DelegatingConnection
| 313 | prepareStatement in org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper
| 55 | <init> . . . . . . . . . in grails.orm.PagedResultList
| 45 | list in tst7.ChecktypesController
| 195 | doFilter . . . . . . . . in grails.plugin.cache.web.filter.PageFragmentCachingFilter
| 63 | doFilter in grails.plugin.cache.web.filter.AbstractFilter
| 1110 | runWorker . . . . . . . . in java.util.concurrent.ThreadPoolExecutor
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . . . . . . . . . in java.lang.Thread
Then I tried to create direct Oracle connection in list method
def list(Integer max) {
def sql = Sql.newInstance("jdbc:oracle:thin:#server_name:1522:instance_name", "TMS_DEV",
"password", "oracle.jdbc.driver.OracleDriver")
sql.eachRow("select * from Dbdrivers"){
println it.dbdrivercode
}
}
Than I run application. As result println it.dbdrivercode - works fine (CONNECTION WORKS!!!).
Most strange in this problem is that exception is generated by h2 (H2 in memory database) class (org.h2.jdbc.JdbcConnection
,org.h2.jdbc.JdbcConnection
and so on).
You are defaulting to the H2 driver because your production and development blocks are being ignored when outside an environments block.
sounds like application cache issue. try running grails clean before running the app.
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.