O'Reilly's Deal of the Day today offers multiple benefits and is detailed at http://oreilly.com/store/dd-jpn.html. The obvious benefit to software developers is 50% off the price of their DRM-free ebooks that are available in numerous formats. As I have highlighted before and as their page states, "Ebooks from oreilly.com are DRM-free. You get lifetime access, multiple file formats, and free updates."
O'Reilly has made this deal even more attractive by providing a benefit to the relief effort associated with the recent earthquake and tsunami in Japan. Their page describes this: "O'Reilly, No Starch Press, and Tidbits will donate all revenues, less author royalties, from today's 'Deal of the Day' sales to the Japanese Red Cross Society."
The Deal of the Day page for today shows that the promotional code for this deal is DDJPN. Note that this deal applies to videos in addition to ebooks.
Dustin's Software Development Cogitations and Speculations My observations and thoughts concerning software development (general development, Java, JavaFX, Groovy, Flex, ...). Select posts from this blog are syndicated on DZone and Java Code Geeks and were formerly syndicated on JavaWorld.
Tuesday, March 22, 2011
Monday, March 21, 2011
JDK 7 JMX Platform Management Beans: A First Peek
One of the new features anticipated for JDK 7 is advertised in the Java SE 7 preview as Enhanced JMX Agent and MBeans. In this post, I look at portions of the enhanced JMX and MXBean support. Specifically, I briefly cover new-to-JDK7 PlatformManagedObject interface and ManagementFactory.getAllPlatformMXBeanInterfaces() method.
The JDK 7 New Features section on "Enhanced JMX Agent and MBeans" states the following about this area of new features:
One of the convenient methods available in the preview release (Milestone 12 AKA M12) version of JDK 7 (b134 in my case) is ManagementFactory.getAllPlatformMXBeanInterfaces(). The current documentation for this method indicates that this method has been available since 1.7 and states: "Returns a list of Class objects, subinterface of PlatformManagedObject, representing all management interfaces for monitoring and managing the Java platform."
The referenced PlatformManagedObject is an interface that is new with JDK 1.7. This interface is extended by new BufferPoolMXBean (part of java.nio package), ClassLoadingMXBean, CompilationMXBean, GarbageCollectorMXBean, MemoryManagerMXBean, MemoryMXBean, MemoryPoolMXBean, OperatingSystemMXBean, java.lang.management.PlatformLoggingMXBean (new to 1.7 but extends previously available java.util.LoggingMXBean in addition to extending
It is very easy to programatically access the available "management interfaces for monitoring and managing the Java platform" with the ManagementFactory.getAllPlatformMXBeanInterfaces() method. The next simple Groovy listing can be used to see these.
The script is so simple that it can be evaluated inline using Groovy's command line
This is shown in the next screen snapshot.
In both cases (script file or invoked inline), the output indicates several available interfaces for managing and monitoring:
In this case, there are the nine MXBeans in the java.lang.management package, one MXBean in the java.util.logging package, and one MXBean in the java.nio package. Additionally, there are four MXBeans provided in the platform-specific com.sun.management package. The four HotSpot-specific MXBeans extend the standard MXBeans of similar names and are HotSpotDiagnosticMXBean, GarbageCollectorMXBean, OperatingSystemMXBean, and UnixOperatingSystemMXBean.
Conclusion
The examples covered in this post demonstrate a few things of interest. It demonstrates direct use of ManagementFactory.getAllPlatformMXBeanInterfaces(), indirect use of the new PlatformManagedObject interface, and the ease of using Groovy to play with these new features.
The JDK 7 New Features section on "Enhanced JMX Agent and MBeans" states the following about this area of new features:
An implementation-specific enhanced JMX management agent, ported from JRockit, which makes it easier to connect to the platform MBean server through firewalls, together with a richer set of MBeans which expose additional information about the internal operation of the VM
One of the convenient methods available in the preview release (Milestone 12 AKA M12) version of JDK 7 (b134 in my case) is ManagementFactory.getAllPlatformMXBeanInterfaces(). The current documentation for this method indicates that this method has been available since 1.7 and states: "Returns a list of Class objects, subinterface of PlatformManagedObject, representing all management interfaces for monitoring and managing the Java platform."
The referenced PlatformManagedObject is an interface that is new with JDK 1.7. This interface is extended by new BufferPoolMXBean (part of java.nio package), ClassLoadingMXBean, CompilationMXBean, GarbageCollectorMXBean, MemoryManagerMXBean, MemoryMXBean, MemoryPoolMXBean, OperatingSystemMXBean, java.lang.management.PlatformLoggingMXBean (new to 1.7 but extends previously available java.util.LoggingMXBean in addition to extending
PlatformManagedObject), RuntimeMXBean, and ThreadMXBean. A side note here is that the new interface PlatformMXBean extends LoggingMXBean but does not add any new methods. Instead, its purpose is, as the documentation states, to "simply unif[y] LoggingMXBean PlatformManagedObject."It is very easy to programatically access the available "management interfaces for monitoring and managing the Java platform" with the ManagementFactory.getAllPlatformMXBeanInterfaces() method. The next simple Groovy listing can be used to see these.
The above Groovy script is simple, but is enough to print out the interface class names provided by the
ManagementFactory.getAllPlatformMXBeanInterfaces() method. The output from this simple script is shown next (I've included Java version information for reference).The script is so simple that it can be evaluated inline using Groovy's command line
-e option rather than calling an external script file with the simple command:groovy -e "java.lang.management.ManagementFactory.getAllPlatformMXBeanInterfaces().each{println it}"
This is shown in the next screen snapshot.
In both cases (script file or invoked inline), the output indicates several available interfaces for managing and monitoring:
interface java.lang.management.ClassLoadingMXBean interface java.lang.management.CompilationMXBean interface java.lang.management.MemoryMXBean interface java.lang.management.GarbageCollectorMXBean interface java.lang.management.MemoryManagerMXBean interface java.lang.management.MemoryPoolMXBean interface java.lang.management.OperatingSystemMXBean interface java.lang.management.RuntimeMXBean interface java.lang.management.ThreadMXBean interface java.util.logging.PlatformLoggingMXBean interface java.nio.BufferPoolMXBean interface com.sun.management.GarbageCollectorMXBean interface com.sun.management.OperatingSystemMXBean interface com.sun.management.UnixOperatingSystemMXBean interface com.sun.management.HotSpotDiagnosticMXBean
In this case, there are the nine MXBeans in the java.lang.management package, one MXBean in the java.util.logging package, and one MXBean in the java.nio package. Additionally, there are four MXBeans provided in the platform-specific com.sun.management package. The four HotSpot-specific MXBeans extend the standard MXBeans of similar names and are HotSpotDiagnosticMXBean, GarbageCollectorMXBean, OperatingSystemMXBean, and UnixOperatingSystemMXBean.
Conclusion
The examples covered in this post demonstrate a few things of interest. It demonstrates direct use of ManagementFactory.getAllPlatformMXBeanInterfaces(), indirect use of the new PlatformManagedObject interface, and the ease of using Groovy to play with these new features.
Friday, March 18, 2011
Google Gears Skidding to a Stop
It was announced earlier this week on the Google Gears Blog that Gears is being deprecated. This announcement points out that the emphasis has been on HTML5 instead of Gears for over a year. This deprecation means that "there will be no new Gears releases." Modern browsers that are expected to have much more complete HTML5 feature support (Firefox 4 and Internet Explorer 9) will not be supported in Gears and Gears will be removed from Chrome 12.
This announcement is significant for multiple reasons. First, it means that authors of applications using Gears will need to adjust their code for this eventuality. Second, this move serves as evidence that Google feels that HTML5 support among popular browsers is or soon my be sufficient to no longer need Gears. Indeed, Aaron Boodman ends the announcing post with this statement:
If the major browsers being to uniformly support these modern web application features, the standardized availability of these functions over use of a plug-in will certainly be welcome.
For those wishing to use Gears functionality past its support timeframe, Boodman reminds us that "the code itself will of course remain open source, and anyone is free to use it."
In Goodbye, Google Gears (Sniff!), Harry McCracken predicted (1 December 2009) the demise of Gears at the hands of HTML5. Besides the original Google Gears blog post warning about that this day would come, RIP Google Gears also recommended (in February 2010) that developers start looking for HTML5 alternatives to their Google Gears use.
There are numerous other posts analyzing what the now realized Google Gears Stoppage means: Death of Google Gears Makes Cloud Backup Harder, The End of Google Gears?, Google Says Farewell to Gears Project, Good-bye Google Gears, Hello HTML5, Google Gears Death Announced, and Google to Retire Gears in Favor of HTML5.
I find the just-referenced collection of posts interesting because they cover my mixed feelings on this announcement. On one hand, it is pleasant to think about having a standard-based, built-in mechanism for the features previously provided by Gears. On the other hand, it is always less than comforting to count on future browser consistency in implementation that is "almost ready." Sometimes, a bird in hand beats two in the bush. Because browsers without requisite HTML5 functionality will be used to some degree for some time even after these newer browsers come out of beta, many web developers can expect to need to use object detection to detect HTML5 support and fallback to Gears, Flash, and other alternatives for some time to come.
This announcement is significant for multiple reasons. First, it means that authors of applications using Gears will need to adjust their code for this eventuality. Second, this move serves as evidence that Google feels that HTML5 support among popular browsers is or soon my be sufficient to no longer need Gears. Indeed, Aaron Boodman ends the announcing post with this statement:
Our mission with Gears was to enable more powerful web applications. Over 5 releases, we added tons of APIs, enabling everything from offline access to parallel computation. Now that these features have all been adopted by browsers and have official W3C specs, they are available to more developers than we could have reached with Gears alone.
If the major browsers being to uniformly support these modern web application features, the standardized availability of these functions over use of a plug-in will certainly be welcome.
For those wishing to use Gears functionality past its support timeframe, Boodman reminds us that "the code itself will of course remain open source, and anyone is free to use it."
In Goodbye, Google Gears (Sniff!), Harry McCracken predicted (1 December 2009) the demise of Gears at the hands of HTML5. Besides the original Google Gears blog post warning about that this day would come, RIP Google Gears also recommended (in February 2010) that developers start looking for HTML5 alternatives to their Google Gears use.
There are numerous other posts analyzing what the now realized Google Gears Stoppage means: Death of Google Gears Makes Cloud Backup Harder, The End of Google Gears?, Google Says Farewell to Gears Project, Good-bye Google Gears, Hello HTML5, Google Gears Death Announced, and Google to Retire Gears in Favor of HTML5.
I find the just-referenced collection of posts interesting because they cover my mixed feelings on this announcement. On one hand, it is pleasant to think about having a standard-based, built-in mechanism for the features previously provided by Gears. On the other hand, it is always less than comforting to count on future browser consistency in implementation that is "almost ready." Sometimes, a bird in hand beats two in the bush. Because browsers without requisite HTML5 functionality will be used to some degree for some time even after these newer browsers come out of beta, many web developers can expect to need to use object detection to detect HTML5 support and fallback to Gears, Flash, and other alternatives for some time to come.
Monday, March 14, 2011
Software Development Isn't About Beans
The term bean counter is often used with a negative connotation. One of the negative connotations often associated with the term "bean counter" is that these folks are incapable of looking past quantitative measures to look into alternative measures that are more qualitative and/or intangible. In software development, bean counting is often particularly ineffective. Attempting to count beans to measure productivity or estimate future work often leads to disappointment and unsatisfied expectations. In this post, I look at some of the ways that software development managers attempt to count "beans" that are not really there or are not really indicative of what they're actually trying to measure.
Lines of Code Are Not Beans
Perhaps the most misleading and falsely assuring software development metric of all time is the infamous line of code. I have blogged previously on the unintended consequences associated with counting lines of code. The reason this is such a terrible metric is that it presumes that every line of source code is a bean that can be counted. There can be some value to measuring lines of code in a large aggregated sense, but any value in this metric is lost as the numbers of lines of code is reduced.
The "bean" assumption is that all lines of code are equally difficult to write and maintain. This is, of course, simply ridiculous. One programming language may be more difficult to write in then another, one developer make write faster than another, one piece of code is more difficult to write than another, and so on. Tactics such as trying to only compares lines of code for the same language or same team of developers might help, but the truth of it is that lines of code will always remain only useful in a very large macro perspective.
I have often found that fewer lines of code can be a little more challenging to write than a greater number of lines of code that do the same thing. In other words, it may take me longer to write fewer, more concise lines than it does to write longer verbose code. The paradox is that fewer lines of code may require more time to write (though often less time to maintain). Not all lines of code are created equal and any presumption of such is folly.
Developers Are Not Beans
Another area in which the bean counters like to count "beans" even when it makes little sense to do so is in terms of staffing. To the bean counter, developers are resources that are easily switched as needed. There is little concern about the differences in experience, skill, and skill set between developers. The idea is that any developer can be plugged into an position interchangeably with any other developer. This is absurd except for on the most trivial of projects.
The consequences of the terrible assumption that all developers are the same quality "bean" is one of the core covered topics in Frederick P. Brooks, Jr.'s software development management classic The Mythical Man-Month. In Chapter 2, Brooks states, the now famous quote, "The man-month as a unit for measuring the size of a job is a dangerous and deceptive myth." He adds, "The man-month is a fallacious and dangerous myth, for it implies that men and months are interchangeable" (Chapter 18, 2.6). Not everyone agrees that this presumption is a problem.
Requirements are Not Beans
Software requirements vary significantly in terms of difficulty involved in implementing them, but they still are often treated as beans of the same type. To the bean counter, implementing ten requirements sounds better than implementing one requirement, although in practice it may be that the single difficult requirement is for functionality that is far more useful than the ten smaller, simpler requirements. Great progress can be perceived in rapidly working off requirements only to become surprisingly slower when the more difficult requirements are encountered. To a bean counter, the "rapid initial productivity" followed by "reduced productivity" is baffling.
Defect Reports Are Not Beans
It is very difficult to resist the urge to count each defect report the same. In practice, there are vast differences in the difficulties of fixing different defects. Appropriate priority settings can help measure the differences in importance or value of defect reports, but it is more challenging to measure the real effort required to resolve a defect. One really nasty defect might require much more effort than numerous easier defects. To the bean counter, though, the expert who takes one week to work off the nasty defect appears less productive than the average developer who can work off many more than that of the easier defects in that same week. Not all bugs are created equal.
Other Bean Counter / Software Development Mismatches
In Open Cubicles Must Die, Jim Showalter discusses how smaller cubicles makes sense to bean counters who can only focus on quantitative measures and not on less tangible consequences such as reduced productivity.
Why Aren't There Software Development Beans?
Brooks's The Mythical Man-Month provides background into why software development tasks are not easily categorized as beans or widgets. Brooks states, "Programming is fun because it gratifies creative longings built deep within us and delights sensibilities." Brooks likens the programmer to the poet, stating, "The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air from air, creating by exertion of the imagination."
Software development is interesting because it combines technology with creativity. It is difficult to measure the "quality" of a poem, a painting, a sculpture, or other creative work of art via quantitative measures. It is similarly difficult to measure the significant creative portion of software development with quantitative measures. Only trivial and uninteresting software development (that which lacks need for creativity) can be measured with quantitative measures. The more challenging and interesting a software project is, and the more creativity it requires, the more difficult it is to measure the project's progress or estimate its costs using the quantitative measures discussed in this post. Software development tasks are not beans and cannot be counted or treated as such.
Why Insist on Beans Where There Aren't Any?
The bean counters don't uniformly misunderstand the nature of the software development business. Most of them understand that not all developers are the same, that not all lines of code are the same, that not all requirements are the same, and that not all defects are the same. The reason they continue to use these metrics like beans is that this is the only way they can make these things fit into their Excel spreadsheets, Microsoft Project projects, or other favorite bean counting tools.
The problem is that the measures described above and similar metrics are "countable" (quantifiable), but are typically so different from each other that counting them arbitrarily makes little sense. It would be like a bean counter counting lima beans, chili beans, coffee beans, and other types of beans as the same type of beans. If one was trying to make coffee or chili, it would matter which type of bean was available! The bean counter has the option to measure the beans by weight rather than by number. This might be a more accurate metric for certain needs. Because software development lacks physical entities that can be counted or weighed, we are stuck doing our best trying to assign "weights," but it is an inexact science.
We often talk in software development about the object-relational impedance mismatch, but a far more difficult such impedance mismatch may be the mismatch between the art of software development and the quantitative side of software development management.
Conclusion
For Java developers, there are many types of "beans" in software development: JavaBeans, Enterprise JavaBeans, JMX Managed Beans, Spring Beans, and so on. These are about the only beans in software development. There is too much creativity involved in software development to easily categorize components of it as beans. That doesn't mean we don't try or that we won't continue trying. After all, we've been doing it since before Brooks published The Mythical Man-Month in 1975.
Lines of Code Are Not Beans
Perhaps the most misleading and falsely assuring software development metric of all time is the infamous line of code. I have blogged previously on the unintended consequences associated with counting lines of code. The reason this is such a terrible metric is that it presumes that every line of source code is a bean that can be counted. There can be some value to measuring lines of code in a large aggregated sense, but any value in this metric is lost as the numbers of lines of code is reduced.
The "bean" assumption is that all lines of code are equally difficult to write and maintain. This is, of course, simply ridiculous. One programming language may be more difficult to write in then another, one developer make write faster than another, one piece of code is more difficult to write than another, and so on. Tactics such as trying to only compares lines of code for the same language or same team of developers might help, but the truth of it is that lines of code will always remain only useful in a very large macro perspective.
I have often found that fewer lines of code can be a little more challenging to write than a greater number of lines of code that do the same thing. In other words, it may take me longer to write fewer, more concise lines than it does to write longer verbose code. The paradox is that fewer lines of code may require more time to write (though often less time to maintain). Not all lines of code are created equal and any presumption of such is folly.
Developers Are Not Beans
Another area in which the bean counters like to count "beans" even when it makes little sense to do so is in terms of staffing. To the bean counter, developers are resources that are easily switched as needed. There is little concern about the differences in experience, skill, and skill set between developers. The idea is that any developer can be plugged into an position interchangeably with any other developer. This is absurd except for on the most trivial of projects.
The consequences of the terrible assumption that all developers are the same quality "bean" is one of the core covered topics in Frederick P. Brooks, Jr.'s software development management classic The Mythical Man-Month. In Chapter 2, Brooks states, the now famous quote, "The man-month as a unit for measuring the size of a job is a dangerous and deceptive myth." He adds, "The man-month is a fallacious and dangerous myth, for it implies that men and months are interchangeable" (Chapter 18, 2.6). Not everyone agrees that this presumption is a problem.
Requirements are Not Beans
Software requirements vary significantly in terms of difficulty involved in implementing them, but they still are often treated as beans of the same type. To the bean counter, implementing ten requirements sounds better than implementing one requirement, although in practice it may be that the single difficult requirement is for functionality that is far more useful than the ten smaller, simpler requirements. Great progress can be perceived in rapidly working off requirements only to become surprisingly slower when the more difficult requirements are encountered. To a bean counter, the "rapid initial productivity" followed by "reduced productivity" is baffling.
Defect Reports Are Not Beans
It is very difficult to resist the urge to count each defect report the same. In practice, there are vast differences in the difficulties of fixing different defects. Appropriate priority settings can help measure the differences in importance or value of defect reports, but it is more challenging to measure the real effort required to resolve a defect. One really nasty defect might require much more effort than numerous easier defects. To the bean counter, though, the expert who takes one week to work off the nasty defect appears less productive than the average developer who can work off many more than that of the easier defects in that same week. Not all bugs are created equal.
Other Bean Counter / Software Development Mismatches
In Open Cubicles Must Die, Jim Showalter discusses how smaller cubicles makes sense to bean counters who can only focus on quantitative measures and not on less tangible consequences such as reduced productivity.
Why Aren't There Software Development Beans?
Brooks's The Mythical Man-Month provides background into why software development tasks are not easily categorized as beans or widgets. Brooks states, "Programming is fun because it gratifies creative longings built deep within us and delights sensibilities." Brooks likens the programmer to the poet, stating, "The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air from air, creating by exertion of the imagination."
Software development is interesting because it combines technology with creativity. It is difficult to measure the "quality" of a poem, a painting, a sculpture, or other creative work of art via quantitative measures. It is similarly difficult to measure the significant creative portion of software development with quantitative measures. Only trivial and uninteresting software development (that which lacks need for creativity) can be measured with quantitative measures. The more challenging and interesting a software project is, and the more creativity it requires, the more difficult it is to measure the project's progress or estimate its costs using the quantitative measures discussed in this post. Software development tasks are not beans and cannot be counted or treated as such.
Why Insist on Beans Where There Aren't Any?
The bean counters don't uniformly misunderstand the nature of the software development business. Most of them understand that not all developers are the same, that not all lines of code are the same, that not all requirements are the same, and that not all defects are the same. The reason they continue to use these metrics like beans is that this is the only way they can make these things fit into their Excel spreadsheets, Microsoft Project projects, or other favorite bean counting tools.
The problem is that the measures described above and similar metrics are "countable" (quantifiable), but are typically so different from each other that counting them arbitrarily makes little sense. It would be like a bean counter counting lima beans, chili beans, coffee beans, and other types of beans as the same type of beans. If one was trying to make coffee or chili, it would matter which type of bean was available! The bean counter has the option to measure the beans by weight rather than by number. This might be a more accurate metric for certain needs. Because software development lacks physical entities that can be counted or weighed, we are stuck doing our best trying to assign "weights," but it is an inexact science.
We often talk in software development about the object-relational impedance mismatch, but a far more difficult such impedance mismatch may be the mismatch between the art of software development and the quantitative side of software development management.
Conclusion
For Java developers, there are many types of "beans" in software development: JavaBeans, Enterprise JavaBeans, JMX Managed Beans, Spring Beans, and so on. These are about the only beans in software development. There is too much creativity involved in software development to easily categorize components of it as beans. That doesn't mean we don't try or that we won't continue trying. After all, we've been doing it since before Brooks published The Mythical Man-Month in 1975.
Monday, March 7, 2011
Better JDBC With Groovy Sql
I don't mind using JDBC directly in many of the Java applications I work with, especially when using it in conjunction with Spring's JDBC support or with a simple SQL mapping framework like MyBatis. Groovy makes using JDBC particularly pleasant. I appreciate the combination of powerful flexibility of direct SQL with the ease and convenience of Groovy's treatment of JDBC. In this post, I look at various helpful aspects of Groovy's Sql class.
I looked at a basic and common use of Groovy's
For convenience, the following Groovy code listing demonstrates accessing an instance of
Beginning of demoGroovySql.groovy Script
Although the overloaded Sql.eachRow methods are often exactly what's needed to iterate over a result set and apply a closure to each row of the result set, this is not the only Groovy approach to querying the database. Another approach is to instruct Groovy to simply access the first row of the underlying result set. This is particularly useful when it is known that only one result will be returned, which is case in the frequent situation of querying based on the primary (unique) key. The next example demonstrates using Sql.firstRow(String, Object[]) to get a single row out of a result set.
Using Sql.firstRow(String, Object[])
As demonstrated in the above code listing, there is no need to use a closure or its implicit
There may be times when one needs direct access to the result set from the database query. In such cases, use of one of the overloaded Sql.query methods is apropos. In other situations, it might be most convenient to have the rows of the result set as a collection of these rows. This structure is obtained by invoking one of the overloaded Sql.rows methods. This might be preferred in situations where traditional Java iteration is preferred over use of the
The Groovy
The next Groovy code snippet shows use of the
The Groovy
Note that the same string with SQL insert command was used in both cases and it was simply a matter of which
The Sql.executeUpdate(String) [and its overloaded versions] are handy to use when one wants to check the returned integer to know how many rows were updated. This is demonstrated in the next Groovy code listing.
Stored procedures and stored functions can also be executed using Groovy's
The above example demonstrates calling an Oracle function and it demonstrates supplying Sql.INTEGER as an OutParameter.
Additional details regarding Groovy's database support can be found in the groovy.sql.Sql documentation (a nice example of how Javadoc documentation can provide examples of how to use the class), in the Database Features section of the Groovy User Guide, and in Practically Groovy: JDBC Programming with Groovy.
I find myself frequently accessing databases with my Groovy scripts. Database access has always been relatively straightforward in Java via JDBC, but Groovy makes this database access even more concise and fluent.
I looked at a basic and common use of Groovy's
Sql class in the post GroovySql: Groovy JDBC. I began that post by looking at using Groovy's basic result set processing closure (Sql.eachRow) as an example of the Read/Retrieve portion of CRUD. I then demonstrated simple examples of CRUD operations Create and Delete using Sql.execute(String) and Sql.execute(String, List). Groovy's Sql class provides significantly more functionality than this and I demonstrate some of those methods here.For convenience, the following Groovy code listing demonstrates accessing an instance of
Sql and using it to query the Oracle hr/hr sample schema and process the result set. The example includes usage of rootLoader to avoid needing to provide the JDBC driver on the script's classpath explicitly.Beginning of demoGroovySql.groovy Script
#!/usr/bin/env groovy
// Add JDBC driver to classpath as part of this script's bootstrapping.
// See http://marxsoftware.blogspot.com/2011/02/groovy-scripts-master-their-own.html.
// This location needs to be adjusted for specific user environment.
this.class.classLoader.rootLoader.addURL(
new URL("file:///C:/app/Dustin/product/11.1.0/db_1/jdbc/lib/ojdbc6.jar"))
// Get instance of Groovy's Sql class
// See http://marxsoftware.blogspot.com/2009/05/groovysql-groovy-jdbc.html
import groovy.sql.Sql
def sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:orcl", "hr", "hr",
"oracle.jdbc.pool.OracleDataSource")
// iterate over query's result set and "process" each row by printing two names
sql.eachRow("SELECT employee_id, last_name, first_name FROM employees")
{
println "Employee ${it.first_name} ${it.last_name} has ID of ${it.employee_id}."
}
Although the overloaded Sql.eachRow methods are often exactly what's needed to iterate over a result set and apply a closure to each row of the result set, this is not the only Groovy approach to querying the database. Another approach is to instruct Groovy to simply access the first row of the underlying result set. This is particularly useful when it is known that only one result will be returned, which is case in the frequent situation of querying based on the primary (unique) key. The next example demonstrates using Sql.firstRow(String, Object[]) to get a single row out of a result set.
Using Sql.firstRow(String, Object[])
// when you know there's only one match, firstRow can be particularly useful
def employee140 = sql.firstRow("SELECT employee_id, last_name, first_name FROM employees where employee_id = ?", [140])
println "Employee 140 is ${employee140.first_name} ${employee140.last_name}"
As demonstrated in the above code listing, there is no need to use a closure or its implicit
it variable because there is only a single object returned from Sql.firstRow. This object's properties are accessed by the same names as the underlying database columns. The few lines of the above example perform the query, extract the first row in the result set, and provide easy access to that row's values. All too easy.There may be times when one needs direct access to the result set from the database query. In such cases, use of one of the overloaded Sql.query methods is apropos. In other situations, it might be most convenient to have the rows of the result set as a collection of these rows. This structure is obtained by invoking one of the overloaded Sql.rows methods. This might be preferred in situations where traditional Java iteration is preferred over use of the
Sql.eachRow's closures.The Groovy
Sql class provides several approaches for inserting (creating) data (the "c" in CRUD). One such method is the Sql.executeInsert(String) method. This method's documentation states that this method "executes the given SQL statement (typically an INSERT statement)" and adds, "Use this variant when you want to receive the values of any auto-generated columns, such as an autoincrement ID field."The next Groovy code snippet shows use of the
Sql.executeInsert(String) method. A screenshot is shown after the code listing which shows the results of running this code. As that output shows, the returned ID in this case is an Oracle ROWID. The ROWID is shown in both of the lines output with a println invocation.// insert new employee with Sql.executeInsert
def insertStr =
"""insert into employees
(employee_id, first_name, last_name, email, hire_date, job_id)
values
(employees_seq.nextval, 'Dustin', 'Marx', 'dustin@marxiansw.com',
to_date('2011/02/28', 'yyyy/mm/dd'), 'IT_PROG')"""
def insertedEmployees = sql.executeInsert(insertStr)
println insertedEmployees.dump()
def insertedEmployeeId = insertedEmployees[0][0].toJdbc()
println "Employee ${insertedEmployeeId} added."
The Groovy
Sql class supports a more traditional insertion via its Sql.execute(String) method (which can also be used for running DDL and other types of DML statements). The next code listing demonstrates this.// insert new employee with Sql.execute
def insertStr =
"""insert into employees
(employee_id, first_name, last_name, email, hire_date, job_id)
values
(employees_seq.nextval, 'Dustin', 'Marx', 'dustin@marxiansw.com',
to_date('2011/02/28', 'yyyy/mm/dd'), 'IT_PROG')"""
def employeeInserted = sql.execute(insertStr)
Note that the same string with SQL insert command was used in both cases and it was simply a matter of which
Sql method was desired. It is important to also note that there are overloaded versions of these methods that allow parameters to be passed. This is usually a better approach because it provides the advantages of using a PreparedStatement. I showed use of the Sql.execute method with parameters for deletion and for insertion in my post GroovySql: Groovy JDBC.The Sql.executeUpdate(String) [and its overloaded versions] are handy to use when one wants to check the returned integer to know how many rows were updated. This is demonstrated in the next Groovy code listing.
// update the previously added employee
def updateStr =
"""update employees set email='dustin@marxblog.com'
where employees.first_name='Dustin' and employees.last_name='Marx'"""
def numberRowsUpdated = sql.executeUpdate(updateStr)
println "${numberRowsUpdated} row(s) was/were updated."
Stored procedures and stored functions can also be executed using Groovy's
Sql class. The next Groovy code listing demonstrates this in calling the Oracle supplied (built-in) function DBMS_UTILITY.GET_TIME().// invoke PL/SQL stored procedure with Sql.call
def storedProcCall =
"""{? = call dbms_utility.get_time()}"""
sql.call(storedProcCall, [Sql.INTEGER])
{
println "DBMS_UTILITY.GET_TIME(): ${it}"
}
The above example demonstrates calling an Oracle function and it demonstrates supplying Sql.INTEGER as an OutParameter.
Additional details regarding Groovy's database support can be found in the groovy.sql.Sql documentation (a nice example of how Javadoc documentation can provide examples of how to use the class), in the Database Features section of the Groovy User Guide, and in Practically Groovy: JDBC Programming with Groovy.
I find myself frequently accessing databases with my Groovy scripts. Database access has always been relatively straightforward in Java via JDBC, but Groovy makes this database access even more concise and fluent.
Saturday, March 5, 2011
My Thoughts on Thoughts on Developer Longevity
Davy Brion's post Thoughts on Developer Longevity has received considerable attention in the blogosphere as evidenced by the following statistics (as of this writing):
The post begins with this introduction:
The post has some points which I completely agree with. For example, many organizations do "reward" or "expect" that the best developers will be managers when they "grow up." As the post states, others do move into management essentially because they find the repetition of software development less interesting or less challenging than they used to and think there are more interesting (or more effective) tactics employed in management. Bruce Eckel provides an excellent example of the latter: one would be hard-pressed to say the the author of Thinking in C++ and Thinking in Java is not "any good in this industry," but Eckel has started changing interests. Note that Eckel is still heavily involved in the industry, but his interests are obviously broadening. Some might argue this is a natural maturation and evolution of the best overall software engineers who understand there is more to software development than coding.
I also agree with Brion's two pieces of advice for developers who want to maintain heavily involved in coding even after they turn forty. Brion recommends "keep feeling stupid" and "question what you know and think, all the time.". I have written about similar concepts in my post Are You the Best Developer You Know? and a commenter left a similar comment on his post.
Although many of the post author's observations are similar to my own, there are also some aspects of this post that I believe are misguided or perhaps a little naive, perhaps because of the perceived youth of the author. I believe many of these are due to coming to sweeping conclusions based on limited exposure to a limited piece of the software development industry. For example, it may be true that "there really aren't that many older developers that are any good in this industry" in some of the tinker toy application development projects or in some of the many projects that dominate the blogosphere. However, in more complex domains where mathematical algorithms and deep scientific knowledge are involved, I've found that the older developers generally outshine their younger, less experienced counterparts. Even the most talented young developer has a difficult time competing with the breadth and depth of knowledge acquired over years or even decades of working in such domains.
Brion's post is an example of how a post with appropriate title and subject can lead to interesting and useful community discussion. His post is worth reading in and of itself, but the comments on his post are at least equally insightful. In the remainder of this post, I look at how some of these comments reflect some of my own observations.
Our World is Not The World
In the movies Men in Black and Men in Black II, there is a recurring theme that even the Men in Black themselves don't realize their relationship to the outer world(s). The first movie ends with a scene showing huge extraterrestrial beings placing with the planet Earth as if it is a marble. The second movie shows Agent Jay's and Agent Kay's residence (again, the Earth) simply being one of many lockers in another world's locker area. The point is that there is a much bigger world out there than the one which they live in and know. They don't know it's out there and so think the whole world is what they do know. In a sense, it's easy in any aspect in life (including development) to make sweeping judgments about the world in general or software development in particular based on our own little piece of that space. We cannot help it because we simply don't know better and often don't realize what we don't know or are missing.
It's likely that there are some projects or areas or organizations where there are few to no strong developers over forty. Having stated that, I'm aware of colleagues working on some projects and products who don't have anyone under 35 on their team because they require breadth and depth that simply aren't generally available in developers with less than 10 years experience. In either situation, it would be all too easy to make erroneous conclusions and stereotypes about developers of different age groups.
Ryan Cromwell left a short but insightful comment along these lines on that post: "I know plenty of very good 40+ developers. Be careful not to assume your world is the norm."
Achilleas Margaritis's comment on this post is also insightful in this regard:
In the comments section, TedT writes, "You probably don't know any because your hyper cool little startup discriminates by age so they won't hire anyone that doesn't look exactly themselves" and Nunya Biznes writes, "I don't know where you work or have worked that there are no developers over 40."
What, There's More to Life?
Ian Smith left another insightful comment on this post:
I've definitely observed this. It does seem that many developers change their interests (some might say develop a better perspective) as they approach the age of forty. For many developers in this age group, new family and/or personal considerations take on a new level of importance. Time for "playing" with the latest technology can become more limited as demands for their time increase. Some developers simply want to try something new. This is not all that unusual because I think there is some satisfaction to learning more about an area in which one knows very little.
The Software Craftsman
I'm a believer in the concept of software craftsmanship. It's difficult to believe that someone can become a "craftsman" in anything in one or two years. It's far more believable that someone can become a true craftsman after many more years (seven years is often used in other industries) of experience.
The Value of History
In The Life of Reason, George Santayana stated, "Those who cannot remember the past are condemned to repeat it." Many of us have heard or even quoted a slightly altered form of this: "Those who don't know history are destined to repeat it." I have found that more experienced developers often have experience in certain areas that allows them to be better judges of whether the latest language, framework, or library is simply another passing fad or something really worth future investment and consideration. Software development is a cyclic industry in which a certain approach can be in fashion for a few years, fall out of fashion for a few years, and come back into fashion again for a few years. The more experienced software developers are less likely to be easily swayed by the Lemming Effect.
Mike has an interesting comment related to this:
I have envied some of the instinctive skills I have witnessed some developers older than me illustrate and I have been on the other end as well when I have had younger developers ask "How did you know how to do that?" and I was able to trace it back to an experience on an earlier project.
I like baeocystin's comment on the "Thought on Developer Longevity" post: "You ask some good questions, but you should add one more- what do these intelligent, experienced ex-developers know that you don't?"
Not All Experience is Created Equal
It is my opinion that twenty years working with multiple domains, multiple problems, and multiple customer needs is far more significant and useful than twenty years doing the same thing. This has been described as the difference between doing the same thing twenty times or doing twenty different things. I extend this to learning new languages, frameworks, and tools. Although I think there's tremendous value in learning new languages and tools, my feeling is that I'd rather have a developer who knows a small number of languages well and has applied them in diverse situations over the developer who knows numerous languages but has used them all for solving the same basic or simple problem. Knowing how to write "Hello, World" in 35 different languages is not a very useful skill in and of itself. The developer who can solve complex problems in a particular language is more likely to be able to pick up a new language for solving another complex problem than the person knowing a bunch of languages only used in simple applications.
Disadvantages for More Experienced Developers
There's no question that experienced developers do face some disadvantages. While their experience can help them avoid the Lemming Effect, they can go too far the other way and not be willing to consider anything new or doing something a different way. This is covered in Brion's post. Other posts on disadvantages of experienced developers include How Experienced Developers Can Handicap a Lean Startup and Older Developers: Bad Habits Are Killing Your Career. While there may be some gross stereotyping in some of these, I do think it's worth every developer's time to always consider whether he or she is letting established habits and comfort misguide decisions.
Early in my software development career, I observed several older software developers who had been effective in days of procedural programming, but really struggled with object-oriented languages. It was not that there people were unintelligent or slow-witted. On the contrary, they had implemented some sophisticated applications despite having significantly less tools to work with than we do today. Unfortunately, they had trouble making the mental shift from procedural style to what many of us do today (object-oriented with some procedural skeletons in the closet).
What is 'Good'?
A problem with any of these types of discussions surrounds the use of subjective terms like "good." This is pointed out well by the Foredecker comment that points out problems of perception of what makes a good developer. As the comment points out, perceived outward excitement is not necessarily an indicator of a better developer.
Examples of Software Developers Over 40 Who Are At Least 'Any Good'
There are numerous examples of good software developers over the age of forty. Tim O'Brien's comment on the "Thoughts on Developer Longevity" post is: "Most of the developers I know are over 40, and they are all so good at what they do they put everyone else to shame."
I previously mentioned Bruce Eckel, who is 53 years old according to Wikipedia. The first edition of Thinking in C++ was published when he was 42 years old and he was over 40 when the first edition of Thinking in Java was published.
According to Wikipedia, Bjarne Stroustrup was born in 1950, Tim Bray, James Gosling, Grady Booch, and Tim Berners-Lee were born in 1955 (what was in the water that year?), Martin Odersky was born in 1958, Josh Bloch and Kent Beck were born in 1961, Martin Fowler was born in 1963, and Yukihiro Matsumoto was born in 1965. I think we could find room on our team for any of these individuals.
Conclusion
The post Thoughts on Developer Longevity and its associated comments are well worth the read. I agree with Brion's assertions as often, but not always, true. My major disagreement is with the percentage or ratio of good/bad developers over age forty and I think this may be due to different experiences in our careers. In the end, Brion's reasoning for the post (to determine what drives developers to remain effective after age forty) is a good way to start potentially valuable community discussion. A user going by the name "Public" perhaps answered the question most succinctly: "I'm a 42 year old developer and my secret is this: love learning new things and spend the time to do so. There you go."
My experience has been that the most successful software development projects often are made up of a mixture of young developers who are already skilled and have even more potential with master craftsman who can guide the team through political and technological challenges they have seen many times before.


- 119 comments on the post itself
- 739 comments on the Reddit Programming link ("How many developers over 40 do you know?" - Thoughts on Developer Longevity)
- 10 known reactions (Tweets and the like)
The post begins with this introduction:
How many developers over 40 do you know? For quite a few of you, the answer will be 0. For those of you who do know of one or more developers over 40: how many of them are good? If you know any good developers over 40, then do yourself a favor: start picking their brain and figure out how they keep their skills sharp. Once you've done that, do us all a favor and publish it somewhere because there really aren't that many older developers that are any good in this industry.
The post has some points which I completely agree with. For example, many organizations do "reward" or "expect" that the best developers will be managers when they "grow up." As the post states, others do move into management essentially because they find the repetition of software development less interesting or less challenging than they used to and think there are more interesting (or more effective) tactics employed in management. Bruce Eckel provides an excellent example of the latter: one would be hard-pressed to say the the author of Thinking in C++ and Thinking in Java is not "any good in this industry," but Eckel has started changing interests. Note that Eckel is still heavily involved in the industry, but his interests are obviously broadening. Some might argue this is a natural maturation and evolution of the best overall software engineers who understand there is more to software development than coding.
I also agree with Brion's two pieces of advice for developers who want to maintain heavily involved in coding even after they turn forty. Brion recommends "keep feeling stupid" and "question what you know and think, all the time.". I have written about similar concepts in my post Are You the Best Developer You Know? and a commenter left a similar comment on his post.
Although many of the post author's observations are similar to my own, there are also some aspects of this post that I believe are misguided or perhaps a little naive, perhaps because of the perceived youth of the author. I believe many of these are due to coming to sweeping conclusions based on limited exposure to a limited piece of the software development industry. For example, it may be true that "there really aren't that many older developers that are any good in this industry" in some of the tinker toy application development projects or in some of the many projects that dominate the blogosphere. However, in more complex domains where mathematical algorithms and deep scientific knowledge are involved, I've found that the older developers generally outshine their younger, less experienced counterparts. Even the most talented young developer has a difficult time competing with the breadth and depth of knowledge acquired over years or even decades of working in such domains.
Brion's post is an example of how a post with appropriate title and subject can lead to interesting and useful community discussion. His post is worth reading in and of itself, but the comments on his post are at least equally insightful. In the remainder of this post, I look at how some of these comments reflect some of my own observations.
Our World is Not The World
In the movies Men in Black and Men in Black II, there is a recurring theme that even the Men in Black themselves don't realize their relationship to the outer world(s). The first movie ends with a scene showing huge extraterrestrial beings placing with the planet Earth as if it is a marble. The second movie shows Agent Jay's and Agent Kay's residence (again, the Earth) simply being one of many lockers in another world's locker area. The point is that there is a much bigger world out there than the one which they live in and know. They don't know it's out there and so think the whole world is what they do know. In a sense, it's easy in any aspect in life (including development) to make sweeping judgments about the world in general or software development in particular based on our own little piece of that space. We cannot help it because we simply don't know better and often don't realize what we don't know or are missing.
It's likely that there are some projects or areas or organizations where there are few to no strong developers over forty. Having stated that, I'm aware of colleagues working on some projects and products who don't have anyone under 35 on their team because they require breadth and depth that simply aren't generally available in developers with less than 10 years experience. In either situation, it would be all too easy to make erroneous conclusions and stereotypes about developers of different age groups.
Ryan Cromwell left a short but insightful comment along these lines on that post: "I know plenty of very good 40+ developers. Be careful not to assume your world is the norm."
Achilleas Margaritis's comment on this post is also insightful in this regard:
I am 38. The developer that sits at the right position of me is 44. The developer that sits at the left position of me is 43. The guy behind him is 55. The group of developers in the end of the office space is from 35 to 60.
Please don't consider people over 40 as old. They are not. While they are not as active as those in their 20s, they have lots of experience, they know algorithms, and they can easily learn new platforms due to their experience.
In the comments section, TedT writes, "You probably don't know any because your hyper cool little startup discriminates by age so they won't hire anyone that doesn't look exactly themselves" and Nunya Biznes writes, "I don't know where you work or have worked that there are no developers over 40."
What, There's More to Life?
Ian Smith left another insightful comment on this post:
You're missing one key reason why many leave the industry before 40. After 20+ years the whole "be happy with no life" approach to keeping up-to-date (always in your own time because firms don't bother with training any more) becomes kind of lame.
I've definitely observed this. It does seem that many developers change their interests (some might say develop a better perspective) as they approach the age of forty. For many developers in this age group, new family and/or personal considerations take on a new level of importance. Time for "playing" with the latest technology can become more limited as demands for their time increase. Some developers simply want to try something new. This is not all that unusual because I think there is some satisfaction to learning more about an area in which one knows very little.
The Software Craftsman
I'm a believer in the concept of software craftsmanship. It's difficult to believe that someone can become a "craftsman" in anything in one or two years. It's far more believable that someone can become a true craftsman after many more years (seven years is often used in other industries) of experience.
The Value of History
In The Life of Reason, George Santayana stated, "Those who cannot remember the past are condemned to repeat it." Many of us have heard or even quoted a slightly altered form of this: "Those who don't know history are destined to repeat it." I have found that more experienced developers often have experience in certain areas that allows them to be better judges of whether the latest language, framework, or library is simply another passing fad or something really worth future investment and consideration. Software development is a cyclic industry in which a certain approach can be in fashion for a few years, fall out of fashion for a few years, and come back into fashion again for a few years. The more experienced software developers are less likely to be easily swayed by the Lemming Effect.
Mike has an interesting comment related to this:
There is another possibility the author overlooks: younger coders' idea of what makes someone "good" is wrong. Refusing to jump on a fad until it's proven to be valuable does not make you a bad coder. Refusing to use the latest alpha release of some open source framework that was posted on freshmeat for the first time yesterday does not mean you're "behind the times". Refusing to take part in the alpha-geeking process of proving who is the techiest of all does not mean that you have no skills.
I have envied some of the instinctive skills I have witnessed some developers older than me illustrate and I have been on the other end as well when I have had younger developers ask "How did you know how to do that?" and I was able to trace it back to an experience on an earlier project.
I like baeocystin's comment on the "Thought on Developer Longevity" post: "You ask some good questions, but you should add one more- what do these intelligent, experienced ex-developers know that you don't?"
Not All Experience is Created Equal
It is my opinion that twenty years working with multiple domains, multiple problems, and multiple customer needs is far more significant and useful than twenty years doing the same thing. This has been described as the difference between doing the same thing twenty times or doing twenty different things. I extend this to learning new languages, frameworks, and tools. Although I think there's tremendous value in learning new languages and tools, my feeling is that I'd rather have a developer who knows a small number of languages well and has applied them in diverse situations over the developer who knows numerous languages but has used them all for solving the same basic or simple problem. Knowing how to write "Hello, World" in 35 different languages is not a very useful skill in and of itself. The developer who can solve complex problems in a particular language is more likely to be able to pick up a new language for solving another complex problem than the person knowing a bunch of languages only used in simple applications.
Disadvantages for More Experienced Developers
There's no question that experienced developers do face some disadvantages. While their experience can help them avoid the Lemming Effect, they can go too far the other way and not be willing to consider anything new or doing something a different way. This is covered in Brion's post. Other posts on disadvantages of experienced developers include How Experienced Developers Can Handicap a Lean Startup and Older Developers: Bad Habits Are Killing Your Career. While there may be some gross stereotyping in some of these, I do think it's worth every developer's time to always consider whether he or she is letting established habits and comfort misguide decisions.
Early in my software development career, I observed several older software developers who had been effective in days of procedural programming, but really struggled with object-oriented languages. It was not that there people were unintelligent or slow-witted. On the contrary, they had implemented some sophisticated applications despite having significantly less tools to work with than we do today. Unfortunately, they had trouble making the mental shift from procedural style to what many of us do today (object-oriented with some procedural skeletons in the closet).
What is 'Good'?
A problem with any of these types of discussions surrounds the use of subjective terms like "good." This is pointed out well by the Foredecker comment that points out problems of perception of what makes a good developer. As the comment points out, perceived outward excitement is not necessarily an indicator of a better developer.
Examples of Software Developers Over 40 Who Are At Least 'Any Good'
There are numerous examples of good software developers over the age of forty. Tim O'Brien's comment on the "Thoughts on Developer Longevity" post is: "Most of the developers I know are over 40, and they are all so good at what they do they put everyone else to shame."
I previously mentioned Bruce Eckel, who is 53 years old according to Wikipedia. The first edition of Thinking in C++ was published when he was 42 years old and he was over 40 when the first edition of Thinking in Java was published.
According to Wikipedia, Bjarne Stroustrup was born in 1950, Tim Bray, James Gosling, Grady Booch, and Tim Berners-Lee were born in 1955 (what was in the water that year?), Martin Odersky was born in 1958, Josh Bloch and Kent Beck were born in 1961, Martin Fowler was born in 1963, and Yukihiro Matsumoto was born in 1965. I think we could find room on our team for any of these individuals.
Conclusion
The post Thoughts on Developer Longevity and its associated comments are well worth the read. I agree with Brion's assertions as often, but not always, true. My major disagreement is with the percentage or ratio of good/bad developers over age forty and I think this may be due to different experiences in our careers. In the end, Brion's reasoning for the post (to determine what drives developers to remain effective after age forty) is a good way to start potentially valuable community discussion. A user going by the name "Public" perhaps answered the question most succinctly: "I'm a 42 year old developer and my secret is this: love learning new things and spend the time to do so. There you go."
My experience has been that the most successful software development projects often are made up of a mixture of young developers who are already skilled and have even more potential with master craftsman who can guide the team through political and technological challenges they have seen many times before.
Wednesday, March 2, 2011
Manning Deal of the Day: Making Java Groovy
Today's (Wednesday, March 2, 2011) Manning Deal of the Day is an offer to purchase the in-progress Manning Early Access Edition (MEAP) of Making Java Groovy with a pbook (printed) and ebook when the book is completed (estimated Fall 2011). The deal is the MEAP+pbook (includes ebook) for $25 plus shipping. The promotional code to use for this deal is located in the top right corner of the main Manning page under the section "DEAL OF THE DAY."
I have purchased and read large portions of three Groovy books: Groovy Recipes: Greasing the Wheels of Java, Programming Groovy, and Groovy in Action (Second Edition expected Summer 2011). I like all three books and have found that each has its advantages and disadvantages and that I really like the comprehensive coverage provided by all three books. With that being stated, I did not expect to be interested in another Groovy book, but the description and table of contents for Making Java Groovy appeal to me. In many ways, it sounds like this book is going to cover Groovy in exactly the way I use it. I look forward to the completion and delivery of this book.
I have purchased and read large portions of three Groovy books: Groovy Recipes: Greasing the Wheels of Java, Programming Groovy, and Groovy in Action (Second Edition expected Summer 2011). I like all three books and have found that each has its advantages and disadvantages and that I really like the comprehensive coverage provided by all three books. With that being stated, I did not expect to be interested in another Groovy book, but the description and table of contents for Making Java Groovy appeal to me. In many ways, it sounds like this book is going to cover Groovy in exactly the way I use it. I look forward to the completion and delivery of this book.
Subscribe to:
Posts (Atom)

