Grails, Jobs, Static Helper Methods and Hibernate Session - java

I have a Grails job-class (grails-app/jobs) who needs to call a static (helper) method (defined in src/groovy). This method calls get- and find-methods respectively on 2 different domain-objects. The result of the method call is returning a simple String (could return anything for that sake - doesn't matter).
My question is, how do I use .withTransaction or .withSession in the job-class when I'm calling a static method containing fetch of 2 (could be more) different domain-classes?
Or, how do I declare/use a Hibernate session in a job-class so that I don't have to use .withBlaBla?
EDIT (another EDIT at the bottom - sorry):
The lines where EZTable and EZRow is fetched is working. EmailReminder I had to wrap with EmailReminder.with... Now the lines with call to ServiceUtils.handleSubjectOrMessageString(ezTable, ezRow, emailReminder.subject) are causing an exception (this is added "now" - the entire job-class was working earlier with simple String-values).
class EmailReminderJob implements Job {
EmailReminder emailReminder
EZTable ezTable
EZRow ezRow
static triggers = {}
def void execute(JobExecutionContext context) {
List<String> emails = new ArrayList<String>(0)
ezTable = EZTable.get(new Long(context.mergedJobDataMap.get('ezTableId')))
ezRow = EZRow.get(new Long(context.mergedJobDataMap.get('ezRowId')))
EmailReminder.withTransaction { status ->
emailReminder = EmailReminder.get(new Long(context.mergedJobDataMap.get('emailReminderId')))
if(emailReminder.sendMessageToOwnerUser && emailReminder.ownerUser.email!=null)
emails.add(emailReminder.ownerUser.email)
if(emailReminder.sendMessageToOwnerCompany && emailReminder.ownerCompany.email!=null)
emails.add(emailReminder.ownerCompany.email)
if(emailReminder.emails!=null && emails.size()>0)
emails.addAll(new ArrayList<String>(emailReminder.emails))
if(emailReminder.messageReceiverUsers!=null && emailReminder.messageReceiverUsers.size()>0) {
for(user in emailReminder.messageReceiverUsers) {
if(user.email!=null)
emails.add(user.email)
}
}
}
if(emails.size()>0) {
String host = "localhost";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);
Session session = Session.getDefaultInstance(properties);
try{
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(emailReminder.emailFrom));
for(email in emails) {
message.addRecipient(
Message.RecipientType.TO,
new InternetAddress(email)
);
}
message.setSubject(ServiceUtils.handleSubjectOrMessageString(ezTable, ezRow, emailReminder.subject));
message.setText(ServiceUtils.handleSubjectOrMessageString(ezTable, ezRow, emailReminder.definedMessage));
Transport.send(message);
}catch (MessagingException mex) {
mex.printStackTrace();
}
}
}
}
The static-method in my util-class under src/groove (the line EZColumn ezcolumn = EZColumn.get(id) and the next are causing the exception):
def static String handleSubjectOrMessageString(EZTable eztable, EZRow ezrow, String subjectOrMessage) {
String regex = '(?<=\\$\\$)(.*?)(?=\\$\\$)'
Pattern pattern = Pattern.compile(regex)
Matcher matcher = pattern.matcher(subjectOrMessage)
StringBuffer stringBuffer = new StringBuffer();
while(matcher.find()) {
if(subjectOrMessage.substring(matcher.start(), matcher.end()).contains('#')) {
String stringId = subjectOrMessage.substring(matcher.start(), matcher.end()).split('#')[0]
String name = subjectOrMessage.substring(matcher.start(), matcher.end()).split('#')[1]
try {
Long id = new Long(stringId)
EZColumn ezcolumn = EZColumn.get(id)
EZCell ezcell = EZCell.findByEzTableAndEzRowAndEzColumn(eztable, ezrow, ezcolumn)
matcher.appendReplacement(stringBuffer, fetchCellValues(ezcell, ezcolumn))
} catch(NumberFormatException nfe) {
if(stringId.equals("id")) {
if(name.equals("row"))
matcher.appendReplacement(stringBuffer, ezrow.id.toString())
else if(name.equals("table"))
matcher.appendReplacement(stringBuffer, eztable.id.toString())
else
matcher.appendReplacement(stringBuffer, "???")
}
}
}
}
matcher.appendTail(stringBuffer);
println stringBuffer.toString().replaceAll('\\$', "")
return stringBuffer.toString().replaceAll('\\$', "")
}
The exception:
| Error 2015-02-11 10:33:33,954 [quartzScheduler_Worker-1] ERROR core.JobRunShell - Job EmailReminderGroup.ER_3_EZTable_3 threw an unhandled Exception:
Message: null
Line | Method
->> 202 | run in org.quartz.core.JobRunShell
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 573 | run in org.quartz.simpl.SimpleThreadPool$WorkerThread
| Error 2015-02-11 10:33:33,996 [quartzScheduler_Worker-1] ERROR core.ErrorLogger - Job (EmailReminderGroup.ER_3_EZTable_3 threw an exception.
Message: Job threw an unhandled exception.
Line | Method
->> 213 | run in org.quartz.core.JobRunShell
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 573 | run in org.quartz.simpl.SimpleThreadPool$WorkerThread
Caused by NullPointerException: null
->> 202 | run in org.quartz.core.JobRunShell
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 573 | run in org.quartz.simpl.SimpleThreadPool$WorkerThread
| Error 2015-02-11 10:33:34,005 [quartzScheduler_Worker-1] ERROR listeners.ExceptionPrinterJobListener - Exception occurred in job: null
Message: org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: java.lang.NullPointerException]
Line | Method
->> 218 | run in org.quartz.core.JobRunShell
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 573 | run in org.quartz.simpl.SimpleThreadPool$WorkerThread
Caused by SchedulerException: Job threw an unhandled exception.
->> 213 | run in org.quartz.core.JobRunShell
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 573 | run in org.quartz.simpl.SimpleThreadPool$WorkerThread
Caused by NullPointerException: null
->> 202 | run in org.quartz.core.JobRunShell
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
^ 573 | run in org.quartz.simpl.SimpleThreadPool$WorkerThread
EDIT AGAIN :( :
I have many nested calls in my static method (fetchCellValues(ezcell, ezcolumn) in the matcher.appendReplacement(stringBuffer, fetchCellValues(ezcell, ezcolumn))-method is calling deeper to fetch values and I actually get a "no Session"-exception at one call (call regular as all the other calls trying to fetch another domain-object):
Message: org.quartz.SchedulerException: Job threw an unhandled exception. [See nested exception: org.hibernate.LazyInitializationException: could not initialize proxy - no Session]

You use them like you would anywhere. Both are independent of the class they're called on; withTransaction just runs the wrapped code in a transaction, joining a current active transaction if there is one, and withSession makes the current Hibernate Session available to the wrapped code but otherwise doesn't do anything.
You don't indicate any reason for needing either, so it's not obvious what to advise specifically. You don't need a transaction if you're only reading data, and if you're calling domain class methods you shouldn't need access to the session.
One use for withTransaction that I've advocated in the past (pretty much the only use for it since it's typically misused) is to avoid lazy loading exceptions when there isn't an active session already. Wrapping code in a withTransaction block has the side effect of creating a session and keeping it open for the duration of the block and that lets you work with lazy-loaded instances and collections. Controllers have an active session because there's an open-session-in-view interceptor that starts a session at the beginning of the request, stores it in a ThreadLocal, and flushes and closes it at the end of the request. Jobs are similar because the plugin uses Quartz job start/end events to do the same thing.
But whether you are making your code transactional because of lazy loading or because you're updating, you should usually be doing the work in a transactional service.
Services are great for transactional work because they're transactional by default (only services that have no #Transactional annotations and include static transactional = false are non-transactional), and it's easy to configure transaction demarcation per-class and per-method with the #Transactional annotation. They are also great for encapsulating business logic, independent of how they're called; there's usually no need for a service method to have any HTTP/Job/etc. awareness, just pass it the data needed in String/number/boolean/object arguments and let it do its work.
I like to keep controllers simple, doing data binding from the request params and calling services to do the real work, then rendering a response or routing to the next page, and I do the same thing in Quartz jobs. Use Quartz for its scheduling functionality, but do the real work in a service. Dependency-inject the service like any bean (def fooService) and put all of the business logic and database work there. It keeps things cleanly delineated in the code, and makes testing easier since you can test the service methods without having to mock HTTP calls or Quartz.

Related

Spring 5 webclient with jetty connector continues to run after main completes execution

I am trying to test rest api by Spring 5 webclient with jetty connector. I am getting data from api call but main program continues to run even after main completes execution. How to resolve the issue.? What configuration needed so that Jetty connector stops after main completes its execution?
My connector initialization code:
SslContextFactory.Client sslContextFactory = new SslContextFactory.Client();
HttpClient httpClient = new HttpClient();
httpClient.setIdleTimeout(DefaultIdleTimeout);
ClientHttpConnector clientConnector = new JettyClientHttpConnector(httpClient, jettyResourceFactory);
webClient = WebClient.builder().baseUrl(getBaseUrl()).clientConnector(clientConnector).build();
Using webclient in main class :
webClient.get().uri("/getUri").exchange().flatMap(response.bodyToMono(String.class)).subscribe(di -> {
System.out.println(di);
}, error -> {
System.out.println(error.getStackTrace());
}, () -> {
System.out.println("Execution complete");
});
getting below in log:
13:39:11.225 [HttpClient#1165b38-scheduler-1] DEBUG org.eclipse.jetty.io.AbstractConnection - HttpConnectionOverHTTP#4eb423a5::DecryptedEndPoint#4345fb54{<hostname>/<targetIp>:443<->/<sourceIp>:65106,CLOSED,fill=-,flush=-,to=15016/15000} onFillInterestedFailed {}
13:39:11.225 [HttpClient#1165b38-scheduler-1] DEBUG org.eclipse.jetty.io.ManagedSelector - Wakeup ManagedSelector#75ed9710{STARTED} id=1 keys=0 selected=0 updates=0
13:39:11.226 [HttpClient#1165b38-24] DEBUG org.eclipse.jetty.io.ManagedSelector - Selector sun.nio.ch.WindowsSelectorImpl#3d003adb woken with none selected
13:39:11.226 [HttpClient#1165b38-scheduler-1] DEBUG org.eclipse.jetty.util.thread.QueuedThreadPool - queue org.eclipse.jetty.io.ManagedSelector$DestroyEndPoint#74c9b13c startThread=0
13:39:11.226 [HttpClient#1165b38-24] DEBUG org.eclipse.jetty.io.ManagedSelector - Selector sun.nio.ch.WindowsSelectorImpl#3d003adb woken up from select, 0/0/0 selected
13:39:11.226 [HttpClient#1165b38-scheduler-1] DEBUG org.eclipse.jetty.io.FillInterest - onClose FillInterest#52ac96eb{null}
13:39:11.226 [HttpClient#1165b38-21] DEBUG org.eclipse.jetty.util.thread.QueuedThreadPool - run org.eclipse.jetty.io.ManagedSelector$DestroyEndPoint#74c9b13c in QueuedThreadPool[HttpClient#1165b38]#45efc20d{STARTED,8<=8<=200,i=1,r=8,q=0}[ReservedThreadExecutor#4bef0fe3{s=2/8,p=0}]
13:39:11.226 [HttpClient#1165b38-scheduler-1] DEBUG org.eclipse.jetty.client.http.HttpConnectionOverHTTP - Closed HttpConnectionOverHTTP#4eb423a5::DecryptedEndPoint#4345fb54{<hostname>/<targetIp>:443<->/<sourceIp>:65106,CLOSED,fill=-,flush=-,to=15017/15000}
13:39:11.226 [HttpClient#1165b38-24] DEBUG org.eclipse.jetty.io.ManagedSelector - Selector sun.nio.ch.WindowsSelectorImpl#3d003adb processing 0 keys, 0 updates
13:39:11.226 [HttpClient#1165b38-24] DEBUG org.eclipse.jetty.io.ManagedSelector - updateable 0
13:39:11.226 [HttpClient#1165b38-24] DEBUG org.eclipse.jetty.io.ManagedSelector - updates 0
13:39:11.226 [HttpClient#1165b38-24] DEBUG org.eclipse.jetty.io.ManagedSelector - Selector sun.nio.ch.WindowsSelectorImpl#3d003adb waiting with 0 keys
13:39:11.226 [HttpClient#1165b38-21] DEBUG org.eclipse.jetty.io.ManagedSelector - Destroyed SocketChannelEndPoint#7a9db40c{<hostname>/<targetIp>:443<->/<sourceIp>:65106,CLOSED,fill=-,flush=-,to=0/15000}{io=0/0,kio=-1,kro=-1}->SslConnection#53046985{NEED_UNWRAP,eio=-1/-1,di=-1,fill=IDLE,flush=IDLE}~>DecryptedEndPoint#4345fb54{<hostname>/<targetIp>:443<->/<sourceIp>:65106,CLOSED,fill=-,flush=-,to=15017/15000}=>HttpConnectionOverHTTP#4eb423a5(l:/<sourceIp>:65106 <-> r:<hostname>/<targetIp>:443,closed=true)=>HttpChannelOverHTTP#7dafb76e(exchange=null)[send=HttpSenderOverHTTP#4491419(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#22805291{s=START}],recv=HttpReceiverOverHTTP#52385f05(rsp=IDLE,failure=null)[HttpParser{s=START,0 of -1}]]
13:39:11.227 [HttpClient#1165b38-21] DEBUG org.eclipse.jetty.io.AbstractConnection - onClose HttpConnectionOverHTTP#4eb423a5::DecryptedEndPoint#4345fb54{<hostname>/<targetIp>:443<->/<sourceIp>:65106,CLOSED,fill=-,flush=-,to=15018/15000}
13:39:11.227 [HttpClient#1165b38-21] DEBUG org.eclipse.jetty.io.AbstractConnection - onClose SslConnection#53046985::SocketChannelEndPoint#7a9db40c{<hostname>/<targetIp>:443<->/<sourceIp>:65106,CLOSED,fill=-,flush=-,to=0/15000}{io=0/0,kio=-1,kro=-1}->SslConnection#53046985{NEED_UNWRAP,eio=-1/-1,di=-1,fill=IDLE,flush=IDLE}~>DecryptedEndPoint#4345fb54{<hostname>/<targetIp>:443<->/<sourceIp>:65106,CLOSED,fill=-,flush=-,to=15018/15000}=>HttpConnectionOverHTTP#4eb423a5(l:/<sourceIp>:65106 <-> r:<hostname>/<targetIp>:443,closed=true)=>HttpChannelOverHTTP#7dafb76e(exchange=null)[send=HttpSenderOverHTTP#4491419(req=QUEUED,snd=COMPLETED,failure=null)[HttpGenerator#22805291{s=START}],recv=HttpReceiverOverHTTP#52385f05(rsp=IDLE,failure=null)[HttpParser{s=START,0 of -1}]]
13:39:11.227 [HttpClient#1165b38-21] DEBUG org.eclipse.jetty.util.thread.QueuedThreadPool - ran org.eclipse.jetty.io.ManagedSelector$DestroyEndPoint#74c9b13c in QueuedThreadPool[HttpClient#1165b38]#45efc20d{STARTED,8<=8<=200,i=1,r=8,q=0}[ReservedThreadExecutor#4bef0fe3{s=2/8,p=0}]
and continue to get log in console & program continues to run..................................
Taken from the official docs
https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder-jetty
You can share resources between multiple instances of the Jetty client (and server) and ensure that the resources are shut down when the Spring ApplicationContext is closed by declaring a Spring-managed bean of type JettyResourceFactory
Your JettyHttpClientConnector should be instantiated with a jettyResourceFactory bean whose lifecycle should end as the test ends.

Hygieia JIRA Collector NullPointerException

I tried to include our JIRA to Hygieia Dashboard. But I always get a NPE in Jira-Collector.
This is the log-file:
hygieia-jira | 2016-05-10 08:27:06,304 ERROR c.c.d.c.s.FeatureDataClientSetupImpl - Unexpected error in Jira paging request of java.lang.NullPointerException
hygieia-jira | [null]
And the docker-compose settings:
hygieia-jira-feature-collector:
image: hygieia-jira-feature-collector:latest
container_name: hygieia-jira
volumes:
- ./logs:/hygieia/logs
links:
- mongodb:mongo
- hygieia-api
environment:
- JIRA_BASE_URL=https://our-jira.com/tracker/base64
- JIRA_CREDENTIALS=b2ZhMmFidDpibsdfGlkbWlsdfzYWfsfdub37527lpbmc=
- JIRA_ISSUE_TYPE_ID=267
- JIRA_SPRINT_DATA_FIELD_NAME=customfield_14290
- JIRA_EPIC_FIELD_NAME=customfield_15590

Spring Data java.lang.NoSuchMethodError in grails

I am using mongo db plugin and spring-data-neo4j in my grails application.
I am using latest version of SDN and mongo db plugin.
Here is my buildconfig :
grails.servlet.version = "3.0" // Change depending on target container compliance (2.5 or 3.0)
grails.project.class.dir = "target/classes"
grails.project.test.class.dir = "target/test-classes"
grails.project.test.reports.dir = "target/test-reports"
grails.project.work.dir = "target/work"
grails.project.target.level = 1.6
grails.project.source.level = 1.6
//grails.project.war.file = "target/${appName}-${appVersion}.war"
grails.server.port.http = 1111
grails.project.fork = [
// configure settings for compilation JVM, note that if you alter the Groovy version forked compilation is required
// compile: [maxMemory: 256, minMemory: 64, debug: false, maxPerm: 256, daemon:true],
// configure settings for the test-app JVM, uses the daemon by default
test: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, daemon:true],
// configure settings for the run-app JVM
run: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
// configure settings for the run-war JVM
war: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256, forkReserve:false],
// configure settings for the Console UI JVM
console: [maxMemory: 768, minMemory: 64, debug: false, maxPerm: 256]
]
grails.project.dependency.resolver = "maven" // or ivy
grails.project.dependency.resolution = {
// inherit Grails' default dependencies
inherits("global") {
// specify dependency exclusions here; for example, uncomment this to disable ehcache:
// excludes 'ehcache'
}
log "error" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
checksums true // Whether to verify checksums on resolve
legacyResolve false // whether to do a secondary resolve on plugin installation, not advised and here for backwards compatibility
repositories {
inherits true // Whether to inherit repository definitions from plugins
grailsPlugins()
grailsHome()
mavenLocal()
grailsCentral()
mavenCentral()
// uncomment these (or add new ones) to enable remote dependency resolution from public Maven repositories
//mavenRepo "http://repository.codehaus.org"
//mavenRepo "http://download.java.net/maven/2/"
//mavenRepo "http://repository.jboss.com/maven2/"
}
dependencies {
// specify dependencies here under either 'build', 'compile', 'runtime', 'test' or 'provided' scopes e.g.
// runtime 'mysql:mysql-connector-java:5.1.29'
// runtime 'org.postgresql:postgresql:9.3-1101-jdbc41'
test "org.grails:grails-datastore-test-support:1.0-grails-2.4"
compile 'org.springframework.data:spring-data-neo4j-rest:3.2.0.RELEASE'
}
plugins {
// plugins for the build system only
build ":tomcat:7.0.55"
// plugins for the compile step
compile ":scaffolding:2.1.2"
compile ':cache:1.1.7'
compile ":asset-pipeline:1.9.6"
// plugins needed at runtime but not for compilation
runtime ":hibernate4:4.3.5.5" // or ":hibernate:3.6.10.17"
runtime ":database-migration:1.4.0"
runtime ":jquery:1.11.1"
compile ":mongodb:3.0.2"
// Uncomment these to enable additional asset-pipeline capabilities
//compile ":sass-asset-pipeline:1.9.0"
//compile ":less-asset-pipeline:1.10.0"
//compile ":coffee-asset-pipeline:1.8.0"
//compile ":handlebars-asset-pipeline:1.3.0.3"
}
}
With this configuration i am getting following error :
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 'mongoTransactionManager' while setting constructor argument with key [1]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTransactionManager': Cannot resolve reference to bean 'mongoDatastore' while setting bean property 'datastore'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDatastore': FactoryBean threw exception on object creation; nested exception is java.lang.NoSuchMethodError: org.springframework.data.util.ClassTypeInformation.from(Ljava/lang/Class;)Lorg/springframework/data/util/TypeInformation;
Line | Method
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1146 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 701 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'mongoTransactionManager' while setting constructor argument with key [1]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoTransactionManager': Cannot resolve reference to bean 'mongoDatastore' while setting bean property 'datastore'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDatastore': FactoryBean threw exception on object creation; nested exception is java.lang.NoSuchMethodError: org.springframework.data.util.ClassTypeInformation.from(Ljava/lang/Class;)Lorg/springframework/data/util/TypeInformation;
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1146 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 701 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'mongoTransactionManager': Cannot resolve reference to bean 'mongoDatastore' while setting bean property 'datastore'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoDatastore': FactoryBean threw exception on object creation; nested exception is java.lang.NoSuchMethodError: org.springframework.data.util.ClassTypeInformation.from(Ljava/lang/Class;)Lorg/springframework/data/util/TypeInformation;
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1146 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 701 | run . . . in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'mongoDatastore': FactoryBean threw exception on object creation; nested exception is java.lang.NoSuchMethodError: org.springframework.data.util.ClassTypeInformation.from(Ljava/lang/Class;)Lorg/springframework/data/util/TypeInformation;
->> 334 | innerRun in java.util.concurrent.FutureTask$Sync
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 166 | run in java.util.concurrent.FutureTask
| 1146 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 701 | run . . . in java.lang.Thread
Caused by NoSuchMethodError: org.springframework.data.util.ClassTypeInformation.from(Ljava/lang/Class;)Lorg/springframework/data/util/TypeInformation;
->> 255 | createMongoTemplate in org.grails.datastore.mapping.mongo.MongoDatastore
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 221 | afterPropertiesSet in ''
| 54 | getObject in org.grails.datastore.gorm.mongo.bean.factory.MongoDatastoreFactoryBean
| 334 | innerRun in java.util.concurrent.FutureTask$Sync
| 166 | run . . . in java.util.concurrent.FutureTask
| 1146 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^ 701 | run in java.lang.Thread
I am using grails 2.4.3 and groovy 2.3.

Grails dynamic scaffolding error

I am new to Grails, I installed Grails 2.4 on Ubuntu 14.04
I have this Grails Domain:
class EndUser {
String username
String password
String fullName
String toString() {
"$fullName"
}
static hasMany = [projects: Project, tasks: Task]
static constraints = {
fullName()
username()
password()
}
}
and it's controller:
class EndUserController {
static scaffold = true
def index = {
// redirect(action: "list")
}
}
I am getting the error below, and everytime i create a new EndUser, I am getting an error page showing this message:
Error 500: Internal Server Error
URI
/ProjectTracker/endUser/create
Class
java.lang.NullPointerException
Message
null
What did I do wrong? and how can I fix it?
Please let me know if I need to provide more info.
|Running Grails application
|Server running. Browse to http://localhost:8080/ProjectTracker
| Error 2014-06-09 01:59:47,663 [http-bio-8080-exec-7] ERROR errors.GrailsExceptionResolver - NullPointerException occurred when processing request: [GET] /ProjectTracker/endUser/edit/1
Stacktrace follows:
Message: Error processing GroovyPageView: Error executing tag <g:form>: Error executing tag <g:render>: null
Line | Method
->> 527 | doFilter in /endUser/edit
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Caused by GrailsTagException: Error executing tag <g:form>: Error executing tag <g:render>: null
->> 38 | doCall in /endUser/edit
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Caused by GrailsTagException: Error executing tag <g:render>: null
->> 33 | doCall in /endUser/edit
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Caused by NullPointerException: null
->> 333 | hash in java.util.concurrent.ConcurrentHashMap
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 988 | get in ''
| 141 | getValue in grails.util.CacheEntry
| 81 | getValue in ''
| 33 | doCall . in endUser_edit$_run_closure2_closure27
| 38 | doCall in endUser_edit$_run_closure2
| 40 | run . . . in endUser_edit
| 189 | 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
^ 745 | run in java.lang.Thread
Thanks,
Khalil.
It looks like you hit this bug: https://jira.grails.org/browse/GRAILS-11430. It will be fixed in Grails 2.4.1; you can either wait until that version is released or try the workaround provided in the comments of that link, which has been reported to work.

Stripes ActionBean event always resolve to default event

I am using cleanurls formatted like /View/{arg1}/{arg2}/{$event}.
ActionBeanView has multiple events. However irrespective of which event I invoke from browser, this always gets resolved to the default event.
Any ideas what am I doing wrong (fairly new to Stripes).
Here is the error log:
11:24:18,497 DEBUG UrlBindingFactory:145 - Matched /View/myarg1/myarg2/ADD.action to [/View/{id}/{asof}/{$event}]
11:24:18,497 DEBUG ExecutionContext:150 - Transitioning to lifecycle stage Reque
stInit
11:24:18,497 DEBUG ExecutionContext:150 - Transitioning to lifecycle stage Actio
nBeanResolution
11:24:18,497 DEBUG UrlBindingFactory:145 - Matched /View/myarg1/myarg2/ADD.action to [/View/{id}/{asof}/{$event}]
11:24:18,497 DEBUG UrlBindingFactory:145 - Matched /View/myarg1/myarg2/ADD.action to [/View/{id}/{asof}/{$event}]
11:24:18,497 DEBUG ExecutionContext:150 - Transitioning to lifecycle stage Handl
erResolution
11:24:18,497 DEBUG UrlBindingFactory:145 - Matched /View/myarg1/myarg2/ADD.action to [/View/{id}/{asof}/{$event}]
11:24:18,497 DEBUG DispatcherHelper:184 - Resolved event: myDefaultEvent; will invoke:
ViewActionBean.myDefaultEvent()
11:24:18,497 DEBUG ExecutionContext:150 - Transitioning to lifecycle stage Bindi
ngAndValidation
11:24:18,497 DEBUG DefaultActionBeanPropertyBinder:453 - Running required field
validation on bean class www.ViewActionBean
11:24:18,497 DEBUG DefaultActionBeanPropertyBinder:779 - Converting 1 value(s) u
sing converter net.sourceforge.stripes.validation.StringTypeConverter
11:24:18,513 DEBUG DefaultActionBeanPropertyBinder:779 - Converting 1 value(s) u
sing converter net.sourceforge.stripes.validation.StringTypeConverter
11:24:18,513 DEBUG DefaultActionBeanPropertyBinder:282 - Could not bind property
with name [ADD.action] to bean of type: ViewActionBean : Bean class www.View
ActionBean does not contain a property called 'ADD'. As a result the followin
g expression could not be evaluated: ADD.action
----
When you are trying to match an URL like: /View/myarg1/myarg2/ADD.action with an UrlBinding /View/{arg1}/{arg2}/{$event} then I would expect Stripes to resolve this to the event named: "ADD.action".
As you did not provide any source code of the Action Bean, I suspect that you didn't annotated the event handler with an HandlesEvent like this:
#HandlesEvent("ADD.action")
public Resolution add() {
... do handle add ...
}

Categories