Enterprise Architect
Pratik Patel wrote the first book on 'enterprise Java' in 1996, "Java Database Programming with JDBC." He has also spoken at various conferences such as the Net Database Summit, WWW7 and the Atlanta Java User's Group (AJUG).Pratik's specialty is in large-scale Java applications for mission-critical use. He has designed and built enterprise applications in the retail, health care, financial services, and telecoms sectors. Pratik holds a master's in Biomedical Engineering from UNC, has worked in places such as New York, London, and Hong Kong, and currently lives in Atlanta, GA.
Presentations by Pratik Patel
Shell++ : Creating a "Groovy" shell for your application
We've all written shell scripts and command line Java applications for helper and troubleshooting purposes. Using Groovy we can combine the best of both worlds - a lightweight scripting language for utility purposes and the ability to reach into your Java library to interact easily with your main application. But why stop there? You can also easily extend the standard Groovy Shell to create a general-purpose, easily extensible command line client.Getting started with Google AppEngine
Google AppEngine is a new cloud computing deployment platform based on Python and Django. More than just static web hosting, Google AppEngine allows you to deploy a real web application. The Rails-like framework for Python called Django is the basis for this new platform. Best of all, Google AppEngine provides a free allowance that is more than enough for most basic personal and commercial websites. Learn how to get setup with Google AppEngine and how to write a web application for deployment into the cloud.Rapid AJAX apps with Grails & Dojo
Grails is a powerful tool for developing web applications quickly. In this presentation, we'll look at some of the excellent Grails plugins for developing cool AJAX apps in a short amount of time. We'll cover some Grails basics while setting up the demo application - then we'll add some eye candy using little or no Javascript to the webapp.Basic JPA & JPAQL
Doing basic Object-to-Relational Mapping is fun and easy with JPA. Annotate your persistent classes, define a couple of configuration parameters, and you're off and running. This session starts with a basic object model and adds persistence using annotations. Learn how to do mappings for your object model for simple and complex relationships. Also learn how to map Java5 constructs like Enumerations.Unit testing with JPA can be tricky. Where do you use mock objects? How can I structure my unit tests to exercise my DAO's effectively? How do I unit test JPAQL? Do I need to enhance or can I use a LoadTimeWeaver in my unit tests? This presentation will show, using live code examples, how to effectively unit test JPA components so developers can have confidence in the code they build using JPA.
Enterprise JPA - Tips and Tricks for JEE5 Persistence
As with many technologies, the basics are easy. The hard part comes when the developer needs to do sophisticated integration, development, and testing as part of an enterprise application. A large enterprise application requires the developer to think of issues that affect the development, scalability and robustness of the application. This presentation will cover the advanced topics described below.A large enterprise application often will have several sub-projects that each contain their own JPA persistence unit. This opens up a number of questions around how to organize the persistence units and how the code between sub-projects should interoperate. Developers will gain insight into these issues and will see a couple of solutions using live code examples.
Real-world JEE performance tuning: Tips n' Tricks
Performance tuning any application is a black art that can consume much time. Fortunately, Java has many tools that can aid in this effort. There also are a number of basic tips that can help to analyze and fix performance problems. The Java memory model is usually something that you don't need to tune, but for high performance applications it is necessary to tweak. While there are a number of advanced things that can be done to performance tune an application, we'll discover that the simple, basic things are all that are usually needed to make your apps fly.Books by Pratik Patel
by Pratik Patel
- The first book on JDBC in 1996. No longer in print.
- Available At: http://search.barnesandnoble.com/booksearch/isbninquiry.asp?..
The Artful Blogger
prpatel's weblog
Friday, August 8, 2008
In preparation for my upcoming No Fluff Just Stuff session in Cincinnati, I decided to finally rework the code example to use Hibernate as the JPA provider - rather than using OpenJPA. Don't get me wrong, OpenJPA is a great persistence framework. However it has fewer features and is less widely supported than Hibernate. One of the things I wanted to add to the 'Entperprise JPA' session was to show some reuse of JPA persistent objects with other frameworks, specifically, Grails. Grails is my favorite web development platform now-a-days, and it is built on top of Hibernate and Spring. I already use Spring heavily in the JPA sessions' demo code, and being able to reuse the JPA PC's with Grails would make for an awesome demo, and also show a real-world value add in using JPA. Grails doesn't support "generic" JPA yet, though it's on the roadmap. Frankly, I don't think Grails should attempt to support JPA until JPA 2.0 hits the streets - it would just be too much work to bridge JPA 1.0 to the dynamic queries that Grails supports now with Hibernate - for the sake of 6 months when JPA 2.0 will be out. Of course, in my sessions I remind attendees that to do real work, you have to use JPA implementation specific extensions anyways (just like Grails does to do many of the cool things GORM provides).
Using OpenJPA in a Maven 2 based project was so simple - just add the OpenJPA dependency in the pom.xml and that's basically it! It loads all the OpenJPA dependencies all by itself, and everything just worked. Initially, I thought that putting in Hibernate support would be just as easy. Unfortunately, it wasn't - I finally broke down and deciphered the Hibernate Compatibility Matrix and got it all put together. Even with the matrix handy, it still took some trial and error. In the hopes of saving somebody else some angst getting a pom.xml with Hibernate dependencies working, I've included the one that worked for me below.
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>CallTracker</groupId>
<artifactId>JPA</artifactId>
<name>CallTracker</name>
<version>1.0</version>
<description>Tracks Conference Calls </description>
<dependencies>
<dependency>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>1.8.0.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>2.5.5</version>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>8.3-603.jdbc4</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.6.ga</version>
<exclusions>
<exclusion>
<groupId>javax.transaction</groupId>
<artifactId>jta</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-tools</artifactId>
<version>3.2.0.ga</version>
</dependency>
<dependency>
<groupId>geronimo-spec</groupId>
<artifactId>geronimo-spec-jta</artifactId>
<version>1.0-M1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>3.0.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-commons-annotations</artifactId>
<version>3.3.0.ga</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.2.GA</version>
</dependency>
</dependencies>
</project>
Monday, July 14, 2008
I've been (very) slowly hacking away at new-and-improved Dojo plugin for Grails. I've found that Dojo, not Grails, has been my bottleneck - primarily because I'm not a Javascript wizard. I might break down and buy one of the 3 new Dojo books that hit the shelves in the last month (note to publisher: if you want a nice review written up, send me the ebook :) )
Dojo Grid JSON Scaffold
I took a try at creating a completely dynamic Dojo grid scaffold: tell it where to find your JSON, and it will just create a grid based on what's in the JSON. It's obviously not gonna be pretty, but for quick-n-dirty grids, it works pretty good. I've found it's a nice way to throw into a Dojo grid any data contained in a server-side list object. You have to convert it to JSON, but the Grails JSONBuilder makes that pretty easy.
JSON
{"items":[
{"id":1,"class":"Book","author":"Dierk Koenig","price":35,"title":"Groovy in Action"},
{"id":2,"class":"Book","author":"Graeme Rocher","price":25,"title":"The Definition Guide to Grails"},
{"id":3,"class":"Book","author":"Gavin King, Christian Bauer","price":35,"title":"Java Persistence with Hibernate"}
]}Note that the Dojo ItemFileReadStore requires that the JSON be in an "items" collection.
Grails JSONBuilder
import grails.converters.JSON
...
def listJSON = {
if (!params.max) params.max = 10
def json = [items:Book.list(params)]
render json as JSON
}
This is so easy using the Grails JSON converter it should be illegal. Again, note how the "items" collection was used to wrap the actual collection of Books.
The Dojo Javascript scaffold
I started with a post I found in the Dojo mail list but it didn't work, so I ended up re-writing it. Here's the Javascript to call the above listJSON server-side action:
dojo.addOnLoad(go);
function go() {
var rowbar = {
type: 'dojox.GridRowView', width: '20px'
};
var rows = {cells: [[
{ name: "dummy", field: "dummy" }
]]
};
var layout = [rowbar, rows];
this.jsonStore = new dojo.data.ItemFileReadStore({url: '/dojodev/book/listJSON'});
this.dataModel = new dojox.grid.data.DojoData(null, null, {store:this.jsonStore,query:"",clientSort:true});
this.dataModel.findAdditionalFields = function(items, columns)
{
console.log("findAdditionalFields called");
var item = items[0];
console.debug("item", item);
for (var j in item)
{
console.debug("j:", j);
if (j != '__id' && j[0] != '_' && j != 'class')
{
columns.push({name: j, field:j, width:'auto'});
}
}
// we want to keep the rowbar so just change the rows, i.e. layout[1]
layout[1].cells[0] = columns;
grid.setStructure(layout);
}
this.dataModel.processRows = function(items, request)
{
console.log("processRows called");
columns = [];
this.findAdditionalFields(items, columns);
// do the default behavior now
return dojox.grid.data.DojoData.prototype.processRows.apply(this, arguments);
}
dojo.connect(this.jsonStore, "onSet", null, function(item, attr)
{
console.log("onSet called");
// check to see if we have a new property, might need to redo the columns
for (var i = 0; i < columns.length; i++)
{
if (columns[i].field == attr)
{
return;
}
}
this.dataModel.findAdditionalFields([item], columns);
});
var gridProps =
{
model: this.dataModel,
structure: layout
};
var grid = new dojox.grid.Grid(gridProps, dojo.byId("griddiv"));
grid.setStructure(layout);
grid.refresh();
}
Couple of things to note here. You'll need a empty div with id = "griddiv" and it only handles non-nested data.
Improvements welcome
I only dabble in Javascript, so leave a comment on how to improve this if you like. Standard disclaimers to the code apply.
Sunday, March 16, 2008
Shake off that St. Patrick's day hang-over by coming over to the AJUG meeting this Tuesday, March 18. I'll be giving a presentation on some JPA and Spring best practices in a talk titled "Enterprise JPA with Spring 2.5." I've been using JPA and Spring quite heavily over the past year and am quite pleased with the development productivity and stability of both Spring and OpenJPA. Transitioning to Spring 2.5 and annotation based configuration required some careful thought - using the annotation based config can be cool, but whenever you introduce some 'automagic' behaviour in your codebase the results can be a little unexpected.
For those who have been using Spring and Hibernate, you will recognize much of what's presented. Hopefully people will share some of their experience and tips too! Again, here's the link to the location. Meeting starts at 7PM, and there's usually a crowd of Java geeks at the Garcia's Mexican around 5:30 for a little pre-dinner drinks and chat.
Wednesday, January 23, 2008
I've been working on integrating Grails and the recently released Dojo 1.0.2. I'm particularly interested in the Dijit components that are now part of Dojo. It seems like a clean, easy way to get some AJAX widgetry into a web application. Grails comes with plugins for common AJAX frameworks - YUI, Dojo 0.4.2(?), and Prototype. Someone's even released a nifty AJAX "dummies" plugin called richUI.
My main reason for undertaking this is to produce something that is easy and natural, but still very powerful. I want to leverage the new Dijit components, something the current Grails AJAX plugins do not do. I'm drawing on my experience with the Grails plugin system from an experiment I did this summer with integrating OpenLaszlo 4 with Grails. I even gave a presentation on doing a RIA using Grails and OL4 at the Atlanta JUG in July. Unfortunately, after working more and more with OL4, I decided it just wasn't a natural fit for Grails. But I digress...
The application: Grallery
I was looking around for a nice application to put some photos on the web, AKA a "web photo gallery". I have tens of thousands of digital pictures I've taken over the years, so using Picasa or some similar service was out of the question (I wonder how much it would cost to host 65G of pictures... hmmm). After hunting around for a nice Java based app to run on my server machine in the basement, I realized there wasn't anything that quite had the features of gallery2 (a PHP app). I thought this would be a perfect little project to undertake to learn about Dojo and Javascript - something I'd been putting off for a long time. Hence, Grallery was born. Over the next couple of months, I'll blog about my experiments on creating a Dojo/Dijit plugin for Grails.
Let's jump into the deep end and look at how Grails and Dojo work with data in JSON format. The two Dojo components we'll use are a image thumbnail viewer which is backed by a JSON data object.
Standard JSON that the Dojo ItemFileReadStore is expecting:
{"items":[ {"thumb":"/grallery/pictures/album1/thumbnails/thumbnail_pic7.jpg",
"large":"/grallery/pictures/album1/pic7.jpg",
"title":"pic7 comment",
"link":""
}
]}
Controller method to generate the JSON:
def thumbsJSON = {def album = Album.get(params.id)
def rootPath = '/grallery'
def basePath = rootPath + "/" + "pictures" + "/" + album.path
render(contentType: "text/json") {
items { for (picture in album.pictures) {pictures(thumb: "$basePath/thumbnails/thumbnail_$picture.filePath",
large: "$basePath/$picture.filePath",
title: "$picture.comment",
link: "")
}
}
}
}
Producing
JSON output is so ridiculously easy in Groovy & Grails, as the
above shows. The only "magic" that needs explaining is this line:
render(contentType: "text/json") {
The above line specifies to use the JSON Builder, which takes the contained closure as the parameter. Go here for a good tutorial on builders in Groovy.
GSP for the Dojo ItemFileReadStore:
function initItemStoreWidget(){ var itemRequest = { query: {},count: 1
};
var itemNameMap = {imageThumbAttr: "thumb",
imageLargeAttr: "large"
};
dijit.byId('thumbPicker2').setDataStore(imageItemStore, itemRequest, itemNameMap);
}
dojo.addOnLoad(initItemStoreWidget);
<div id="thumbPicker2" dojoType="dojox.image.ThumbnailPicker"
numberThumbs="1" isClickable="true" isHorizontal="true"></div>
<div jsId="imageItemStore" dojoType="dojo.data.ItemFileReadStore"
url="${createLinkTo(dir: 'album/thumbsJSON/' + album.id)}"></div>
The above code is using the ItemFileReadStore to populate the ThumbnailPicker Dojo widget.
The initItemStoreWidget function is used to tie the ItemFileReadStore (JSON data) to the ThumbnailPicker.
Next Time
Hopefully, this article has whet your appetite for some Dojo and Grails magic. This article presents a complex example that used JSON and a DojoX, or Dojo Experimental, widget called ThumbnailPicker. Using Dijit widgets, like calendars, buttons, and sliders is so easy, it's almost boring - as you'll see in the next installment coming soon.
Sunday, January 20, 2008
- Blog more
- Start publishing the stuff I've been doing with Grails & Groovy
- Start publishing the stuff I'm learning about JEE5 (and Glassfish)
I went to the Sun Tech Days in ATL last week. My buddy from AJUG, Mike, was there and gave me a copy of OpenSolaris 11 beta build78 (Developer Edition or something). After seeing the demos, I figured I would give it a shot.
It took a long time to install on my laptop. Almost 45 mins! Once the install finished, with some error that it wasn't able to complete, I just tried booting the OS rathering than trying the re-install again. The install had worked for the most part, it hadn't put Netbeans and some other dev tools on there.
It booted into the GUI (looks like Gnome?) and once I logged in, to my surprise, it asked me which wireless network I wanted to connect to... one click and I was online... started Firefox and I was surfing the web... awesome.
Java6 was installed on it already. I tried a few things like Netbeans and one of my Grails apps on it - it was noticeably faster than Windows XP. Which isn't hard, of course, but I put most of the performance gain down to the superiour filesystem, ZFS. My initial impression was mostly positive. Suspend/hibernate didn't work at all. I also felt that OpenSolaris 11 can run faster, it felt a bit sluggish, but no slower than Windows XP. Seeing as the installer didn't ask me for any installation options aside from partition and root password, I imagine things can be tuned to squeeze more performance out of my laptop. I've always used Solaris as a server OS, though I did have a Sun workstation about 13 years ago as a grad student at UNC.
The helpful people in the #opensolaris IRC chatroom helped me get accustomed to OpenSolaris by answering a few questions. So here's my wishlist for OpenSolaris 11:
- A software package manager like Synaptic
- Configuration widgets
- Suspend/Hibernate to work out-of-the box
- Run even faster :)
