Thứ Hai, 11 tháng 1, 2010

Software Engineering One of 2010's Best Jobs

I have recently had several colleagues and friends with the Systems Engineer job title brag (trying to convince themselves, no doubt) about Money magazine ranking Systems Engineer their #1 job in Best Jobs in America 2009. That same article ranked Information Technology Program Manager as #5, Computer/Network Security Consultant as #8, Software Developer as #12, Software Product Manager as #16, IT Business Analyst as #17, Technical Writer as #28, Computer Software Program Manager as #39, and Application Systems Analyst as #40. As this list demonstrates, many jobs related to software development were listed in the top 50 jobs in the United States.

In The Register article Software engineer rated best job of 2010 (almost), Gavin Clarke highlights the job of "Software Engineering" ranking #2 in The Wall Street Journal's Best and Worst Jobs 2010 (Actuary was #1) based on a CareerCast.com study.

There are numerous other software development-related jobs listed in CareerCast's Best and Worse Jobs 2010. Besides the #2 listing for Software Engineer, other examples are Computer System Analyst at #3, Web Developer at #15, and Computer Programmer at #34. The worst of the 200 is that of the roustabout.

One of the observations one cannot help but make when looking at these lists is the attempted delineation of various similar-sounding professions. There are already numerous blog posts and forum threads examining what makes a software engineer different than a computer programmer and so forth, so I won't go into that here.

The CareerCast.com page The 10 Best Jobs of 2010 provides a brief description of the job duties of a "software engineer" and points out that what particularly sets this occupation apart is its "hiring outlook":
With low unemployment compared to the national average and projected job growth of nearly 45% through 2016, Software Engineer currently has the best hiring outlook of any available job in 2010.


After a difficult worldwide economy has had a tremendous negative impact in the world of software development, it is encouraging to see positions in this field ranking so high in these studies.

The Systems Engineers may have had the #1 position in 2009, but that was so 2009. We Software Engineers have the highest ranking of related fields in 2010. Take that, Systems Engineers.

I now go to ensure that my resume refers to my current position as "Software Engineer."

Thứ Sáu, 8 tháng 1, 2010

Favorite Development Cheatsheets

Although modern search engines have made it easier than ever to look up various details, it is still sometimes nice to have a go-to resource to refresh my memory about certain development tasks. I first started to appreciate materials like this when I encountered the famous Oracle data dictionary wall posters (such as this TUSC-provided poster and the Quest poster). In this blog post, I point to and briefly summarize some of my favorite development-related cheat sheets.

There are too many useful DZone-provided Refcardz ("Free Cheat Sheets for Developers") to cover them all here, but I will focus on a few individual examples of them in this blog post. I call them out here separately because there are so many of them on so many different subjects. These require registration with DZone/JavaLobby, but that is free. Although I only list a small sample of these DZone refcardz in conjunction with other development-related cheat sheets listed in this post, it should still be obvious that a single free registration with DZone to be able to download so many useful cheat sheets doesn't seem so onerous.


Java Cheat Sheets

Java Collections

Java Collections Cheatsheet

When I was first learning Java in the mid- to late- 1990s, I wished there was a good visual summary of the different Java collections. Java collections have changed dramatically since then and increased in size and variety and so such a visual summary is even more desirable now. Coder-Friendly has made just such a thing available in the Java Collections Cheatsheet. Not only does this show collections-related hierarchical information and Big O notation for various operations on the various collections types, but it is also inspired by one of my favorite intermediate to advanced Java books (Java Generics and Collections).


General Java

Java Quick Reference
Java 1.5 Cheat Sheet
Java Reference Sheet

Jialong He's Java Quick Reference and Project Encycode's Java Cheat Sheet seems a little dated now, but can still be useful for a quick perusal of Java basics and overview of some of the JDK's packages. Pete Freitag's Java 1.5 Cheat Sheet adds some specific new features of J2SE 5.


Java Persistence API

Getting Started with JPA
TopLink JPA Annotation Reference

Mike Keith's DZone-provided (Refcardz #22) Getting Started with JPA provides an introduction to JPA and a good resource of the JPA basics. The TopLink JPA Annotation Reference is also helpful when developing with JPA.


XML in Java

Using XML in Java

The DZone refcardz Using XML in Java (#35) is written by Masoud Kalali and


Groovy Cheat Sheets

Groovy Refcardz

Although Dierk König's DZone-provided DZone Groovy Refcardz (#15) requires (free) registration, it is significantly more up-to-date (2008) and comprehensive (7 pages) than the 2004 Groovy Reference Summary.


Flex / AIR Cheat Sheets

Very First Steps in Flex
Getting Started with BlazeDS
AIR Cheat Sheets

Very First Steps in Flex is written by Bruce Eckel and James Ward and is available as a DZone Refcardz. Getting Started with BlazeDS is also a DZone refcardz (#75) and is written by Shashank Tiwari. The AIR Cheat Sheets do not require any registration to download the PDF.


Other Web Development

HTML

Core HTML

The DZone-provided Andy Harris Refcardz Core HTML (#64) covers HTML and XHTML along with brief mention of HTML 5 and Cascading Style Sheets.

HTML 5 Cheat Sheet (PDF)

Speaking of HTML 5, the HTML 5 Cheat Sheet (AKA HTML 5 Quick Reference Guide) from Chris Hanscom and Smashing Magazine summarizes this emerging standard's markup tags.

CSS

Core CSS: Parts I, II, and III

Speaking of CSS, there is a whole DZone Refcardz series written by Molly E. Holzschlag dedicated to CSS: Core CSS: Part I (#19), Core CSS: Part II (#25), Core Css: Part III (#34).

Veign's CSS3 Quick Reference Guide

If you are not registered with DZone (and refuse to do so), you can download the CSS3 Quick Reference Guide from Veign and Chris Hanscom without registration.

Thứ Năm, 7 tháng 1, 2010

Viewing Groovy Application's Classpath

Because the set of classes that Groovy applications see is wider than the set standard Java applications see, it can be helpful to see what classes are already on the Groovy classpath. This is very easy to do and the one line of executable Groovy to do this is shown in the next code listing.


#!/usr/bin/env groovy
this.class.classLoader.rootLoader.URLs.each{ println it }


The above code takes advantage of the Groovy RootLoader. This RootLoader is often used to dynamically add a library to the Groovy application's classpath, but, as the example here shows, can also be used to see what Groovy sees.

When the above code is executed, the results shown next are seen.


file:/C:/java/examples/groovyExamples/displayGroovyClasspath/./
file:/C:/Program%20Files/Java/jre6/lib/ext/QTJava.zip
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ant-1.7.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ant-junit-1.7.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ant-launcher-1.7.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/antlr-2.7.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-analysis-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-commons-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-tree-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/asm-util-3.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/balloontip_2009-01-2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-anim-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-awt-util-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-bridge-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-codec-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-css-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-dom-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-ext-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-extension-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-gui-util-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-gvt-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-parser-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-script-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-svg-dom-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-svggen-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-swing-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-transcoder-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-util-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/batik-xml-1.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/bsf-2.4.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/commons-cli-1.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/commons-logging-1.1.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/cssbuilder-0.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/cssparser-0.9.5.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/Filters.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/flamingo-4.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/flamingo-4.0dev.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/flamingobuilder-0.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/forms-1.2.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/fxbuilder-0.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gant-1.9.0_groovy-1.7.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gfxbuilder-core-0.2.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gfxbuilder-svg-0.2.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gfxbuilder-swingx-0.2.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/gpars-0.9.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/groovy-1.7.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/ivy-2.1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jacob-1.14.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/JFXtras-0.5.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jide-oss-2.6.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jidebuilder-2.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jline-0.9.94.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jsilhouette-geom-0.3.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jsp-api-2.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/jsr166y-070108.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/junit-4.7.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/l2fprod-common-all.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/macwidgets-0.9.4.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/macwidgetsbuilder-0.2.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/maven-ant-tasks-2.0.10.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/miglayout-3.6.3-swing.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/MultipleGradientPaint.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/netty-3.1.5.GA.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/sac-1.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-ie-6-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-office-2K3-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-sapi-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-scripting-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-wbem-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/scriptom-wsh-tlb-1.6.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/servlet-api-2.4.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/spock-core-0.3.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/svg-salamander-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swing-worker-1.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingx-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingx-beaninfo-0.9.5.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingx-ws.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingxbuilder-0.1.6.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/swingxtrasbuilder-0.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/timingframework-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/trident-1.0.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/tridentbuilder-0.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/xml-apis-ext-1.3.04.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/xstream-1.3.1.jar
file:/C:/Program%20Files/Groovy/Groovy-1.7.0/lib/xswingx-0.2.jar
file:/C:/Program%20Files/Java/jdk1.6.0_14/lib/tools.jar


The results returned from that simple Groovy script indicate what is already advertised about where Groovy automatically looks for classes and JARs: the current directory, the JRE extension mechanism directory, the Groovy installation's lib directory (%GROOVY_HOME%\lib or ${GROOVY_HOME}/lib), and the JDK's tools.jar. Had I specified any classes or JARs on the classpath using the -cp option, those would have been displayed here as well.

Thứ Ba, 5 tháng 1, 2010

Groovy: Means, Medians, Modes, and Ranges Calculations

I needed to check a seventh grader's homework related to means, medians, modes, and ranges and Groovy seemed like a nice approach to writing a quick tool to check these calculations. The calculations used in this Groovy script are based on definitions of these terms in Mean, Median, Mode, and Range and in Mean, Median, and Mode: Overview.

I hurriedly put this script, modeMedianMean.groovy, together, so it could probably use some work. However, I wanted to check the homework with a quick and dirty tool and it does provide more examples of using some of Groovy's features and syntax.

modeMedianMean.groovy

#!/usr/bin/env groovy
// Script for calculating median, mean, mode, range, etc.
//
// http://www.purplemath.com/modules/meanmode.htm

if (args.length < 1)
{
println "You need to provide at least one numeric argument."
System.exit(-1)
}

// Place passed-in number arguments in List
values = new ArrayList<BigDecimal>()
for (i in args)
{
try
{
values.add(new BigDecimal(i))
}
catch (NumberFormatException numberFormatEx)
{
println "Ignoring non-numeric parameter: ${i}"
}
}
Collections.sort(values)

// Begin collecting metadata about the data
numberItems = values.size()
sum = 0
modeMap = new HashMap<BigDecimal, Integer>()
for (item in values)
{
sum += item
if (modeMap.get(item) == null)
{
modeMap.put(item, 1)
}
else
{
count = modeMap.get(item) + 1
modeMap.put(item, count)
}
}
mode = new ArrayList<Integer>()
modeCount = 0
modeMap.each()
{ key, value ->
if (value > modeCount) { mode.clear(); mode.add(key); modeCount = value}
else if (value == modeCount) { mode.add(key) }
};
mean = sum / numberItems
midNumber = (int)(numberItems/2)
median = numberItems %2 != 0 ? values[midNumber] : (values[midNumber] + values[midNumber-1])/2
minimum = Collections.min(values)
maximum = Collections.max(values)

println "You provided ${numberItems} numbers (${values}):"
println "\tMean: ${mean}"
println "\tMedian: ${median}"
println "\tMode: ${mode}"
println "\tMinimum: ${minimum}"
println "\tMaximum: ${maximum}"
println "\tRange: ${maximum - minimum}"


The next screen snapshot demonstrates this simple script in action with a variety of different numbers.



The examples demonstrated in the above screen snapshot demonstrated the sort and the basic functionality of median, mode, and mean, but all examples use integral numbers. The next screen snapshot includes some non-integer numbers and also shows the handling (ignored) of non-numeric parameters.



This simple script demonstrates how easy it is to use Groovy to accomplish repetitive tasks. With a little more time and effort, the script could be further improved, but it was sufficient for me to use to quickly check the seventh grade homework.

Thứ Hai, 4 tháng 1, 2010

I Use Dead Programming Languages

In the late 1990s, a well respected and visionary colleague made the surprising statement, "Java is dead." That is probably the first time I had heard that phrase. Despite my respect for his considerable accomplishments, I thought that the statement was ridiculous. More than ten years later, it is still a pretty ridiculous statement. Java will "die" one day; all languages (and, even more so, all people) do. In that respect, Java "is dead," but so is every other programming language out there. I guess, then, it is safe to say that all programming languages are "dead."

When I enter the quotes-bound string "java is dead" into the Google search engine, I currently see 199,000 matches. Evidently, at least a few people have written this or written about someone else who has written this. Many of these posts make good points and the authors don't mean literally dead as of today, but the title "Java is dead" is obviously hyperbole. Who knew there could be so much Drama Queen behavior in software development?

The typical author of a "Java is dead" post is stating such claims because he or she doesn't like the Java feature set (such as the now-not-necessarily-the-case news that closures would not be in JDK 7; see Java Just Died (No Closures in Java 7)), he or she is concerned about the effectiveness and appropriateness of new features given backwards compatibility concerns (see Java: Evolutionary Dead End, Java is Dead?, and Java is Dead!), or he or she believes Java has become too complicated (see Java is Dead). Almost all of these posters have an alternative language in mind, though in almost all of these cases one could easily attack that alternative as well with some of the same criticisms. Indeed, Java is likely to outlive some of these languages.

For a "dead" language, Java isn't doing too badly. Java continues to top the Tiobe Programming Community Index, an almost boring feat at this point after holding this spot for roughly ten years (though it did swap places with second place C in the mid-2000s). Java continues to be a highly sought-after skill among potential new hires as proven by job searches at sites like Dice and Monster and obviously at JustJavaJobs.com. A Google search for "java -coffee -island" (without the quotes) reports 215 MILLION matches (and that's with the removal of pages/sites that might have happened to mention the Java programming language in conjunction with "coffee" or "island").

There are many reasons that the claim "Java is dead" will continue to be ridiculous (or at least overly dramatic) for at least several more years. First, many computer science programs and other training programs use Java as a primary teaching language. Second, there is a huge established code base that already uses Java. Third, there is significant vendor investment, tools, training, and other products that make both the vendors and their customers somewhat tied to Java. Fourth, Java boasts arguably the largest developer and open source ecosystem out there. When it comes to applications for which I want tools, vendors, and developers to be around with the right skills in the future, Java is still the leader. This point is well-made in Java: The Perpetually Undead Language.

Looking at other languages who have long since been pronounced dead shows us that Java's future may not be as bleak as some think. I heard (and hear) many enthusiastic Java developers talking about C++ being dead. I have noticed recently a resurgence in the interest in C++. The announcement of Google's Go programming language validates the interest there is in languages like C/C++.

One of the obstacles that faced Java from replacing C++ in places where Java obviously had advantages (such as GUI and database development) was the cost organizations faced to completely migrate C++ applications to Java applications. JNI, CORBA, web services, and similar technologies have made it possible to mix the two, but they all have their own complexities and issues. In a somewhat ironic twist, Java's greatest threat may be the rapidly rising popularity of alternative JVM-hosted languages such as Groovy, Scala, JRuby, and Clojure. Because these langauges run on the JVM, their integration with Java is much simpler than it ever was to integrate C++ and Java. This can potentially allow Java-heavy shops to more easily begin using these alternative JVM-hosted languages.

One development that could drastically impact the future of Java is Oracle's acquisition of Sun. However, for good or for bad, we won't know the depth or nature of that impact until the deal is finally approved (assuming that it is) and only time will tell. My best guess (and that's all it is) is that Oracle will do very little to change Java management in the near term.

If I was to base my opinions solely on what I observe in the blogosphere, I'd be sure that Java was already dead. It so happens, however, that reality is actually quite different than the blogosphere. When I talk to attendees at conferences, talk to other developers offline, and so forth, I get a much more realistic view of development. In that more realistic view, Java is far from dead.


Conclusion

Ted Neward wrote in mid-2008 that Java is Dead Like COBOL. In many ways, I still see this as the case. Java has warts and wrinkles. There are things I wish were done differently in Java. However, every language has its issues. When all things are considered (the large Java ecosystem of products, existing code, and investment), it is difficult to see what language one should tie himself or herself to for a good future that would be any more likely to succeed than Java. Instead, I prefer to continue to work with Java and to play with and work with other languages when they are more appropriate. I especially like the JVM-based languages because I can easily use them in conjunction with Java.

Java is far from dead and is probably further from language death than several of today's trendiest languages. Indeed, Java is only "dead" in the sense that all programming languages are destined to eventually die. I see some nice languages that complement Java (such as Scala and Groovy), but I don't realistically seeing them displacing Java altogether.

Thứ Bảy, 2 tháng 1, 2010

RMOUG Training Days 2010 Presentations Blogs

Several people scheduled to present at Rocky Mountain Oracle Users Group Training Days 2010 have started blogging about their presentations. This post is a summary of some of these. The list of presentation summaries is available here.

Ken Lee has blogged about his presentation APEX Moves from the Garage to the Basement in his blog post RMOUG 2010 – February 17 – 18, 2010. Oracle Application Express (APEX) is an Oracle-provided tool for building web applications off of an Oracle database.

Kellyn Pedersen blogs about her upcoming presentation The Power of Parallel in her blog post Presenting at RMOUG 2010!!! This presentation appears to be related to Oracle parallel processing.

Chen Shapira is presenting What Every DBA Should Know About TCP/IP Networks and Analyzing Oracle Performance Using Time Series Models. She references the latter of these in two blog posts: Autocorrelation and Causation and Goodness of Data.

Jože Senegačnik is scheduled to present RMAN Tips and Services - Why Should One Use Them? One of the reasons that I'm a developer rather than a DBA is that the idea of backing up and restoring databases is one of the most boring that I can imagine. However, it is important and Oracle DBAs seem to love presentations related to Oracle Recovery Manager (RMAN).

Robert G Freeman mentions his 1/2 day university session in his blog post Creating VMWare and RAC on Windows, Part 2. He is also presenting on RMAN: Advanced RMAN Backup and Recovery.

I expect to see additional blogs from presenters at RMOUG Training Days 2010 as it approaches. Training Days will be held February 17-18 (and 1/2 day University Sessions on February 16) in the Colorado Convention Center in Denver, Colorado.

Thứ Sáu, 1 tháng 1, 2010

Finding Files by Name with Groovy

I recently was trying unsuccessfully to burn some files to a DVD with my Vista-based laptop. Thanks to a Google search, I found a helpful page at TroubleFixers.com that indicated that this particular error might be caused by a dollar sign ($) in a filename extension or by the machine going into sleep mode during a mastered disc writing. Because I was having difficulty getting the Vista search to do what I wanted (probably more my fault than Vista's), I turned to a Groovy solution for finding files with $ in their name.

fileFind.groovy

#!/usr/bin/env groovy
// fileFind.groovy
//
// Find a file with recursive directory search.
//
// There are certain rules to be observed when providing the substring to be
// searched for in file names:
// Escape the $ character with a slash.
//
if (args.length < 2)
{
println "Need to specify directory to be searched and the substring of file."
println "\tUSAGE: fileFind <directoryPath> <fileNameSubString>"
System.exit(-1)
}
def directoryName = args[0]
def fileSubStr = args[1]
def filePattern = ~/${fileSubStr}/
def directory = new File(directoryName)
if (!directory.isDirectory())
{
println "The provided directory name ${directoryName} is NOT a directory."
System.exit(-2)
}
println "Searching for files including ${fileSubStr} in directory ${directoryName}..."
def findFilenameClosure =
{
if (filePattern.matcher(it.name).find())
{
println "\t${it.name} (size ${it.size()})"
}
}
println "Matching Files:"
directory.eachFileRecurse(findFilenameClosure)


The above script will print out the name of any file it finds matching the provided string. If I pass $ to it without escaping the dollar sign, all files in the directory are returned. Using backslash to escape the dollar sign accomplishes what I want (only files with $ in their name). The next two screen snapshots demonstrate this.

Finding All Files with Unescaped $



Finding Only Files with $ in Their Name




If the purpose is to delete these files that match, that is very easy to add to the above script. In a "production" quality script, I'd add some optional deletion verification. For now, I'm going to live on the edge and add capability to automatically and without verification delete the matching files. Don't try this at home!

fileFindAndDelete.groovy

#!/usr/bin/env groovy
// fileFindAndDelete.groovy
//
// Find a file with recursive directory search and delete any matching files.
//
// There are certain rules to be observed when providing the substring to be
// searched for in file names:
// Escape the $ character with a slash.
//
if (args.length < 2)
{
println "Need to specify directory to be searched and the substring of file."
println "\tUSAGE: fileFind <directoryPath> <fileNameSubString>"
System.exit(-1)
}
def directoryName = args[0]
def fileSubStr = args[1]
def filePattern = ~/${fileSubStr}/
def directory = new File(directoryName)
if (!directory.isDirectory())
{
println "The provided directory name ${directoryName} is NOT a directory."
System.exit(-2)
}
println "Searching for files including ${fileSubStr} in directory ${directoryName}..."
def findFilenameClosure =
{
if (filePattern.matcher(it.name).find())
{
println "\tDeleting ${it.name} (size ${it.size()}) ..."
it.delete()
println "\t${it.name} deleted."
}
}
println "Matching Files:"
directory.eachFileRecurse(findFilenameClosure)


I simply changed the closure to delete the files with matching names. The output of this script looks like shown in the next screen snapshot.

Find and Delete Files Matching Name via Groovy




The above scripts took advantage of Java APIs (such as java.io.File and Java regular expressions support with classes like java.util.regex.Matcher) and Groovy goodness (such as Groovy's GDK-provided File support, Groovy's regular expression support, closures, and more concise syntax).


Conclusion

Groovy is so easy to apply that it didn't take me much longer to write and use a Groovy script to delete the necessary files than it would have taken me to figure out how to do the same thing via Windows and then delete each of those found files. This was a situation where scripting works better than manual handling and Groovy makes that scripting easy.