Today I had a very puzzling Exception case in a Spock unit test for LittleGoblin:

void "happyPathTest"() {

given:
def accountResult = userAccountService.createUserAccount('a username', 'a password',
'This email address is being protected from spambots. You need JavaScript enabled to view it.')

expect:
accountResult.isOkay()

}

was giving an NPE in the line with 'def accountResult'.

After making sure that the userAccountService was not null, I checked the return value of createUserAccount - which looks like this:

package de.dewarim.goblin

import grails.transaction.Transactional

@Transactional
class UserAccountService {

AccountCreationResult createUserAccount(String username, String password, String email){
try {
UserAccount newAccount = new UserAccount(username: username, email: email, userRealName: username)
newAccount.passwd = password
newAccount.save()
Role role = Role.findByName('ROLE_USER')
UserRole userRole = new UserRole(newAccount, role)
userRole.save()
return new AccountCreationResult(userAccount: newAccount)
}
catch (Exception e){
log.debug("Failed to create account: "+e.getMessage())
return new AccountCreationResult(errorMessage: e.getMessage())
}
}
}

So, due to the try...catch block, the method should _always_ return an object, never null.

After searching for quite some time I came upon the JIRA entry:

Unit test of service doesn't work with @Transactional annotation

Turns out, you need to add @Mock([...]) for all domain objects used in the service method along with mocking the transactionManager for the service in the tests setup().

userAccountService.transactionManager = Mock(PlatformTransactionManager) {
getTransaction(_) >> Mock(TransactionStatus)
}

 

 

In the last weeks, I have begun to getting reacquainted with Little Goblin and started to fix the outstanding bugs and issues.

I have moved the code base to Grails 2.4.3, which took some work.

My goal is to get the plugin stable again and then continue work on project Schedim (a game based upon the LittleGoblin framework).

Changes for 0.4.3:

  • Fixed JavaScript bug in shop page: jQuery was not being loaded.
  • Changed all pages containing inventory to use a better template/layout. (internal improvement, less GSP code)
  • Currently buggy: equip items, also see: https://github.com/dewarim/LittleGoblin/issues for outstanding issues.

Thanks to Rainer for pointing out the bugs :)

Today I had some fun while trying to publish the new version of LittleGoblin.

The publish-plugin step failed while generating the pom file, with a rather obscure error:


ingo@turtle:~/personalWorkspace/goblin$ grails publish-plugin --no-scm --dry-run --stacktrace --verbose
Base Directory: /home/ingo/personalWorkspace/goblin
| Packaging Grails application.....
[...]
| Plugin packaged grails-goblin-0.4.0.1.zip
| Generating POM file.....
| Error Exception in thread "DefaultMetadataResolver-0-2"
| Error Exception in thread "DefaultMetadataResolver-0-0"
| Error Exception in thread "DefaultMetadataResolver-0-3"
| Error Exception in thread "DefaultMetadataResolver-0-1"
| Error java.lang.NoSuchMethodError: org.apache.http.client.utils.URIUtils.extractHost(Ljava/net/URI;)Lorg/apache/http/HttpHost;
| Error at org.eclipse.aether.transport.http.HttpTransporter.<init>(HttpTransporter.java:112)
| Error at org.eclipse.aether.transport.http.HttpTransporterFactory.newInstance(HttpTransporterFactory.java:93)
| Error at org.eclipse.aether.internal.impl.DefaultTransporterProvider.newTransporter(DefaultTransporterProvider.java:110)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnector.<init>(BasicRepositoryConnector.java:115)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory.newInstance(BasicRepositoryConnectorFactory.java:180)
| Error at org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider.newRepositoryConnector(DefaultRepositoryConnectorProvider.java:113)
| Error at org.eclipse.aether.internal.impl.DefaultMetadataResolver$ResolveTask.run(DefaultMetadataResolver.java:603)
| Error at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)
| Error at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
| Error at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
| Error at java.lang.Thread.run(Thread.java:724)
| Error java.lang.NoSuchMethodError: org.apache.http.client.utils.URIUtils.extractHost(Ljava/net/URI;)Lorg/apache/http/HttpHost;
| Error at org.eclipse.aether.transport.http.HttpTransporter.<init>(HttpTransporter.java:112)
| Error at org.eclipse.aether.transport.http.HttpTransporterFactory.newInstance(HttpTransporterFactory.java:93)
| Error at org.eclipse.aether.internal.impl.DefaultTransporterProvider.newTransporter(DefaultTransporterProvider.java:110)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnector.<init>(BasicRepositoryConnector.java:115)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory.newInstance(BasicRepositoryConnectorFactory.java:180)
| Error at org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider.newRepositoryConnector(DefaultRepositoryConnectorProvider.java:113)
| Error at org.eclipse.aether.internal.impl.DefaultMetadataResolver$ResolveTask.run(DefaultMetadataResolver.java:603)
| Error at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)
| Error at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
| Error at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
| Error at java.lang.Thread.run(Thread.java:724)
| Error java.lang.NoSuchMethodError: org.apache.http.client.utils.URIUtils.extractHost(Ljava/net/URI;)Lorg/apache/http/HttpHost;
| Error at org.eclipse.aether.transport.http.HttpTransporter.<init>(HttpTransporter.java:112)
| Error at org.eclipse.aether.transport.http.HttpTransporterFactory.newInstance(HttpTransporterFactory.java:93)
| Error at org.eclipse.aether.internal.impl.DefaultTransporterProvider.newTransporter(DefaultTransporterProvider.java:110)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnector.<init>(BasicRepositoryConnector.java:115)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory.newInstance(BasicRepositoryConnectorFactory.java:180)
| Error at org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider.newRepositoryConnector(DefaultRepositoryConnectorProvider.java:113)
| Error at org.eclipse.aether.internal.impl.DefaultMetadataResolver$ResolveTask.run(DefaultMetadataResolver.java:603)
| Error at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)
| Error at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
| Error at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
| Error at java.lang.Thread.run(Thread.java:724)
| Error java.lang.NoSuchMethodError: org.apache.http.client.utils.URIUtils.extractHost(Ljava/net/URI;)Lorg/apache/http/HttpHost;
| Error at org.eclipse.aether.transport.http.HttpTransporter.<init>(HttpTransporter.java:112)
| Error at org.eclipse.aether.transport.http.HttpTransporterFactory.newInstance(HttpTransporterFactory.java:93)
| Error at org.eclipse.aether.internal.impl.DefaultTransporterProvider.newTransporter(DefaultTransporterProvider.java:110)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnector.<init>(BasicRepositoryConnector.java:115)
| Error at org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory.newInstance(BasicRepositoryConnectorFactory.java:180)
| Error at org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider.newRepositoryConnector(DefaultRepositoryConnectorProvider.java:113)
| Error at org.eclipse.aether.internal.impl.DefaultMetadataResolver$ResolveTask.run(DefaultMetadataResolver.java:603)
| Error at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)
| Error at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
| Error at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
| Error at java.lang.Thread.run(Thread.java:724)
| Error Error executing script PublishPlugin: org.apache.http.client.utils.URIUtils.extractHost(Ljava/net/URI;)Lorg/apache/http/HttpHost;
java.lang.NoSuchMethodError: org.apache.http.client.utils.URIUtils.extractHost(Ljava/net/URI;)Lorg/apache/http/HttpHost;
at org.eclipse.aether.transport.http.HttpTransporter.<init>(HttpTransporter.java:112)
at org.eclipse.aether.transport.http.HttpTransporterFactory.newInstance(HttpTransporterFactory.java:93)
at org.eclipse.aether.internal.impl.DefaultTransporterProvider.newTransporter(DefaultTransporterProvider.java:110)
at org.eclipse.aether.connector.basic.BasicRepositoryConnector.<init>(BasicRepositoryConnector.java:115)
at org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory.newInstance(BasicRepositoryConnectorFactory.java:180)
at org.eclipse.aether.internal.impl.DefaultRepositoryConnectorProvider.newRepositoryConnector(DefaultRepositoryConnectorProvider.java:113)
at org.eclipse.aether.internal.impl.DefaultMetadataResolver$ResolveTask.run(DefaultMetadataResolver.java:603)
at org.eclipse.aether.util.concurrency.RunnableErrorForwarder$1.run(RunnableErrorForwarder.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:724)
| Error Error executing script PublishPlugin: org.apache.http.client.utils.URIUtils.extractHost(Ljava/net/URI;)Lorg/apache/http/HttpHost;

After some searching I found the culprit:

A dependency on an old version of Groovy HttpBuilder:

compile("org.codehaus.groovy.modules.http-builder:http-builder:0.5.2") {
excludes "groovy"
}

The current version is at 0.7.2, but that one is not yet available to maven dependency resolution. So I use 0.7.1 and generate-pom now works.

 

Checking out the source code, installing the database and adding the demo data may be difficult if you are not an experienced developer with some free time.

The alternative is: download the Cinnamon-Server-VM

The username is 'tex', with password 'tex'. Once unpacked, it will require about 11 GByte of your hard drive. You will need either VMware workstation (commercial) or VMware Player (free) to run the VM.


The Cinnamon developer VM contains the source code for the Cinnamon 3 server, including the dependencies (cinnamon-db and cinnamon-humulus) as well as a PostgreSQL server with a demo repository. So, you just can start up Cinnamon from the command line and open the browser to start exploring Cinnamon.
You can even connect with the desktop client from a Windows machine, for example if you wish to debug the code.

Also included is the Spring Groovy Grails Tool Suite, which is a free integrated development environment.

Subcategories

Descriptions of error messages and possible solutions

Posts about Little Goblin, the Grails based open source browser game engine and its reference implementation.

The home page of Little Goblin is littlegoblin.de