Why Grails is using H2 instead of Oracle? - oracle

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.

Related

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 to register eureka client from Grails on eureka server in Spring boot

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

Grails custom validation message, error

I was trying to add a custom message to my validator like this:
static constraints = {
joining validator: { val, obj ->
if(val?.after(obj.birthday)) return 'joining.error'
}
}
Of course I adjusted the messages.properties file. I'm getting the following exception:
2015-04-30 16:52:27,253 [localhost-startStop-1] ERROR context.GrailsContextLoaderListener - Error initializing the application: No signature of method: usermanagement.UserRole.exists() is applicable for argument types: (null, java.lang.Long) values: [null, 1]
Possible solutions: exists(long, long), exists(java.io.Serializable), list(), first(), wait(), last()
Message: No signature of method: usermanagement.UserRole.exists() is applicable for argument types: (null, java.lang.Long) values: [null, 1]
Possible solutions: exists(long, long), exists(java.io.Serializable), list(), first(), wait(), last()
Line | Method
->> 92 | methodMissing in org.grails.datastore.gorm.GormStaticApi
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 86 | doCall in usermanagement.UserRole$__clinit__closure9$_closure14$_closure15
| 85 | doCall . . . . . . . . . . . . . in usermanagement.UserRole$__clinit__closure9$_closure14
| 44 | create in usermanagement.UserRole
| 19 | doCall . . . . . . . . . . . . . in BootStrap$_closure1
| 327 | evaluateEnvironmentSpecificBlock in grails.util.Environment
| 320 | executeForEnvironment . . . . . in ''
| 296 | executeForCurrentEnvironment in ''
| 266 | run . . . . . . . . . . . . . . in java.util.concurrent.FutureTask
| 1142 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 617 | run . . . . . . . . . . . . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run in java.lang.Thread
I dont really understand why there is a connection to usermanagement.UserRole.exists()?
EDIT: UserRole is generated by the SpringSecurity core Plugin
EDIT: Bootstrap.groovy:
import java.text.SimpleDateFormat
import usermanagement.*
class BootStrap {
def init = { servletContext ->
def adminRole = new Role(authority: 'ROLE_ADMIN').save(flush: true)
def userRole = new Role(authority: 'ROLE_USER').save(flush: true)
def birthday_sdf = new SimpleDateFormat("dd-M-yyyy hh:mm:ss")
def birthday_str = "31-08-1982 10:20:56"
def testUser = new User(username: 'me', password: 'password',
firstName: 'Adam', lastName: 'Administrator',
role: adminRole, email: 'test#gmail.com',
birthday: birthday_sdf.parse(birthday_str), joining: new Date())
testUser.save(flush: true)
UserRole.create testUser, adminRole, true
}
}
I just saw that the statement in the validator is wrong:
if(val?.after(obj.birthday)) return 'joining.error'
should be
if(!(val?.after(obj.birthday))) return 'joining.error'
Because of that the joining I set in the Bootstrap.groovy was not valid which should be the root of the problem.

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.

using grails with legacy database

I faced with problem of using Grails with legacy Oracle database. I have legacy table TARGETTYPES with primary key text column TARGETTYPECODE:
CREATE TABLE "TMS"."TARGETTYPES"
( "TARGETTYPECODE" VARCHAR2(100) NOT NULL ENABLE,
"TARGETTYPEDESCR" VARCHAR2(255 CHAR),
"ACTIVE" CHAR(1) DEFAULT 'Y' NOT NULL ENABLE,
CONSTRAINT "TARGETTYPES_PK" PRIMARY KEY ("TARGETTYPECODE")
)
I created grails domain class:
package tmsconf
class Targettypes {
static transients = ['Targettypecode']
void setTargettypecode(String Targettypecode) {
id = Targettypecode
}
String getTargettypecode() {
return Targettypecode
}
String targettypedescr
String active
static mapping = {
table 'TARGETTYPES'
version false
columns {
id generator:'assigned', column:"TARGETTYPECODE", type:'text'
}
}
static constraints = {
id()
targettypecode(size: 1..100, blank: false)
targettypedescr(size: 0..255)
active(size: 1..1, blank: false)
id(nullable: true)
}
String toString() {
return "${targettypecode}"
}
}
Also I created controller class:
package tmsconf
class TargettypesController {
def scaffold = true
}
Application has started successfully.
When I click on link tmsconf.TargettypesController I have error in console:
Error 2012-10-10 10:55:37,243 [http-bio-8080-exec-9] ERROR util.JDBCExceptionReporter - ORA-00918: column ambiguously defined
| Error 2012-10-10 10:55:37,305 [http-bio-8080-exec-9] ERROR errors.GrailsExceptionResolver - SQLSyntaxErrorException occurred when processing request: [GET] /TMSConf/targettypes/list
ORA-00918: column ambiguously defined
. Stacktrace follows:
Message: ORA-00918: column ambiguously defined
Line | Method
->> 445 | processError in oracle.jdbc.driver.T4CTTIoer
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 396 | processError in ''
| 879 | processError . . . . in oracle.jdbc.driver.T4C8Oall
| 450 | receive in oracle.jdbc.driver.T4CTTIfun
| 192 | doRPC . . . . . . . in ''
| 531 | doOALL in oracle.jdbc.driver.T4C8Oall
| 207 | doOall8 . . . . . . in oracle.jdbc.driver.T4CPreparedStatement
| 884 | executeForDescribe in ''
| 1167 | executeMaybeDescribe in oracle.jdbc.driver.OracleStatement
| 1289 | doExecuteWithTimeout in ''
| 3584 | executeInternal . . in oracle.jdbc.driver.OraclePreparedStatement
| 3628 | executeQuery in ''
| 1493 | executeQuery . . . . in oracle.jdbc.driver.OraclePreparedStatementWrapper
| 96 | executeQuery in org.apache.commons.dbcp.DelegatingPreparedStatement
| 55 | <init> . . . . . . . in grails.orm.PagedResultList
| 15 | list in tmsconf.TargettypesController
| 186 | 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
Please help, where am I wrong
This should work:
package tmsconf
class Targettypes {
String targettypecode
String targettypedescr
String active
static mapping = {
version false
id generator: 'assigned', name: 'targettypecode'
}
static constraints = {
targettypecode(size: 1..100, blank: false)
targettypedescr(size: 0..255, nullable: true)
active(size: 1..1, blank: false)
}
String toString() {
targettypecode
}
}
You can now use the name property in the mapping block, so creating a transient get/set pair to wrap the id isn't needed.
I also removed the table name and column name settings since they're set to what would be used anyway, and removed type:'text' since Hibernate knows the type of the field, so it can use that for the type of the column.
Also, I added nullable: true for targettypedescr based on the SQL you showed.
In general when you're trying to map to legacy databases, use the http://grails.org/doc/latest/ref/Command%20Line/schema-export.html script to look at what Hibernate thinks the tables should look like. Tweak the constraints and mapping blocks until it's "close enough".

Resources