Summer is here.
Things have been pretty busy for the past month or so and as such I’ve decided to take a quick jaunt to Kelowna. Family and friends there so it’s a good opportunity to relax and unwind.
Although it looks like the west coast rain we got this week is going to be following me inland. Here’s hoping that we see a return to the mid 35 degree celsius weather.
For the first time in awhile, the plan is to leave the laptop behind and completely unplug. We’re in the midst of some interesting conversations surrounding project resources so it’s a good opportunity to get away. With any luck, when I get back to the office next week I’ll be able to switch right back into new product development mode and have a (small) team of developers to help me out.
Cheers.
Being a long weekend, I had a couple hours yesterday to mess around with my Maven build in the hopes of integrating Groovy and ridding myself of a lot of Hibernate boilerplate (you know, all the annoying getters/setters).
I’m currently working on a Seam-based prototype and Groovy is certainly applicable to aspects other than Hibernate but it was a good initial goal.
Required POM Changes
<build>
<plugins>
<plugin>
<groupId>org.codehaus.groovy.maven</groupId>
<artifactId>gmaven-plugin</artifactId>
<version>1.0-rc-2</version>
<executions>
<execution>
<goals>
<goal>generateStubs</goal>
<goal>compile</goal>
<goal>generateTestStubs</goal>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
The gmaven plugin is able to cross-compile Java and Groovy. The compilation phase will generate Java stubs corresponding to the groovy classes prior to compiling the actual Java classes. This allows for seamless dependencies to exist between Groovy and Java.
It’s important to note that your Groovy sources must (by default) be in a src/main/groovy folder.
<dependencies>
<dependency>
<groupId>org.codehaus.groovy.maven.runtime</groupId>
<artifactId>gmaven-runtime-default</artifactId>
<version>1.0-rc-2</version>
</dependency>
</dependencies>
Results
Simple as that. Unit tests passed!
I’m able to take a class that looked like:
@Entity
public class Annotation
{
private Long id;
private String name;
private Specimen specimen;
private Patient patient;
/**
* Getter for property ‘id’.
*
* @return Value for property ‘id’.
*/
@Id @GeneratedValue
public Long getId()
{
return id;
}
/**
* Setter for property ‘id’.
*
* @param id Value to set for property ‘id’.
*/
public void setId(Long id)
{
this.id = id;
}
…
}
and make it look like:
@Entity
public class Annotation
{
@Id @GeneratedValue
Long id;
@Length(max=50) @NotNull
String name;
@ManyToOne @JoinColumn(name = “specimen_id”)
Specimen specimen;
@ManyToOne @JoinColumn(name = “patient_id”)
Patient patient;
}
Much simpler and without a lot of unnecessary boilerplate.
Gotchas
Just a couple of things to be aware of. Simple stuff really if you actually read documentation and know what you’re doing
Firstly, Groovy sources have to live in src/main/groovy.
Secondly, don’t add private modifiers to your attributes if you want the generated Groovy stubs to include getters/setters. This is probably more obvious if you’re creating your Groovy classes from scratch. I forgot to remove them when I was converting from a Java POJO and had a minor WTF moment.
Next step will be to see how much Groovy could potentially be leveraged for other aspects of the system.
For the past couple of days I’ve been attending the caBIG Annual Meeting (it’s the 5th such meeting and by all accounts the most well attended).
About caBIG
caBIG™ stands for the cancer Biomedical Informatics Grid™. caBIG™ is an information network enabling all constituencies in the cancer community – researchers, physicians, and patients – to share data and knowledge. The components of caBIG™ are widely applicable beyond cancer as well.
The mission of caBIG™ is to develop a truly collaborative information network that accelerates the discovery of new approaches for the detection, diagnosis, treatment, and prevention of cancer, ultimately improving patient outcomes.
In a nutshell, caBIG is an initiative of the National Cancer Institute built heavily upon open-source components that aims to motivate and facilitate the sharing of data. It strongly suggests a front-loaded UML workflow (using MDA) and incorporates certain aspects of ontologies and common data definitions to help guarantee consistent semantics (and syntax).
From a purely technical perspective, I’ve never been sold on the idea of MDA. I’ve had experience with both open-source and commercial modeling tools that have never fulfilled on the promise of true round-tripping (and if you don’t have round-tripping… well, you’re in for a world of hurt). Now in the caBIG case, there is a pipeline of transformations that you’re more or less required to run through…
- Create a UML representation of your object and domain models
- Annotate the model with caBIG specific annotations and stereotypes
- Run the annotated model through the Semantic Integration Workbench (another caBIG tool)
- Submit the final model (XMI) to caBIG for approval and insertion into the caDSR (cancer data standards repository)
Make a change in the future and you’re more or less required to run through steps #1-4 again.
Once you have a validated UML model, you can then run through the caCORE SDK and generate skeleton code for a 3-tiered application consisting of (at a high level) a Hibernate data model, an external API and some middleware code to glue the API and data model together. Round-tripping is essentially non-existent from what I’ve heard and seen.
You’re done! Congratulations on achieving Silver-level compliance.
…
wait a second.
It’s a little bit too process heavy for my liking. I would have liked to see the NIH/caBIG be first and foremost focused on data interoperability and less on tools, particularly those that dictate particular workflows (like UML -> annotation -> MDA -> Code Generation).
I’d much rather see an extensible API with pluggable end-points, a meta data registration service and a suite of validation test cases. Define suitable goals and keep it simple. Provide suitable incentives and vendors will support it.
There’s more than one way to provide interoperability.
As a developer working on existing products that are considering support for caBIG, the requirement to fundamentally change my development process is a bit unnerving. Speaking generally, there’s no guarantee that everyone has UML models for their systems and even if they did, attempting to do full MDA transformations on them would be fairly ambitious.
That’s it for now. It’s been an interesting conference and I’ve learned a lot about the various initiatives and their progress. Off to visit customers in Cincinnati tomorrow!
We recently finished migrating our product from Java5 to Java6. The software migration itself went quite smoothly with only a couple unanticipated problems.
However we do have a number of developers on MacBook Pro’s (myself included) that began having problems with other Java-based applications after making Java6 their default JVM.
One such problem was with the popular Spark IM client. After upgrading to Java6 we started getting the following exception:
macos:/Applications/Spark.app/Contents/MacOS ajordens$ ./JavaApplicationStub
NSRuntime.loadLibrary(/usr/lib/java/libObjCJava.dylib) error.
java.lang.UnsatisfiedLinkError: /usr/lib/java/libObjCJava.A.dylib:
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1822)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1702)
at java.lang.Runtime.load0(Runtime.java:770)
at java.lang.System.load(System.java:1005)
at com.apple.cocoa.foundation.NSRuntime.loadLibrary(NSRuntime.java:127)
Revert back to Java6 and the problems disappeared.
Solution:
Reverting back to Java5 for a particular application was about the only suggestion I’ve seen that has actually worked.
Fortunately, you should be able to apply the change directly to the problem application’s Info.plist and not system-wide. Best of both worlds in a way.
Using the Spark example:
Edit /Applications/Spark.app/Contents/Info.plist and change the value associated with the JVMVersion key to be 1.5 instead of 1.5+.
Similar to a JNLP file, this will result in the runtime falling back to 1.5.0.
For the past couple of weeks I’ve been doing a bit of early development work with Seam, it’s been fun but not without annoyance.
The project is green field which in one respect is quite nice because of the freedom it presents with regards to technology and architecture choices, but on the flip side you’ve actually got to investigate these choices and do all the general project plumbing (build management, etc.).
This initial post will deal largely with a couple of build infrastructure issues and solutions.
1. Maven
Fortunately the Seam Framework guys have been publishing Maven artifacts for awhile now.
Unfortunately, information on suitable project archetypes to use has been scarce. Initial searches turned up a few examples that were a number of years old and quite dated.
I eventually found JBSEAM-2371 which provided a useful starting point project.
I had to download the parent Seam pom and make modifications to the artifact name in order to get mvn site-deploy working appropriately. Something about the site plugin not being able to create directories with spaces in them.
Current Status: Everything is working. SeamTest-based integration tests are working (using embedded-jboss and hsqldb). Both the Maven site and IntelliJ IDEA plugins create the appropriate output. Artifacts are being deployed into JBoss 4.2.2.GA as part of the install phase using cargo.
The project layout is somewhat like the following:
api/app1-api api/app2-api seam/app1/app1-web seam/app1/app1-ejb seam/app1/app1-ear seam/app2/app2-web seam/app2/app2-ejb seam/app2/app2-ear
2. Static Analysis
Nothing too out of the ordinary here.
I’ve currently setup Checkstyle and FindBugs.
Configuration is stored in a separate top-level build-resources artifact (with xml configurations stored in src/main/resources) and included as a build extension in the project pom.
<build>
...
<extensions>
<extension>
<groupId>a.b.c</groupId>
<artifactId>build-resources</artifactId>
<version>1.0-SNAPSHOT</version>
</extension>
</extensions>
</build>
3. API Development
One of the key components of this project will be an API.
Rather than go the SOAP web services route, we’re strongly considering going RESTful with JAX-RS/JSR 311 helping us get there.
Bill Burke, Angry Bill of JBoss fame, has been actively developing RESTeasy, an implementation of JSR 311. It integrates fairly nicely with a Seam deployment (annotate your stateless EJBs and modify your web.xml) and allows you to easily expose a RESTful API backed by stateless session beans.
It should also be possible to go with the reference implementation of the JSR 311, Jersey, although I suspect that the JBoss implementation will eventually have a nicer integration for users of their stack.
JBoss AS doesn’t currently ship with a JSR 311 implementation so I had to install the jax-rs API and resteasy implementation jars into server/default/lib as part of a separate bootstrap process. This allowed me to mark the dependencies as provided.
Conclusion
Things are working and most of the grunt project infrastructure work is behind me. It’s been a good opportunity to get more familiar with Maven but now it’s time to get cracking on requirements definition and prototyping!
If you’re interested in working on a Seam-based application in the BioIT/Data management space, leave a comment and we’ll be in touch.
I’m been sufficiently busy at work since getting back from San Francisco and haven’t had much opportunity to blog.
As part of the JavaOne experience, I’ve taken another look at Twitter and have been using it as a quasi micro-publishing platform. It’s somewhat entertaining and the barrier to tweet is sufficiently lower.
Nothing too exciting and I hope to get back into the blogging train of thought shortly. I’ve got plenty to talk about from some recent experiences in the land of Seam (JPA, Facelets, etc.) and Maven.
-
Pet Peeve: Don’t email my password to me in plain text You know the drill.
Signup for some random service on the internet
Receive a confirmation email with your account information
or
Forget a password for some random service ...
-
Eclipise Memory Analyzer (MAT) I must say the Eclipse Memory Analyzer looks pretty slick. There is some pretty good material over on the developers blog. Lastly, there was a talk on it ...
-
Open-source Web-based Code Review Tool: Rietveld Guido van Rossum, of Python fame, has recently released a Django-based application that enables web-based code reviews... Rietveld.
It supports any language and currently can hook into Subversion repositories. You ...
-
An implementation of the JVM in Javascript? Caught this over on JavaPosse Google Groups.
Essentially, some bright fellows over in Japan have developed a bytecode->javascript compiler. There's a demo floating around that took a Tetris ...
-
Facebook Chat? So it looks like the Facebook Chat service has finally started rolling out to my network (Facebook Chat has been mentioned previously).
Not quite sure how ...
Latest Entries
- Headed to Kelowna for a short vacation (and the laptop stays behind)
- Seam + Groovy + Maven : Nice Simple Hibernate POJOs
- Pet Peeve: Don’t email my password to me in plain text
- Eclipise Memory Analyzer (MAT)
- caBIG Annual Meeting - A developers perspective
- OS X + Java6: java.lang.UnsatisfiedLinkError: /usr/lib/java/libObjCJava.A.dylib
- Getting started with JBoss Seam and Maven
- Twitter + Me
- We’re Hiring : Java Geniuses, Lets Talk.
- JavaOne + You == Plague
Blogroll