Error With ForkedTomcatServer in Grails

Recently I had an issue with just about all of the Grails apps on my machine.

When I tried to run them, I was getting this error:

| Packaging Grails application.....
| Error Tomcat plugin classes JAR grails-plugin-tomcat-7.0.42.jar not found
| Running Grails application
Error: Could not find or load main class org.grails.plugins.tomcat.fork.For­kedTomcatServer
| Error Forked Grails VM exited with error

The number for the jar file would be different for different versions of Grails.

What I finally did to get rid of the error was:

  1. Run “grails clean; grails compile; grails list-plugins”
  2. Comment out the line for the Tomcat plugin in BuildConfig.groovy
  3. Run “grails clean; grails compile; grails list-plugins” again
  4. Uncomment the line for the Tomcat plugin
  5. Run “grails clean; grails compile; grails list-plugins” again

Maybe the first “grails clean; grails compile” is unnecessary. But this seemed to work.

I have no idea what caused it. It happened with various versions of Grails. I had no problem with new Grails apps, or with apps downloaded from Github.

You’re welcome.

 

2014-07-14 Tweets

Using Groovy Validators in the Groovy Shell

I used the Groovy shell to test my Groovy validators. I learned a little bit more about the Groovy shell in the process.

When you declare a class in the shell, you cannot include a package.

Also, when you use the annotations on fields, you have to put the annotations on the same line as the fields. Class annotations can still be on separate line as the class declaration.

So instead of this:

import groovy.transform.ToString
import info.shelfunit.properties.annotations.IntAnnotation
import info.shelfunit.properties.annotations.StringAnnotation

@ToString( includeNames = true )
class Person {
    @StringAnnotation( minLength = 5, maxLength = 20 ) 
    String firstName
    @StringAnnotation( minLength = 5, maxLength = 20 ) 
    String lastName
    @IntAnnotation( minValue = 0, maxValue = 100 ) 
    def age
}

you would have to do this:

import groovy.transform.ToString
import info.shelfunit.properties.annotations.IntAnnotation
import info.shelfunit.properties.annotations.StringAnnotation

@ToString( includeNames = true )
class Person {
    @StringAnnotation( minLength = 5, maxLength = 20 ) String firstName
    @StringAnnotation( minLength = 5, maxLength = 20 ) String lastName
    @IntAnnotation( minValue = 0, maxValue = 100 ) def age
}

Note that @ToString does not need to be on the same line as “class Person”. Aside from that, it is no different than using the annotations in code or the console.

You’re welcome.

 

Using Groovy Validator on Immutable Objects

I have been working on my Groovy Validator project. I think I have figured out a way to get the validation annotations to work with immutable objects.

The annotation you need to add for the class is AstImmutableConstructor, which is processed by AstImmutableConstructorTransform. I will reproduce the Groovydoc from AstImmutableConstructor:

BEGIN QUOTE

This is an annotation that can be used to validate fields in immutable objects. It is intended to be used with the Immutable annotation at the class level, although I think it will also work with mutable POGOs as well. The fields can be annotated with the following annotations: DoubleAnnotation, FloatAnnotation, IntAnnotation, LongAnnotation and StringAnnotation. You do not need to run the AnnotationProcessor for this to work.

There is a bit of a bug: It will set String, double, float, int and long fields within the default constraints in the annotations listed in the previous paragraph even if the fields are not annotated. They are pretty broad, but the default for the numbers is to set the minimum equal to 0. So if you have no annotation for an int, and you try to give it a value below 0, it will be set to 0.

Here is an example class:

package info.shelfunit.properties.sample.immutable

import info.shelfunit.properties.annotations.AstImmutableConstructor
import info.shelfunit.properties.annotations.IntAnnotation
import info.shelfunit.properties.annotations.LongAnnotation
import info.shelfunit.properties.annotations.StringAnnotation
import groovy.transform.Immutable
import groovy.transform.ToString

@ToString( includeNames = true )
@AstImmutableConstructor
@Immutable
class ImmutableObject002 {
    @StringAnnotation( minLength = 5, maxLength = 10 )
    String firstString
    @IntAnnotation( minValue = 10, maxValue = 100 )
    int firstInt
    @LongAnnotation( maxValue = 100L )
    long firstLong
}

You could set this with a Map like any other immutable object in Groovy, or with the fields, but it will not trigger validation:

def firstImObject = new ImmutableObject002( firstString: "Hello", firstInt: 55, firstLong: 44L )

To get the annotation to actually process, you should send two parameters to the constructor: a Map for the fields, and a boolean for whether or not you want the fields to be validated. If the validation is set to false, the effect is the same as if you simply sent the fields as a Map.

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

END QUOTE

It’s not as clean as a POGO, but it beats having to write setters and constructors every time you make a POGO.

To get the annotation to actually process work, you should send two parameters to the constructor: a Map for the fields, and a boolean for whether or not you want the fields to be validated. If the validation is set to false, the effect is the same as if you simply sent the fields as a Map.

This annotation is processed in the INSTRUCTION_SELECTION compile phase. This is one phase after CANONICALIZATION, which is when the Immutable annotation is processed.

I went through the usual cycle for ASTTransformations: I wrote a class that implemented the visit method in the ASTTransformation interface, did some magic, called

def ast = new AstBuilder().buildFromString( CompilePhase.INSTRUCTION_SELECTION, false, theString )

in the AstBuilder class, add the nodes I created to my annotated ClassNode, and then we are done.

There is a little bit of voodoo involved. When I call AstBuilder().buildFromString, I am using a String I have created via string interpolation. I was inspired by this in the tests in AstBuilderFromStringTest.groovy.  In there, they use a multi-line string to create a class. So I use string interpolation to create a ClassNode with the same name and package name, and I go through each FieldNode and create a new constructor that takes a HashMap and a boolean.

Since the first line in a constructor should be a call to another constructor, I send the HashMap and boolean to a method I create that takes the HashMap and boolean as parameters. In that method, I create a new map. I cycle through all the field nodes, and I compare the values in the map to the arguments given to the validation annotations. If the map value is within the constraints, I add it to the new map. If the map value does not fit the constraints, that key/value pair is not added to the map. Then at the end, the new map is returned to the constructor I created. This new constructor then calls the HashMap constructor that was created by the Immutable annotation.

So if we look at the class at the top of this post in the AST inspector in the Groovy console, we see the constructor I created:

    public ImmutableObject002(java.util.LinkedHashMap argMap, boolean validation) {
        this (ImmutableObject002.createValidatingConstructor(argMap, validation))
    }

I also create a method called createValidatingConstructor, which looks like this (once again, from the Groovy console):

    public static java.lang.Object createValidatingConstructor(java.util.HashMap argMap, boolean validation) {
        if (!( validation )) {
            return argMap 
        } else {
            java.util.HashMap newMap = [:]
            java.lang.Object val = 
            val = argMap [ 'firstString']
            if (5 <= val?.length() && val?.length() <= 10) {
                newMap [ 'firstString'] = val 
            }
            val = argMap [ 'firstInt']
            if (10 <= val && val <= 100) {
                newMap [ 'firstInt'] = val 
            }
            val = argMap [ 'firstLong']
            if (0 <= val && val <= 100) {
                newMap [ 'firstLong'] = val 
            }
            return newMap 
        }
    }

I hope this won’t break in a future version of Groovy. I tried to look through ImmutableASTTransformation.java (which processes the Immutable annotation), and it was not easy to follow.

You’re welcome.

 

2014-07-07 Tweets

Another Post on Automatic Getters and Setters

Recently I was looking at the Groovy section on DZone, and there was an article called Evil: Getters and Setters Where They’re Not Required (original here). He reiterates a lot of what I have been saying in my posts about why I am making the Groovy Validators.

I doubt that he and I are the only two that have noticed this issue. I have heard/read a lot of people complain about the verbosity of getters and setters (like we can get in Eclipse), and how much cleaner it is to use a language that will generate them for you (like Groovy and Ruby). Yet it is odd that so many times people gloss over the fact that these blind, automatic getters and setters essentially leave your variables wide open for just about anything. It seems like people hate verbosity more than they like data integrity.

Granted, I am a bit out of practice with Ruby, so it is possible that there is some sort of validation in the non-Rails Ruby space. And this is purely anecdotal. I just thought it was interesting.

UPDATE: I am making some progress on using the validation annotations with immutable objects. Hopefully Mr LaForge hasn’t closed that bug yet, and announcing my validators will bring me fame and fortune.

More On Groovy Validation

I put my Groovy validators on github. So far it is all in a branch called “working”. There is not much in master.

I think the only way I can get it to work with immutable objects is if you declare the class and the fields final, and add the @Equals, @HashCode and @ToString annotations to the class. So you have to do a by hand most of the things that @Immutable just does for you. Getting my annotations to work with the @Immutable annotation might be difficult. Every time I try AST transformations, I always wind up saying to myself: That’s an hour of my life I am not getting back.

There are a couple of other projects that can be used for validation. Grails has constraints. The Grails constraints use the Spring Validator interface. (“Spring Validator” sounds like yet another Spring project, but it’s not.) It would be nice to validate POGOs without having to drag in Spring to do it. Looking at the Spring site (and a couple of examples like this one), it looks like you have to write a separate validator for every class you make. I want something simple and light.

There is also a project called on Sourceforge called OVal. That does a LOT of stuff, far beyond this project. It has 22 dependencies, 3 of them for logging alone. This allows you to do a LOT of stuff: you can have one field’s constraints depend on another property, you can have one property’s constraints dependent upon the state of another object, you can put the constrains in XML or annotations, it can also be used for Design By Contract. It does a lot of stuff. I wanted to make something similar to the Grails constraints for POGOs. It looks like OVal does a lot more than what I am looking for.

There is also Hibernate Validator. It implements some JSR, but when I read the documentation, it said I had to add two or three other JSRs. Honestly, I could not get it to work. You can use this to validate properties/fields. It can also validate method and constructor parameters. I just want something simple for POGOs.

Maybe I can refactor it to be a static constraints block like Grails has.