Posts Tagged ‘groovy’
Dependency Injection with Guice and GuiceJumper May 10, 2014 | 10:14 pm

When a lot of people discussion static vs. dynamic typing, they are really discussing Java vs. Ruby typing: they simply don’t know any better than to think that Java is representative of static typing. In a similar way, when people hear “dependency injection”, they think Spring. I was one of these people: after getting caught on one too many angle brackets, I was generally put off Spring. The dynamic language features of Groovy made Spring a bit more tolerable within Grails, but I still found it more annoying and obscure than helpful.

For a while, I considered dependency injection to be an informative failure, but something kept nagging at me: the magical variables in Rails are effectively involuntary dependency injection—this pattern is half-jokingly called “dependency ejection” or “dependency secretion”. So there’s something to dependency injection, even if Spring got it wrong.

Then, at JavaOne, I bumped into some of the Google devs, and they pitched me Guice. Some of the pitch points hit home: compile-time type checking; actionable error messages; configured through code; works with immutable classes. However, it still used annotations (which I was busy hating on), and dependency injection was not a popular point with me, so it took me a while to get around to checking Guice out.

I wish I hadn’t waited so long.

Guice does dependency injection as right as I’ve seen, and it makes working within Java and Groovy much nicer. Its simplicity sometimes leads people to underestimate it, however. Recently, I released GuiceJumper, which is my extension to the Guice core library. The code in there demonstrates some of the power of Guice.

For instance, there’s the ExecutorModule. Its primary purpose is to enable classes to ask for an ExecutorService—the core class for concurrency—by specifying the kind of tasks that will be passed to it. The context will provide an appropriately-configured implementation of the ExecutorService, which (if appropriate) is shared throughout the system.

// Groovy code so it's short enough to read
class Busy {
   @Inject @Background ExecutorService executor
   ...
}
 
def injector = Guice.createInjector(new ConcurrentModule())
def busy = injector.getInstance(Busy)
busy.executor.submit {-> ... }

The @Background annotation means the ExecutorService will be appropriate for background task processing. The other options are @Process (CPU-limited processing); @Read (work production and I/O input); and @Write (work consumption and I/O output).

But that’s no big deal: that’s basically a step above rudimentary dependency injection. Slightly cooler: load your application configuration up into your favorite properties file (through, say, Properties.load(Reader)), provide it to the PropertiesModule, and then those properties will be available throughout your system. You can convert them to any primitive type, BigInteger, BigDecimal, Charset, File, URL, URI, or any enum…with actionable errors if the conversion fails. So all those magic constants can now be stored up front in a single configuration step, loaded later, and you will get an early error if they are badly formatted or otherwise bogus. It’s a beautiful thing.

class Configured {
   @Inject @Named("my.config.prop") int value
   @Inject @Named("my.awesome.blog") URL blogUrl
   ...
}
 
def injector = Guice.createInjector(new PropertiesModule(["my.config.prop":"42", "my.awesome.blog": "http://enfranchisedmind.com"]))
def confed = injector.getInstance(Configured)
assert confed.value == 42
assert "$confed.blogUrl" == "http://enfranchisedmind.com"

The I18nModule pulls a similar stunt, but uses annotations that look like @Localized("i18n.key") and loads localized values from the ResourceBundle, enabling super-simpler localization of the application and centralization of the messaging.

I’ve got another module to be released which provides all the wiring necessary for the AWS Java SDK objects, but that’s not released to the public yet.

Guice gives you the ability to have a distinct configuration phase to your application, which is entirely under the control of your application, and which need not be at the very beginning. In fact, I have systems that have multiple configuration phases, generating child injectors with new modules as more information becomes available: for instance, my hybrid of Groovy/Guice/Restlet (working title: Restling) creates a new injector for each request. The request injector can provide the request itself, the response, the user, and other request-scoped information.[1] It is worth emphasizing that all of this is configured and controlled by code, which means that you can have precise control over what is going on when, and in the unlikely situation that there is a problem, you can apply your standard debugging tactics. It’s great.

It’s dependency injection without the pain. I love it.

[1] Yes, I am aware that there is a request scope using the servlet plugin for Guice. I find that plugin more magical than helpful, especially given that I can accomplish the same things with nested injectors.

Executing a MySQL Script through JDBC July 30, 2013 | 03:26 pm

There’s no way to execute a MySQL script through JDBC, and most of the tools (including SimpleJdbcTestUtils) have weird requirements for the script and/or a bunch of overhead to do what you want to do. The big trick is that DELIMITER isn’t actually a SQL command: it’s a pre-processing instruction (at least conceptually). And that makes feeding the script into MySQL a pain.

Groovy and Commons-Lang StringUtils to the rescue. Here’s the short script that will break up a SQL script into a Collection of String objects, which can then be fed to your favorite SQL execution tool.

	static Collection<String> breakUpSqlScript(String loadSql) {
		List<String> statements = []
 
		String delimiter = ";"
		String currentStatement = ""
		loadSql.eachLine { String line ->
			line = line.trim()
			if(StringUtils.startsWithIgnoreCase(line, "--")) {
				// Comment: IGNORE
			} else if(line.endsWith(delimiter)) {
				line = StringUtils.removeEnd(line, delimiter)
				currentStatement = "$currentStatement \n $line".trim()
				statements << currentStatement
				currentStatement = ""
			} else if(StringUtils.startsWithIgnoreCase(line, "DELIMITER")) {
				delimiter = StringUtils.removeStartIgnoreCase(line, "DELIMITER").trim()
			} else {
				currentStatement = "$currentStatement \n $line"
			}
		}
		if(!StringUtils.isBlank(currentStatement)) statements << currentStatement
 
		return statements
	}

PS: If you want to get the contents of a file as a string, use File#getText().

Gaelyk (Groovy/Google App Engine) Persistence in September’s GroovyMag: Announcement and Errata September 9, 2012 | 11:24 am

This month, I have an article on persistence on Google App Engine’s persistence (BigTable/DataStore), viewed through the perspective of Gaelyk. One of the big things I highlight is ways in which this NoSQL engine differs from relational databases, and what that means for structuring your data and optimizing your structures. This is a part of the conversation which is often sorely missing, so I felt the need to highlight it.

Vladimír Oraný read through it, and said he liked it quite a bit, but noticed two things that I have to correct. First, I apparently imply through my example that you need to use @Entity in order to use coercion into Google App Engine’s Entity. This isn’t true: any bean or POGO can be coerced. I knew that, but apparently conflated two steps in a way that might be confusing. Second, despite an error in the documentation implying the contrary, @Unindexed cannot be applied to a class. Instead, you need to pass that as an argument to the @Entity annotation: @Entity(unindexed=true).

Like before, you can get a free copy of this month’s GroovyMag by tweeting me for it.

Open Source Journaling: Cornerstone February 11, 2009 | 08:48 am

I did another brief update to Cornerstone last night. When parsing floating point numbers, I was doing a parse of an integer, then the dot, then a series of digits, and gluing it all together afterwards. Fred Medlin at the Java Hack Night pointed out that was silly, and I should should parse the value directly as a regex. I went one step further, and jacked the BigDecimal String constructor’s BNF, but encoded as a regex.

So the number parsing now looks like this:

  def float_number : Parser[BigDecimal] = (rawFloat <~ ("F"|"f"))
 
  def integer_number : Parser[BigInteger] = (rawInteger <~ ("Z"|"z"))
 
  def rational_number : Parser[CSRational] = (
    (rawFloat ^^ { new CSRational(_) }) |
    fraction |
    (rawInteger ^^ { new CSRational(_) })
  )
 
  def fraction : Parser[CSRational] = (
    ((rawInteger <~ "/") ~ rawNonzeroNatural) ^^ {
      case x ~ y => new CSRational(x,y)
    }
  )
 
  def rawInteger: Parser[BigInteger] = (
    ((opt("+") ~> """[01-9]+""".r) |
      """[-]?[01-9]+""".r) ^^ { new BigInteger(_) }
  )
 
  def rawNonzeroNatural : Parser[BigInteger] = (
    (opt("+") ~> """[1-9][01-9]*""".r) ^^ { new BigInteger(_) }
  )
 
  def rawFloat : Parser[BigDecimal] = (
    """[-+]?\d*\.\d+([eE][+-]?\d+)?""".r ^^ { new BigDecimal(_) }
  )

As you can see, Cornerstone has only 3 kinds of numbers: integers, floats, and rationals. Rationals are the default, with integers and floats being signaled by suffixes on the numbers (“Z”/”z” and “F”/”f”, respectively). I’m still trying to decide, but I may go with 5 numeric types at the end of the day: long integers (“z”), BigIntegers (“Z”), double-precision floats (“f”), BigDecimals (“F”), and arbitrary-precision rationals (un-suffixed).

Open Source Journaling: Autobase v0.8.1 February 9, 2009 | 12:12 am

Did a bunch of work on Autobase tonight, culminating in a v0.8.1 release.

  • First, I upgraded to Grails 1.1b3. This wasn’t that big a deal, except they moved the staging directory on me, so I had to shift to using stagingDir on the eventWarStart to populate the war. That was on the to-do list for Autobase anyway, so it’s good it got done.
  • I also added a bit of a short-cut for things that have raw bodies (like the “sql” change) — bare string arguments will be set to the “sql” property. This isn’t the best solution for that, but the best solution involves upstream changes in Liquibase — it needs to somehow signal that a body is expected and what property to set with that body. Or (less OO-y), simply a helper object that takes the change and the string and applies it appropriately. This is probably coming in Liquibase 1.10, so the “sql” stopgap is only temporary.
  • I fought again with the whole column/where problem. The methodMissing dispatching was introducing arrays (instead of ArrayLists), missing existing methods, and other weirdness. I punted over to groovy.util.Proxy, but discovered that a proxy of a proxy fails. So I had to leave the dirty hack in place, because I just can’t get the meta-object magic to work.

Feature or Bug, You Decide: Argument Reordering in Groovy August 19, 2008 | 04:52 am

[Edit: Some documentation has been added to clarify this issue — see Groovy’s Extended Guide to Method Signatures on the wiki. And now that I’ve read through the documentation and grok the way that Groovy is intending to work, I actually like it. At first, though, it was a bit of a nasty shock.]

Running this in the groovyConsole:

void custom(Class cls, Map args) { println cls.name + " " + args }
custom(Integer.class, foo:"Bar!")

Explodes like this:

groovy.lang.MissingMethodException: No signature of 
method: Script3.custom() is applicable for argument 
types: (java.util.LinkedHashMap, java.lang.Class) 
values: {[foo:Bar!], class java.lang.Integer}
at Script3.run(Script3:5)

I expect the explosion, but it looks like the types of my arguments are getting swapped around before it explodes. In fact, if I swap the order of the arguments around at the call site…

void custom2(Map args, Class cls) { println cls.name + " " + args }
custom2(Integer.class, foo:"Bar!")

…the code runs without a hitch.

It turns out that Groovy intentionally reorganizes arguments passed into a method for you, beginning with the naked map, then normal arguments, then varargs.

More at my (closed, “Not a Bug” JIRA ticket): GROOVY-3006. See also Groovy-3009 for more issues with method reordering.