Notes From Ken Kousen at Austin GGUG

Ken Kousen spoke about Grails 3 testing a few weeks ago at the Austin Groovy and Grails User Group.

Here are some quick notes I took down:

Spock: You can add notes to when and then
when: "Some conditions"
then: "You should see some results"
In console:
make a list of lists, call combinations()
also: Look up "unroll" for Spock - annotation

CastleController, he uses a service, and makes it "def" instead of a type
then in his test he can do Expando to mock instead of dealing with mocking stuff

Plug-in: build-test-data

You’re welcome.

 

Update 2015-06-15

For the past couple of weeks, I have been working on some Groovy.

I have been working with some metaprogramming to make lists more functional in Groovy. I spent some time trying to intercept the constructors and replace the output with a call to List.asImmutable(). I wasn’t able to quite get the default call, but now that I think about it, that might be a good thing. I think it is good to have choices. I had to use a closure to get what I want.

I took a look at Functional Groovy. He does some stuff with lists, but he does not make them immutable. I think that is part of the functional way: immutable data. I have not committed anything yet, but I might soon.

I have also spent more time on my Groovy email server. It took me a while to get the hang of things. I wanted to use some of the Groovy goodness, but bytes and IO streams are pretty low-level, so I think I may have had to make some compromises. I made two versions, one that uses some of the Groovy goodness, and one that reads bytes. At first I was able to test the version that uses bytes, but not the other one. But the version with bytes is not working as well for some reason. I got another VPS host, and I email myself and print out logging statements to the console. After the “DATA” command, my regular server sends a “RSET” command.

But I figured out how to do some testing in the version that uses some of the Groovy goodness for the java.io classes.

I also got logging to work with Slf4J and Logback. I was using an older version of Logback that was causing problems, but upgrading fixed them.

This might be like the Groovy Validators: I might get frustrated and stop, and then after a while come back to it. We shall see.

You’re welcome.

2015-06-08 Tweets

2015-06-01 Tweets

Groovy Concurrency With Closure Locks

I have played around a bit more with closures and locks in Groovy.

In one of Venkat S’s talks, he says that the java.util.concurrent.locks package solves a lot of the issues with the synchronized keyword: You have to have try/catch/finally blocks to get the lock and release it. I made a class that will hold a Lock object, and can take code as a closure and run it. It seems to work pretty well. At least I think so.

But I realized there is one possible issue: The ClosureLock class only imports from java.util.concurrent.locks. What if some of the code in the closure is from another package that is not imported in the ClosureLock class?

I made a class that imports groovy.time.Duration, and creates a couple of objects and invokes methods in a closure. And it ran without blowing up. I also made a class called DebugClosureLock that prints out some stuff to the console checking if the lock is held by the current thread.

Here is the DebugClosureLock class:

package info.shelfunit.concurrency.locks

import java.util.concurrent.locks.Lock
import java.util.concurrent.locks.ReentrantLock

class DebugClosureLock { 
    final Lock lock = new ReentrantLock()
    
    // prevent lock from being changed
    def setLock( arg ) {}
    
    def lockSomeCode( block ) {
        
        try { 
            println "Is lock ${lock.hashCode()} held? ${lock.isHeldByCurrentThread()}"
            println( "about to try to get the lock" )
            if ( lock.tryLock() || lock.tryLock( 500, TimeUnit.MILLISECONDS ) ) {
                println " About to call block. Is lock ${lock.hashCode()} held? ${lock.isHeldByCurrentThread()}"
                block.call()
            }
        } finally {
            println( "About to try to unlock" )
            lock.unlock()
        }
        println "Done with code. Is lock ${lock.hashCode()} held? ${lock.isHeldByCurrentThread()}"
    }
}

Here is the class that uses it:

package info.shelfunit.concurrency.locks

import groovy.time.Duration 

class SecondLockRunner { 

  def doStuff() { 
    DebugClosureLock cLock = new DebugClosureLock()
    def dur = new Duration(  30, // days 
        2, // hours 
        45, // minutes 
        32, // seconds 
        123 // millis 
    )
    println( "about to call dur.toString() " )
    cLock.lockSomeCode( { println "${dur.toString()}" } )
    def dur2 = new Duration(  3, // days 
        20, // hours 
        43, // minutes 
        31, // seconds 
        522 // millis 
    )
    println( "\nabout to call dur2.toString() " )
    cLock.lockSomeCode { 
        println "${dur2.toString()}"
        println "dur2 as long: ${dur2.toMilliseconds()}"
    }
    
  }

  static void main( String[] args ) { 
    SecondLockRunner slr = new SecondLockRunner()
    slr.doStuff()
  }
} // end class

So, to review: My question was would DebugClosureLock blow up when it was called since it does not import groovy.time.Duration? And the answer is it did not.

Here is the console output:

about to call dur.toString() 
Is lock 1740808647 held? false
about to try to get the lock
 About to call block. Is lock 1740808647 held? true
30 days, 2 hours, 45 minutes, 32.123 seconds
About to try to unlock
Done with code. Is lock 1740808647 held? false

about to call dur2.toString() 
Is lock 1740808647 held? false
about to try to get the lock
 About to call block. Is lock 1740808647 held? true
3 days, 20 hours, 43 minutes, 31.522 seconds
dur2 as long: 333811522
About to try to unlock
Done with code. Is lock 1740808647 held? false

Paul King shows how to do this on slide 36 of his talk Groovy and Concurrency using metaprogramming:

import java.util.concurrent.locks.ReentrantLock

ReentrantLock.metaClass.withLock = { critical ->
    lock()
    try { critical() }
    finally { unlock() }
}

Then you can use it like this:

ReentranLock lock = new ReentrantLock()
lock.withLock{ someCode() }

You’re welcome.

Thinking About Starting A Grails 3 Tutorial

I was at the Austin Groovy and Grails User Group this past week. The speaker was Ken Kousen. I am seeing a pattern with the No Fluff Just Stuff Speakers: they are all really smart guys who tell the same jokes year after year.

Ken Kousen said that he has run into some gotchas with Grails 3, and that the docs are not up to date. He said Grails 3 needs a book, and he doesn’t see one coming out any time soon. A lot of the Groovy and Grails authors either have just finished books and don’t want to go through the grinder again right away.

I have been thinking for a couple of years of making a Grails tutorial, sort of like a Hartl tutorial for Grails. Perhaps it is time to get it started. If I did this, it would only exist online.

I have also thought about making a quick Ratpack tutorial. It would be nice if there was a linear set of steps to make a CRUD app. It’s nice to know some theory, but sometimes I wish projects would make it easier to help newbies get through a “Hello, World”.

I have to think about it. I might be biting off more than I can chew.

You’re welcome.

Some Groovy Threading

There is an example of using threads with Groovy in Venkat’s book.

He uses the GDK extension to Thread and calls Thread.start. I wondered if the main thread would wait until the started thread completed, and what would happen if you started another thread.

I made some changes, and ran it.

Here is my class:

package info.shelfunit.venkat.ch07

class BetterThreadExample {
    
    def printThreadInfo( msg ) {
        println "$msg" 
    }
    
    def doStuff() {
        sleep( 5000 )
        printThreadInfo 'Main'
        println "Main is ${Thread.currentThread().name}"
        Thread.start {
            def name = Thread.currentThread().name
            printThreadInfo "AA Started: ${name}"
            sleep( 3000 ) 
            println "AA Interrupted 1" 
            sleep( 1000 )
            println "AA IN started"
            sleep( 3000 )
            println "AA still in started"
            println "AA Finished Started"
        }
        
        Thread.start( 'Second' ) {
            def name = Thread.currentThread().name
            printThreadInfo "BB Started Daemon: ${name}"
            sleep( 5000 ) 
            println "BB Interrupted 2" 
            sleep( 1000 )
            println "BB in second thread"
            sleep( 1000 )
            println "BB Finished Started Daemon"
        }
        println "At the end in main"
    }
      static void main( String[] args ) { 
          def bte = new BetterThreadExample()
          bte.doStuff()
      } // end method main

}

Here is the result:

Main
Main is main
At the end in main
AA Started: Thread-1
BB Started Daemon: Second
AA Interrupted 1
AA IN started
BB Interrupted 2
BB in second thread
BB Finished Started Daemon
AA still in started
AA Finished Started

 

So the main thread gets to its last statement pretty quickly. The two threads run simultaneously. I already knew this, but it’s good to review threads every now and then.

I was always intimidated by threading and concurrent  programming. Maybe it’s not too bad in Groovy.

You’re welcome.

2015-05-25 Tweets

Groovy Validator: Ready For Public Consumption

I think the Groovy Validators are ready for public consumption, at least as ready as they’ll ever be.

The basic idea is to allow you to use the same sort of constraints you get with Grails domain objects and use them in Groovy. The main difference is this uses annotations, and Grails uses static blocks.

I have tested them with POGOs, using final and mutable fields, and with immutable objects. Everything seems to work as intended.

Here is the README for the project:

This project has a few annotations that validate fields in POGOs, sort of like Grails constraints.

I will attempt to make some annotations for properties in Groovy.

Here is a POGO:

package info.shelfunit.properties.sample

class Book {

    int pages
    String title
    int year
}

It’s clean, and has no getters and setters. But what I do not like is there is no validation for your data. What if you want your String to be between 10 and 20 characters? What if you want your int field to be more than 100? And what’s to stop some dingo from trying to create a book object with less than 0 pages?

So I made some annotations that can do some validation for you.

package info.shelfunit.properties.sample

import validation.IntAnnotation
import validation.StringAnnotation

class Book {

    @IntAnnotation( minValue = 30, maxValue = 400, throwEx = false )
    def pages
    @StringAnnotation( minLength = 5, maxLength = 20, regEx = /^.*?[Gg]roovy.*$/  )
    String title
    int year
}

For POGOs, if a numeric field is declared as “def”, it will become null if the argument does not meet the validation constraints. If it is declared as a primitive, it will be set to 0 if the argument does not meet the validation constraints.

This project can also validate fields in immutable objects. In addition to using the annotations for the fields, you annotate the class with ImmutableValidator:

package info.shelfunit.properties.sample.immutable

import validation.ImmutableValidator
import validation.IntAnnotation
import validation.LongAnnotation
import validation.StringAnnotation

@ImmutableValidator
class ImmutableObject002 {
    @StringAnnotation( minLength = 5, maxLength = 10 )
    String firstString
    @IntAnnotation( minValue = 10, maxValue = 100 )
    int firstInt
    @LongAnnotation( maxValue = 100L, divisorSet = [ 5L, 7L ] )
    long firstLong
}

To process the annotations, put your properties in a Map, and add a boolean called “validation” and set it to true (since I couldn’t overload the Map constructor, I added a boolean):

def validatingImObject = new ImmutableObject002( 
    [ firstString: "Hi Again", firstInt: 11, firstLong: 22L ], true )

Adding the “throwEx” will throw an exception if the arguments do not meet the validation constraints. It is optional and is set to false by default. If an exception is thrown, it will print out the value and the constraints.

You might get a message like this:

"Hey" is a String with a length outside the range of 5 and 10 or does not match the regular expression ".*"

You can also use it with immutable objects annotated with the ImmutableValidator annotation. This would be a second boolean after the Map with your properties, since the first boolean controls validation:

def thirdImObject = new ImmutableObject002( 
[ firstString: "Hi Once Again", firstInt: 1234567, firstLong: 222L ], 
true, true )

In that case, you get a message with a line for each field. So you might get a message like this:

Groovy validation exception: 
"eeeeeeeeeee" is a String with a length outside the range of 5 to 10 characters or does not match the regular expression ".*" 
1234567 is an integer outside the range 10 to 100 or it is not divisible by anything in the set [1] 
222 is a long outside the range 0 to 100 or it is not divisible by anything in the set [5, 7]

If “throwException” is true for an immutable object and an exception is thrown, then the object will not be created.

This library can also handle final fields in mutable objects.

import groovy.transform.ToString
import validation.IntAnnotation
import validation.FinalFieldValidator

@ToString( includeNames = true )
@FinalFieldValidator
class Car {
    @IntAnnotation( minValue = 10, throwEx = false )
    int miles
    @IntAnnotation( minValue = 1990 )
    final int year
}

As with immutable validation, you need to use a map in the constructor to validate a final field.

def car = new Car( [ miles: 50, year: 2007 ], true, true )

Right now it only handles String, double, float, int and long. For String, it checks the string is checked against a minimum (“minLength”) and maximum (“maxLength”) length, and against a regular expression (“regEx”). For integers and longs, the field is checked against minimum (“minValue”) and maximum (“maxValue”) values, and a set of divisors (“divisorSet”). For double and float, the field is checked against minimum (“minValue”) and maximum (“maxValue”) values. There are defaults for all of these.

To use this project: Run

gradle distZip

and use build/libs/groovy-validator.jar in your project.
You’re welcome.