Monday, March 26, 2012

Code Lounge

by Richard Vowles

Last year I started a conference - I was looking for a barcamp style conference that I could really enjoy going to - that would be full of topics I wanted to cover. It eventually got named The Exceptional Conference (given Illegal Argument as the theme) - and it got a good turnout. However, the topics really didn't interest me all that much. They interested a lot of other people however and the feedback was good. We got some Pizza sponsorship from Fronde, the rest was paid for by my company Blue Train Software Ltd.

We had a few people come up from Wellington - which was excellent, I enjoy John and Nigel's company and it was great to meet the other guys who seem to form a really informed and friendly group. John and Nigel decided to run one in Wellington and so it was simply polite that I went - Mark and I went down (I took my son Xavier with me). Unfortunately it was pretty much the same topics, so I didn't enjoy it a whole lot. I felt pretty guilty about that - John, Nigel, and the VUW crew had gone to a lot of trouble to organize it - I just couldn't get into it. Later I just realized that my original goal - something discussing things that I am interested in is hard to find at conferences - even ones of such a small size. I get it from the IllegalArgument podcast, but only in general chat. I also found there wasn't enough core-geek depth.

So when Nigel asked when the next conference was going to take place I said I'd bow out of this one, but more prodding from Nigel and Mark got me thinking, and I really appreciate that they did prod.

What I realized I wanted in reflection was what John, Nigel, Mark and myself did at the start of all this - a geek weekend or even just a single day where we could take a topic or idea and really explore it - a small number of people (4 in that case - perhaps up to 8?) would probably work. Idea had to be fairly tight, people shouldn't know too much about it otherwise its not a learning experience - or perhaps they should - I don't know yet. Close environment, good for pairing, good food, good drinks (coffee for those that like it, water for those that don't :-), good wifi, projector if necessary, white board, all that good stuff.

And I realized I had most of these in my lounge - and so was born the concept of CodeLounge. The idea is to take a topic, advertise your lounge will be a meeting place on a specific date for a specific set of times, specify what you can provide and just go for it. At the moment, I'm not sure how it will turn out - but I am hoping that we'll learn ways of making the experience interesting.

I registered a domain name for it - CodeLounge.IO (a play on Google.IO - a conference I no-longer wish to attend, the videos are good enough), there is no website yet - perhaps that is the first job (Twitter Bootstrap anyone?), but we have a Meetup group and a logo.

I call them a micro-code-camp.


Bluegrails Maven Plugin

by Richard Vowles

There have been some considerable changes made to the Bluegrails Maven plugin - we are starting support for Grails at 2.0.1 - it is quite difficult to ensure compatibility as I have found a number of quirks to how the Grails Gant scripts behave.

We are now using it internally, and it seems to be going well - we found one dependency that wasn't in central (Spring UAA) but that can be excluded and is only used by the plugin (via the scripts inclusion). I hope to have video tutorials up once we are happy that it is solid and working well.

It can be downloaded on Github now under the http://www.github.com/bluegrails/grails-maven repository.


Friday, March 16, 2012

Can you afford to not know Git any longer?

by Richard Vowles

As much as people still debate the Subversion vs Git arguments, particularly in the JVM community I asked myself today whether or not you can get away with not knowing the basics of Git any longer. Why? Because 2/3 of your source base (or more) is likely to be open source and an ever increasing portion of that seems to reside on Github - for the better in my opinion as it has a superior mechanism for supporting patches via pull requests. One of the fundamental tenants of open source is that you can fix the bug and with Git,  not being able to get a patch accepted - like with Guava or many Grails plugins) or in a timely fashion so it is released and usable (for example with Guice), is not fatal. At least you will be able to keep merging the upstream changes into your code base with the patches relatively easily (as I recently did with the Grails Maven plugin).

I think any organisation that chooses an open source project that isn't on Git is actually choosing one that is a higher risk for their organization and when you do, you need to have a basic working knowledge of it. If it was me, I'd get every organisation to have a Github organisation account where any forked artifacts reside so as people come and go in their organisation, they have one central place where their patched versions reside. Its not a perfect solution, ideally projects that need patching with do it quickly and update themselves, but the way most projects have their artifacts organized and how often they release is always a problem, so I think it is inevitable and Git offers such a better mechanism than Subversion.

So if you are a JVM software developer and you don't know Git, now is the time to learn. There are great books out there and some excellent screen casts from Orielly, so get on it now!

Friday, March 9, 2012

Grails 2.0.1 and Maven

by Richard Vowles


One of the projects I have been working on is moving from Grails 1.3.7 to Grails 2.0.1 - so I naturally went looking for the Maven artifacts for the project. We use Maven extremely successfully with composites and I have had a talk to Graeme about using them to reduce clutter in the project pom and make things clean.

My first hurdle is that Grails 2.x is not in Apache Maven Central - asking Graeme on twitter gave the answer that it wasn't going to be there and was in http://repo.grails.org/grails/core. Fair enough I thought until I realized that in fact this would cause problems for me - I couldn't release bluegrails because bluegrails needs to be in central. Bluegrails as a refresher is a set of composite dependencies that allow you to be consistent with Grails dependencies in your non Grails artifacts.

Greame's reasoning when @talios prodded him was that Grails had external dependencies that weren't in central - which I understand - if you have that you can't use Apache Maven Central, and it is a rule that makes sense especially from a corporate perspective. Grails run their own repo, just point to it. Yet, still - it has hosed my ability to deploy these artifacts that add considerable value to anyone who uses Maven and Grails generally in their organization and want to maintain version compatibility.

So tonight I decided to check - if I could chase those projects down that weren't in Apache Maven Central and offer to help get them there, I'd hope the Grails team would push to Central.

I downloaded and build the Grails Maven Archetype and Grails Maven Plugin (which wouldn't build in Maven 3.0.4 - there are a couple of annotation problems with it). Once I had those two working, I created an archetype and found to my delight that Graeme had taken the Composite approach to Maven dependencies - the new pom is a delight!


  <dependencies>
<dependency>
      <groupId>org.grails</groupId>
      <artifactId>grails-dependencies</artifactId>
      <version>${grails.version}</version>
  <type>pom</type>
    </dependency>
  </dependencies>

Thats it. Awesome! Exactly how it should be.

Now to ascertain the naughty dependencies - so a mvn dependency:tree


[INFO] - org.grails:grails-dependencies:pom:2.0.1:compile
[INFO]    +- org.grails:grails-core:jar:2.0.1:compile
[INFO]    |  +- commons-io:commons-io:jar:2.1:compile
[INFO]    |  +- org.slf4j:slf4j-api:jar:1.6.2:compile
[INFO]    |  +- org.slf4j:jcl-over-slf4j:jar:1.6.2:compile
[INFO]    |  +- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.1.Final:compile
[INFO]    |  - commons-lang:commons-lang:jar:2.6:compile
[INFO]    +- org.grails:grails-bootstrap:jar:2.0.1:compile
[INFO]    +- org.grails:grails-crud:jar:2.0.1:compile
[INFO]    +- org.grails:grails-datastore-core:jar:1.0.2.RELEASE:compile
[INFO]    +- org.grails:grails-hibernate:jar:2.0.1:compile
[INFO]    |  +- javax.validation:validation-api:jar:1.0.0.GA:runtime
[INFO]    |  +- org.grails:grails-datastore-simple:jar:1.0.2.RELEASE:compile
[INFO]    |  +- javax.transaction:jta:jar:1.1:compile
[INFO]    |  +- org.hibernate:hibernate-validator:jar:4.1.0.Final:runtime
[INFO]    |  +- org.hibernate:hibernate-ehcache:jar:3.6.7.Final:runtime
[INFO]    |  +- org.grails:grails-datastore-gorm:jar:1.0.2.RELEASE:compile
[INFO]    |  +- org.hibernate:hibernate-core:jar:3.6.7.Final:compile
[INFO]    |  |  +- antlr:antlr:jar:2.7.7:compile
[INFO]    |  |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO]    |  |  - org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile
[INFO]    |  - javassist:javassist:jar:3.12.0.GA:compile
[INFO]    +- org.grails:grails-plugin-codecs:jar:2.0.1:compile
[INFO]    |  - commons-codec:commons-codec:jar:1.5:compile
[INFO]    +- org.grails:grails-plugin-controllers:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-converters:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-datasource:jar:2.0.1:compile
[INFO]    |  +- commons-dbcp:commons-dbcp:jar:1.4:compile
[INFO]    |  - commons-pool:commons-pool:jar:1.5.6:compile
[INFO]    +- org.grails:grails-plugin-domain-class:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-filters:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-gsp:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-i18n:jar:2.0.1:compile
[INFO]    +- org.grails:grails-logging:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-log4j:jar:2.0.1:compile
[INFO]    |  +- log4j:log4j:jar:1.2.16:compile
[INFO]    |  - org.slf4j:jul-to-slf4j:jar:1.6.2:compile
[INFO]    +- org.grails:grails-plugin-mimetypes:jar:2.0.1:compile
[INFO]    |  - commons-collections:commons-collections:jar:3.2.1:compile
[INFO]    +- org.grails:grails-plugin-scaffolding:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-services:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-servlets:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-url-mappings:jar:2.0.1:compile
[INFO]    +- org.grails:grails-plugin-validation:jar:2.0.1:compile
[INFO]    +- org.grails:grails-resources:jar:2.0.1:compile
[INFO]    +- org.grails:grails-spring:jar:2.0.1:compile
[INFO]    |  - org.springframework:spring-web:jar:3.1.0.RELEASE:compile
[INFO]    |     - aopalliance:aopalliance:jar:1.0:compile
[INFO]    +- org.grails:grails-web:jar:2.0.1:compile
[INFO]    |  +- commons-fileupload:commons-fileupload:jar:1.2.2:compile
[INFO]    |  +- xpp3:xpp3_min:jar:1.1.4c:compile
[INFO]    |  - opensymphony:sitemesh:jar:2.4:compile
[INFO]    +- org.grails:grails-webflow:jar:2.0.1:compile
[INFO]    +- org.codehaus.groovy:groovy-all:jar:1.8.6:compile
[INFO]    +- org.aspectj:aspectjweaver:jar:1.6.10:runtime
[INFO]    +- org.aspectj:aspectjrt:jar:1.6.10:runtime
[INFO]    +- cglib:cglib:jar:2.2:runtime
[INFO]    +- asm:asm:jar:3.1:runtime
[INFO]    +- oro:oro:jar:2.0.8:runtime
[INFO]    +- commons-beanutils:commons-beanutils:jar:1.8.3:runtime
[INFO]    +- commons-el:commons-el:jar:1.0:runtime
[INFO]    +- commons-validator:commons-validator:jar:1.3.1:runtime
[INFO]    +- com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:jar:1.2_jdk5:runtime
[INFO]    +- com.h2database:h2:jar:1.2.147:runtime
[INFO]    +- javax.servlet:jstl:jar:1.1.2:runtime
[INFO]    +- net.sf.ehcache:ehcache-core:jar:2.4.6:runtime
[INFO]    +- org.springframework:spring-aspects:jar:3.1.0.RELEASE:runtime
[INFO]    +- org.springframework:spring-jdbc:jar:3.1.0.RELEASE:runtime
[INFO]    +- org.springframework:spring-jms:jar:3.1.0.RELEASE:runtime
[INFO]    +- org.springframework:spring-orm:jar:3.1.0.RELEASE:runtime
[INFO]    +- org.springframework:spring-tx:jar:3.1.0.RELEASE:runtime
[INFO]    - org.springframework:spring-webmvc:jar:3.1.0.RELEASE:compile
[INFO]       +- org.springframework:spring-asm:jar:3.1.0.RELEASE:compile
[INFO]       +- org.springframework:spring-beans:jar:3.1.0.RELEASE:compile
[INFO]       +- org.springframework:spring-context:jar:3.1.0.RELEASE:compile
[INFO]       |  - org.springframework:spring-aop:jar:3.1.0.RELEASE:compile
[INFO]       +- org.springframework:spring-context-support:jar:3.1.0.RELEASE:compile
[INFO]       +- org.springframework:spring-core:jar:3.1.0.RELEASE:compile
[INFO]       |  - commons-logging:commons-logging:jar:1.1.1:compile
[INFO]       - org.springframework:spring-expression:jar:3.1.0.RELEASE:compile

(I removed the \)

And a bit of code (I put that all in a def called deps, its ugly but it doesn't matter) - ignored the org.grails ones as these were accepted to not be in central:


def failed = []


deps.split("\n").each { line ->


  if (line.startsWith("[INFO]")) {
    line.split(" ").each { dep ->
      if (dep.size() > 0 && Character.isLetter(dep.charAt(0)) ) {
        if (!dep.startsWith("org.grails")) {
          
          //println dep
          String[] splitDep = dep.split(':')
          
          String url = "http://repo1.maven.org/maven2/${splitDep[0].replace('.', '/')}/${splitDep[1]}/${splitDep[3]}/${splitDep[1]}-${splitDep[3]}.pom"
          try {
            new URL(url).openStream()
            println "ok ${url}"
          } catch ( Exception ex ) {
            println "failed ${url}"
            failed.add(url)
          }          
        }
      }
    }
  
  }
}

And the result?

ok http://repo1.maven.org/maven2/commons-io/commons-io/2.1/commons-io-2.1.pom
ok http://repo1.maven.org/maven2/org/slf4j/slf4j-api/1.6.2/slf4j-api-1.6.2.pom
ok http://repo1.maven.org/maven2/org/slf4j/jcl-over-slf4j/1.6.2/jcl-over-slf4j-1.6.2.pom
ok http://repo1.maven.org/maven2/org/hibernate/javax/persistence/hibernate-jpa-2.0-api/1.0.1.Final/hibernate-jpa-2.0-api-1.0.1.Final.pom
ok http://repo1.maven.org/maven2/commons-lang/commons-lang/2.6/commons-lang-2.6.pom
ok http://repo1.maven.org/maven2/javax/validation/validation-api/1.0.0.GA/validation-api-1.0.0.GA.pom
ok http://repo1.maven.org/maven2/javax/transaction/jta/1.1/jta-1.1.pom
ok http://repo1.maven.org/maven2/org/hibernate/hibernate-validator/4.1.0.Final/hibernate-validator-4.1.0.Final.pom
ok http://repo1.maven.org/maven2/org/hibernate/hibernate-ehcache/3.6.7.Final/hibernate-ehcache-3.6.7.Final.pom
ok http://repo1.maven.org/maven2/org/hibernate/hibernate-core/3.6.7.Final/hibernate-core-3.6.7.Final.pom
ok http://repo1.maven.org/maven2/antlr/antlr/2.7.7/antlr-2.7.7.pom
ok http://repo1.maven.org/maven2/dom4j/dom4j/1.6.1/dom4j-1.6.1.pom
ok http://repo1.maven.org/maven2/org/hibernate/hibernate-commons-annotations/3.2.0.Final/hibernate-commons-annotations-3.2.0.Final.pom
ok http://repo1.maven.org/maven2/javassist/javassist/3.12.0.GA/javassist-3.12.0.GA.pom
ok http://repo1.maven.org/maven2/commons-codec/commons-codec/1.5/commons-codec-1.5.pom
ok http://repo1.maven.org/maven2/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4.pom
ok http://repo1.maven.org/maven2/commons-pool/commons-pool/1.5.6/commons-pool-1.5.6.pom
ok http://repo1.maven.org/maven2/log4j/log4j/1.2.16/log4j-1.2.16.pom
ok http://repo1.maven.org/maven2/org/slf4j/jul-to-slf4j/1.6.2/jul-to-slf4j-1.6.2.pom
ok http://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-web/3.1.0.RELEASE/spring-web-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/aopalliance/aopalliance/1.0/aopalliance-1.0.pom
ok http://repo1.maven.org/maven2/commons-fileupload/commons-fileupload/1.2.2/commons-fileupload-1.2.2.pom
ok http://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.pom
ok http://repo1.maven.org/maven2/opensymphony/sitemesh/2.4/sitemesh-2.4.pom
ok http://repo1.maven.org/maven2/org/codehaus/groovy/groovy-all/1.8.6/groovy-all-1.8.6.pom
ok http://repo1.maven.org/maven2/org/aspectj/aspectjweaver/1.6.10/aspectjweaver-1.6.10.pom
ok http://repo1.maven.org/maven2/org/aspectj/aspectjrt/1.6.10/aspectjrt-1.6.10.pom
ok http://repo1.maven.org/maven2/cglib/cglib/2.2/cglib-2.2.pom
ok http://repo1.maven.org/maven2/asm/asm/3.1/asm-3.1.pom
ok http://repo1.maven.org/maven2/oro/oro/2.0.8/oro-2.0.8.pom
ok http://repo1.maven.org/maven2/commons-beanutils/commons-beanutils/1.8.3/commons-beanutils-1.8.3.pom
ok http://repo1.maven.org/maven2/commons-el/commons-el/1.0/commons-el-1.0.pom
ok http://repo1.maven.org/maven2/commons-validator/commons-validator/1.3.1/commons-validator-1.3.1.pom
ok http://repo1.maven.org/maven2/com/googlecode/concurrentlinkedhashmap/concurrentlinkedhashmap-lru/1.2_jdk5/concurrentlinkedhashmap-lru-1.2_jdk5.pom
ok http://repo1.maven.org/maven2/com/h2database/h2/1.2.147/h2-1.2.147.pom
ok http://repo1.maven.org/maven2/javax/servlet/jstl/1.1.2/jstl-1.1.2.pom
ok http://repo1.maven.org/maven2/net/sf/ehcache/ehcache-core/2.4.6/ehcache-core-2.4.6.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-aspects/3.1.0.RELEASE/spring-aspects-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-jdbc/3.1.0.RELEASE/spring-jdbc-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-jms/3.1.0.RELEASE/spring-jms-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-orm/3.1.0.RELEASE/spring-orm-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-tx/3.1.0.RELEASE/spring-tx-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-webmvc/3.1.0.RELEASE/spring-webmvc-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-asm/3.1.0.RELEASE/spring-asm-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-beans/3.1.0.RELEASE/spring-beans-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-context/3.1.0.RELEASE/spring-context-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-aop/3.1.0.RELEASE/spring-aop-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-context-support/3.1.0.RELEASE/spring-context-support-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-core/3.1.0.RELEASE/spring-core-3.1.0.RELEASE.pom
ok http://repo1.maven.org/maven2/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.pom
ok http://repo1.maven.org/maven2/org/springframework/spring-expression/3.1.0.RELEASE/spring-expression-3.1.0.RELEASE.pom

No failures.

Now I'm perplexed - it isn't because of dependencies in the Grails artifacts.