Category Archives: Java (General)

PHPHOST BLOG

Web Hosting Related Articles You May Need

Programmatic Access to Sizes of Java Primitive Types

One of the first things many developers new to Java learn about is Java’s basic primitive data types, their fixed (platform independent) sizes (measured in bits or bytes in terms of two’s complement), and their ranges (all numeric types in Java are sig… Continue reading

Posted in Java (General), Java SE 8, Syndicated | Comments Off on Programmatic Access to Sizes of Java Primitive Types

Compiling and Running Java Without an IDE

A recent Java subreddit thread called “Compiling Java Packages without IDE” posed the question, “is [there] a command that compiles a group of java files that are inside a package into a separate folder (let’s just call it bin), and how would I go about running the new class files?” The post’s author, kylolink, explains that “When I started out using Java I relied on Eclipse to do all the compiling for me and just worried about writing code.” I have seen this issue many times and, in fact, it’s what prompted my (now 4 years old) blog post GPS Systems and IDEs: Helpful or Harmful? I love the powerful modern Java IDEs and they make my life easier on a daily basis, but there are advantages to knowing how to build and run simple Java examples without them. This post focuses on how to do just that.

In my blog post Learning Java via Simple Tests, I wrote about how I sometimes like to use a simple text editor and command-line tools to write, build, and run simple applications. I have a pretty good idea now how my much “overhead” my favorite Java IDEs require and make an early decision whether the benefits achieved from using the IDE are sufficient to warrant the “overhead.” In most real applications, there’s no question the IDE “overhead” is well worth it. However, for the simplest of example applications, this is not always the case. The rest of this post shows how to build and run Java code without an IDE for these situations.

The Java Code to be Built and Executed

To make this post’s discussion more concrete, I will use some very simple Java classes that are related to each other via composition or inheritance and are in the same named package (not in the unnamed package) called dustin.examples. Two of the classes do not have main functions and the third class, Main.java does have a main function to allow demonstration of running the class without an IDE. The code listings for the three classes are shown next.

Parent.java


package dustin.examples;

public class Parent
{
@Override
public String toString()
{
return "I'm the Parent.";
}
}

Child.java


package dustin.examples;

public class Child extends Parent
{
@Override
public String toString()
{
return "I'm the Child.";
}
}

Main.java


package dustin.examples;

import static java.lang.System.out;

public class Main
{
private final Parent parent = new Parent();
private final Child child = new Child();

public static void main(final String[] arguments)
{
final Main instance = new Main();
out.println(instance.parent);
out.println(instance.child);
}
}

The next screen snapshot shows the directory structure with these class .java source files in place. The screen snapshot shows that the source files are in a directory hierarchy representing the package name (dustin/examples because of package dustin.examples) and that this package-reflecting directory hierarchy is under a subdirectory called src. I have also created classes subdirectory (which is currently empty) to place the compiled .class files because javac will not create that directory when it doesn’t exist.

Building with javac and Running with java

No matter which approach one uses to build Java code (Ant, Maven, Gradle, or IDE) normally, I believe it is prudent to at least understand how to build Java code with javac. The Oracle/Sun-provided javac command-line tool‘s standard options can be seen by running javac -help and additional extension options can be viewed by running javac -help -X. More details on how to apply these options can be found in the tools documentation for javac for Windows or Unix/Linux.

As the javac documentation states, the -sourcepath option can be use to express the directory in which the source files exist. In my directory structure shown in the screen snapshot above, this would mean that, assuming I’m running the javac command from the C:\java\examples\javacAndJava\ directory, I’d need to have something like this in my command: javac -sourcepath src src\dustin\examples\*.java. The next screen snapshot shows the results of this.

Because we did not specify a destination directory for the .class files, they were placed by default in the same directory as the source .java files from which they were compiled. We can use the -d option to rectify this situation. Our command could be run now, for example, as javac -sourcepath src -d classes src\dustin\examples\*.java. As stated earlier, the specified destination directory (classes) must already exist. When it does, the command will place the .class files in the designated directory as shown in the next screen snapshot.

With the Java source files compiled into the appropriate .class files in the specified directory, we can now run the application using the Java application launcher command line tool java. This is simply done by following the instructions shown by java -help or by the java tools page and specifying the location of the .class files with the -classpath (or -cp) option. Using both approaches to specify that the classes directory is where to look for the .class files is demonstrated in the next screen snapshot. The last argument is the fully qualified (entire Java package) name of the class who has a main function to be executed. The commands demonstrated in the next screen snapshot is java -cp classes dustin.examples.Main and java -classpath classes dustin.examples.Main.

Building and Running with Ant

For the simplest Java applications, it is pretty straightforward to use javac and java to build and execute the application respectively as just demonstrated. As the applications get a bit more involved (such as code existing in more than one package/directory or more complex classpath dependencies on third-party libraries and frameworks), this approach can become unwieldy. Apache Ant is the oldest of the “big three” of Java build tools and has been used in thousands of applications and deployments. As I discussed in a previous blog post, a very basic Ant build file is easy to create, especially if one starts with a template like I outlined in that post.

The next code listing is for an Ant build.xml file that can be use to compile the .java files into .class files and then run the dustin.examples.Main class just like was done above with javac and java.

build.xml


<?xml version="1.0" encoding="UTF-8"?>
<project name="BuildingSansIDE" default="run" basedir=".">
<description>Building Simple Java Applications Without An IDE</description>

<target name="compile"
description="Compile the Java code.">
<javac srcdir="src"
destdir="classes"
debug="true"
includeantruntime="false" />
</target>

<target name="run" depends="compile"
description="Run the Java application.">
<java classname="dustin.examples.Main" fork="true">
<classpath>
<pathelement path="classes"/>
</classpath>
</java>
</target>
</project>

I have not used Ant properties and not included common targets I typically include (such as “clean” and “javadoc”) to keep this example as simple as possible and to keep it close to the previous example using javac and java. Note also that I’ve included “debug” set to “true” for the javac Ant task because it’s not true in Ant’s default but is true with javac’s default. Not surprisingly, Ant’s javac task and java task closely resemble the command tools javac and java.

Because I used the default name Ant expects for a build file when it’s not explicitly specified (build.xml) and because I provided the “run” target as the “default” for that build file and because I included “compile” as a dependency to run the “run” target and because Ant was on my environment’s path, all I need to do on the command line to get Ant to compile and run the example is type “ant” in the directory with the build.xml file. This is demonstrated in the next screen snapshot.

Although I demonstrated compiling AND running the simple Java application with Ant, I typically only compile with Ant and run with java (or a script that invokes java if the classpath is heinous).

Building and Running with Maven

Although Ant was the first mainstream Java build tool, Apache Maven eventually gained its own prominence thanks in large part to its adoption of configuration by convention and support for common repositories of libraries. Maven is easiest to use when the code and generated objects conform to its standard directory layout. Unfortunately, my example doesn’t follow this directory structure, but Maven does allow us to override the expected default directory structure. The next code listing is for a Maven POM file that overrides the source and target directories and provides other minimally required elements for a Maven build using Maven 3.2.1.

pom.xml


<project>
<modelVersion>4.0.0</modelVersion>
<groupId>dustin.examples</groupId>
<artifactId>CompilingAndRunningWithoutIDE</artifactId>
<version>1</version>

<build>
<defaultGoal>compile</defaultGoal>
<sourceDirectory>src</sourceDirectory>
<outputDirectory>classes</outputDirectory>
<finalName>${project.artifactId}-${project.version}</finalName>
</build>
</project&gt

Because the above pom.xml file specifies a “defaultGoal” of “compile” and because pom.xml is the default custom POM file that the Maven executable (mvn) looks for and because the Maven installation’s bin directory is on my path, I only needed to run “mvn” to compile the .class files as indicated in the next screen snapshot.

I can also run the compiled application with Maven using the command mvn exec:java -Dexec.mainClass=dustin.examples.Main, which is demonstrated in the next screen snapshot.

As is the case with Ant, I would typically not use Maven to run my simple Java application, but would instead use java on the compiled code (or use a script that invokes java directly for long classpaths).

Building and Running with Gradle

Gradle is the youngest, trendiest, and hippest of the three major Java build tools. I am sometimes skeptical of the substance of something that is trendy, but I have found many things to like about Gradle (written in Groovy instead of XML, built-in Ant support, built-in Ivy support, configuration by convention that is easily overridden, Maven repository support, etc.). The next example shows a Gradle build file that can be used to compile and run the simple application that is the primary example code for this post. It is adapted from the example I presented in the blog post Simple Gradle Java Plugin Customization.

build.gradle


apply plugin: 'java'
apply plugin: 'application'

// Redefine where Gradle should expect Java source files (*.java)
sourceSets {
main {
java {
srcDirs 'src'
}
}
}

// Redefine where .class files are written
sourceSets.main.output.classesDir = file("classes")

// Specify main class to be executed
mainClassName = "dustin.examples.Main"

defaultTasks 'compileJava', 'run'

The first two lines of the build.gradle file specify application of the Java plugin and the Application plugin, bringing a bunch of functionality automatically to this build. The definition of “sourceSets” and “sourceSets.main.output.classesDir” allows overriding of Gradle’s Java plugin’s default directories for Java source code and compiled binary classes respectively. The “mainClassName” allows explicit specification of which class should be run as part of the Application plugin. The “defaultTasks” line specifies the tasks to be run by simply typing “gradle” at the command line: ‘compileJava’ is a standard task provided by the Java plugin and ‘run’ is a standard task provided by the Application plugin. Because I named the build file build.gradle and because I specified the default tasks of ‘compileJava’ and ‘run’ and because I have the Gradle installation bin directory on my path, all I needed to do to build and run the examples was to type “gradle” and this is demonstrated in the next screen snapshot.

Even the biggest skeptic has to admit that Gradle build is pretty slick for this simple example. It combines brevity from relying on certain conventions and assumptions with a very easy mechanism for overriding select defaults as needed. The fact that it’s in Groovy rather than XML is also very appealing!

As is the case with Ant and Maven, I tend to only build with these tools and typically run the compiled .class files directly with java or a script that invokes java. By the way, I typically also archive these .class into a JAR for running, but that’s outside the scope of this post.

Conclusion

An IDE is often not necessary for building simple applications and examples and can even be more overhead than it’s worth for the simplest examples. In such a case, it’s fairly easy to apply javac and java directly to build and run the examples. As the examples become more involved, a build tool such as Ant, Maven, or Gradle becomes more appealing. The fact that many IDEs support these build tools means that a developer could transition to the IDE using the build tool created earlier in the process if it was determined that IDE support was needed as the simple application grew into a full-fledged project.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Ant, Gradle, Java (General), Maven, Syndicated | Comments Off on Compiling and Running Java Without an IDE

Abstract Class Versus Interface in the JDK 8 Era

In The new Java 8 Date and Time API: An interview with Stephen Colebourne, Stephen Colebourne tells Hartmut Schlosser, “I think the most important language change isn’t lambdas, but static and default methods on interfaces.” Colebourne adds, “The addit… Continue reading

Posted in Java (General), Java SE 8, Syndicated | Comments Off on Abstract Class Versus Interface in the JDK 8 Era

Serializing Java Objects with Non-Serializable Attributes

There are multiple reasons one might want to use custom serialization instead of relying on Java’s default serialization. One of the most common reasons is for performance improvements, but another reason for writing custom serialization is when the de… Continue reading

Posted in Java (General), Syndicated | Comments Off on Serializing Java Objects with Non-Serializable Attributes

ObjectStreamClass: Peeking at a Java Object’s Serialization

ObjectStreamClass can be a useful class to analyze the serialization characteristics of a serialized class loaded in the JVM. This post looks at some of the information this class provides about a loaded serialized class. ObjectStreamClass provides two… Continue reading

Posted in Java (General), Syndicated | Comments Off on ObjectStreamClass: Peeking at a Java Object’s Serialization

Something to Consider as Java Tops the Programming Charts

The following is a contributed article from Dennis Chu of Coverity:


Something to Consider as Java Tops the Programming Charts

By Dennis Chu, Senior Product Manager, Coverity

For development teams, it may be obvious: Java is one of the top programming languages today. Approximately 9 million developers are currently working in Java; it’s said to be running on three billion devices and the language continues to evolve almost as quickly as the changing technology landscape. But, as the story goes, the rise to the top isn’t always easy.

While Java continues to grow in popularity, it has also been linked to a number of vulnerabilities over the years – due in large part to hackers capitalizing on its widespread use. So much so that Apple moved to pull Java entirely from its Mac OS X and its products at the end of 2012.

Further, during the summer of 2013, flaws in Java were linked to growing security threats for some Android device users who owned the much-hyped digital currency Bitcoin. The vulnerability enabled hackers to tap into the digital wallets of these Bitcoin owners, exposing a serious risk for both the new monetary system and the Android operating system.

One of the most recent blows for Java came from its link to HealthCare.gov, the website that continues to make headlines as developers work to fix the programming errors that caused the site to come to a crawl – only about 5 percent of the expected 500,000 health insurance plan enrollments were able to occur in the first month of the site’s launch. HealthCare.gov was developed with Java on top of Tomcat, and while the causes of its errors are many and complex, coding and architecture design flaws were no doubt part of the problem.

Despite the shortcomings exposed over the years, Java has a large number of effective testing and development tools. But even so, given the persistence of issues, it’s become clear that these tools are not being leveraged properly. This is presumably due to poor development testing discipline or weak processes in place within organizations.

After reviewing a number of open source Java projects via our Coverity Scan service – which helps the open source development community evaluate and improve the quality and security of their software – we found similar levels of quality and security issues for Java relative to other languages, such as C and C++. So it turns out that just because Java is one of the most widely used computer languages, it doesn’t guarantee higher quality software.

Some advice for developers coding in Java, or any other computer programming language for that matter: be vigilant. Make an emphasis to select the right tools that will provide the right framework and process to allow your organization to test early and often. This will enable your organization to avoid potential nightmares down the road – for example after it’s been released to customers, when it’s too late.

Using the right technologies and best practices are still the best safeguards to ensure high-quality software. Fixing a flaw during the development process will cost only a small fraction of what it will cost to fix a defect after the product has been released – and that’s not including the damage to your brand and reputation.

On the road ahead, no matter what language tops the charts, it’s important to view testing as a critical investment rather than an unintended expense.


The article above was contributed by Dennis Chu of Coverity. I have published this contributed article because I think it brings up some interesting points of discussion. No payment or remuneration was received for publishing this article.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Contributed, General Development, Java (General), Syndicated | Comments Off on Something to Consider as Java Tops the Programming Charts

Determining Presence of Characters or Integers in String with Guava CharMatcher and Apache Commons Lang StringUtils

A recent Reddit post asked the question, “Is there a predefined method for checking if a variable value contains a particular character or integer?” That question-based title was also asked a different way, “A method or quick way for checking if a vari… Continue reading

Posted in Apache Commons, Guava, Java (General), Syndicated | Comments Off on Determining Presence of Characters or Integers in String with Guava CharMatcher and Apache Commons Lang StringUtils

Orika: Mapping JAXB Objects to Business/Domain Objects

This post looks at mapping JAXB objects to business domain objects with Orika. Earlier this month, I covered the same mapping use case using reflection-based Dozer. In this post, I’ll assume the same example classes need to be mapped, but they will be … Continue reading

Posted in Java (General), JAXB, Syndicated | Comments Off on Orika: Mapping JAXB Objects to Business/Domain Objects

Closing 2013 with Core Java Posts

As 2013 starts drawing to a close, I have recently spotted several posts related to what I consider “core Java” knowledge appearing. This post is a listing of three posts and a forum with brief descriptions of these. I have two purposes in doing this: (1) to help others be aware of the existence of these fine posts and (2) to serve as a sort of glorified “bookmark” for myself when I want to find these again. These posts and forum were good enough to justify me taking the time to “print” (save) them to my hard drive as PDFs.

HotSpot JVM Flags

Kirk Pepperdine‘s “A Case Study of JVM HotSpot Flags” is an excellent resource on practical analysis and application of HotSpot’s JVM flags. Pepperdine demonstrates use of the -XX:+PrintFlagsFinal flag (I have blogged on this as well) to “identify the redundant flags by figuring out what the default settings are” so that he could remove deprecated flags and flags that simply explicitly set to the default values they would have had anyway. Pepperdine then analyzes some of the flags remaining after removal of deprecated flags and removal of flags that simply restated the defaults. He analyzes how they interact and sometimes supersede one another. Pepperdine’s concluding paragraph is well articulated advice:

I think it’s fantastic that we have a technology that is so configurable, so flexible. But this flexibility is a double edged sword and one shouldn’t just jump blindly into using all of that configurability. One thing I do know is that your applications performance does depend on how it’s configured. Messing up on even one flag can have a detrimental effect on the performance of your application and getting it wrong is far easier than getting it right. And quite often, the JVM does get it right, right out of the box.

Remote Java Debugging

Adam Bien‘s post “What are the Options of Remote Debugging…” provides a short review of key options available for debugging a remote Java process such as an application server. In this post, he references Connection and Invocation Details for greater details but provides concise summaries of available transports (dt_socket and dt_shmem for socket and Windows shared memory access respectively), suspend=y versus suspend=n, and server=y versus server=n.

Java Standard Library/Language Wish List

The question “What is a feature that the Java Standard Library desperately needs?” was recently asked on Reddit. I found the replies (72 so far) to be interesting for a variety of reasons. There were a few examples of comment authors demonstrating their superior knowledge at the expense of others as has become increasingly common in online forums, but most of the comments were insightful and provided an interesting perspective on what Java developers would like to see added to the language (in a few cases) or to the SDK (more common in replies, probably because more closely aligned with the question). Answers included all of subset of Guava, all or subset of Apache Commons, deprecation and removal of largely unused features and libraries, and properties annotations or other mechanism to replace get/set methods (or Project Lombok).

I thought that Tillerino made an insightful comment that some Java developers might not realize regarding the “commons” libraries like Apache Commons (Lang specifically) and Guava. Tillerino stated:

commons-lang per definition provides those classes which are not in the Java API. Is is not uncommon that features which commons-lang provides appear in the Java API and are then removed from commons-lang. I have used a couple of other packages and while commons-lang is probably part of 90% of all projects, the others are just way to specialized to be a part of the Java API. It’s important for Java developers to know which features are easily accessible through the commons, but I think the line has been drawn pretty well.

Recent examples of where Java SE has adopted and standardized popular libraries’ features include Java 7’s addition of the Objects class and Java 8’s addition of the Optional class, both of which have obvious similarities with classes such as Guava’s Objects class and Optional class. We see this in the Java EE world as well with one of the prime examples being the many new features of Java EE in recent years inspired by the Spring Framework.

This is a general principle that I have written about in my post Standardization: The Dangerous Relationship for Open Source. We developers should be “happy consumers” about this principle as open source seems to help refine best of breed ideas that the slower-moving standards organizations can adopt into the standards once those features’ popularity and usefulness is proven. These open source produces’ implementations allow us to use the feature before it is available in a standard implementation.

The RMI/Distributed Garbage Collection Connection

I appreciated Nikita Salnikov-Tarnovski‘s recent post RMI enforcing Full GC to run hourly for three reasons:

  1. The ultimate issue he addresses in this post is one I’ve run into before myself.
  2. I agree with his opening statement about the the bugs we are chasing down “are evolving and becoming meaner and uglier over time.”
  3. Salnikov-Tarnovski not only states the solution to this mean bug, but he describes his process for isolating the bug and determining its cause.

The issue that Salnikov-Tarnovski ran into had to do with the “hourly Full GC taking place” due to the setting of the HotSpot RMI property called sun.rmi.dgc.server.gcInterval. The fix for bug JDK-6200091 (“RMI gcInterval is too short by default”) lengthened the settings of sun.rmi.dgc.server.gcInterval and sun.rmi.dgc.server.gcInterval to one hour in Java SE 6. For reference, other posts of interest related to regular periodic distributed garbage collection include How we solved – GC every 1 minute on Tomcat, Analyze GC logs for Sun Hotspots, JVM 6, Unexplained System.gc() calls due to Remote Method Invocation (RMI) or explict garbage collections, and If you don’t do this JBoss will run really slowly.

I like that Salnikov-Tarnovski documented his steps in resolving the issue rather than simply stating the resolution. Although the resolution in this case was searching with Google search engine for someone else’s account of how to resolve the issue, the several steps tried before that can be illustrative to others of how to narrow down a problem and hone in on a defect. One of the greatest questions I’ve been asked on this blog was when a person left a comment asking how I found the fix that I had documented in that post. By the time I posted and read this comment, I had forgotten the steps I had used to resolve that particularly tricky issue and so could not really help.

In Salnikov-Tarnovski’s case in this post, about all that was provided was “sometimes the system is slow” (I’m sure many of us have been on the receiving end of that more than once). The steps used to diagnose the issue included monitoring response times to see a regular pattern, ruling out the usual suspects in cases like these, increasing logging output, and finally resorting to Google.

Conclusion

There are thousands of new posts each week detailing a wide variety of new technologies and tools for the software developer. These are valuable posts and help all of us to learn new things, but I also appreciate posts and forums that provide focus on “core concepts.” While core concepts may not be as exciting or flashy as new things, core concepts help us to better deliver and manage software for our customers’ benefit.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Java (General), Syndicated | Comments Off on Closing 2013 with Core Java Posts

Sublime Simplicity of Scripting with Groovy

Many of my blog posts are, as my blog’s title suggests, inspired by actual events. Three experiences this week have reminded me yet again of the simple simplicity of scripting with Groovy. In this post, I briefly look at each of these three events that are only related because they tie to Groovy and to scripting with Groovy.

Groovy Provides Easy Scripting for Java Developers

In the post I Use the main() Method, Bozhidar Bozhanov writes that he “[uses] a tool class with a main method” rather than scripting in Linux/bash or Windows PowerShell. Bozhanov goes explains this decision:

Java has a lot of powerful libraries that allow me to ditch the need of doing stuff in the shell or using bash scripts. And the good thing is – it’s Java, it can be versioned if needed, and it’s easy to use, with no additional learning curve, no man pages, etc.

Although I have been caught writing and maintaining Perl and have been known to use other scripting languages such as Ruby, Python, PHP, and shell/bash or PowerShell, I do also appreciate Bozhanov’s reasons for preferring a Java class with a main() function for developing tools. The JDK and JVM provide powerful and feature-rich libraries and capabilities and are familiar to me as a Java developer.

Groovy is a great scripting language for a person who is more comfortable with the JDK and JVM than with the underlying operating system. Groovy is easy for the Java developer to pick up and makes some things even easier than when written in Java. Groovy is particularly nice in providing “script-style” characteristics such as no need to write explicit objects, no need to write public static void main method definitions, no need to catch exceptions (checked or unchecked), built in command-line support, numerous useful GDK extensions of the JDK, dynamic typing, concise syntax (one-liners are extreme examples), easy access to root class loader for internal class loading, report-friendly output features, integrated Ant support, easy SQL access, easy XML parsing, improved regular expression support, and more.

One advantage of scripting with Groovy over some other scripting languages is the ability to run the Groovy scripts on any platform supporting a Java Virtual Machine.

Groovy Increases Java Knowledge

I have also blogged on using simple Java main classes to learn about the language. Earlier this week, a colleague ran into a surprising discovery related to Double.MIN_VALUE. When he asked if I knew what the value of Double.MIN_VALUE is, I told him that I don’t know off the top of my head, but then in a matter of seconds was able to tell him by running the following simple command on the command line:


groovy -e "println Double.MIN_VALUE"

The output of running this single line command was, as shown in the next screen snapshot, 4.9E-324. He asked me because he was (and now I was) surprised that it was not negative. After reading the Javadoc for Double.MIN_VALUE, this value made sense, but it was quicker for me to find the value by running that simple Groovy script than it was to access the Javadoc or even Google the question. I repeatedly find Groovy to be highly useful for quickly learning more about Java.

By the way, the Javadoc for Double.MIN_VALUE states (I added the emphasis), “A constant holding the smallest positive nonzero value of type double, 2-1074. It is equal to the hexadecimal floating-point literal 0x0.0000000000001P-1022 and also equal to Double.longBitsToDouble(0x1L).” I had assumed it was a negative number because I had never used it before and because of my previous experiences with negative values for Integer.MIN_VALUE and Long.MIN_VALUE. A great discussion on the reason for this selection of Double.MIN_VALUE (and applicable to Float.MIN_VALUE) is available on the StackOverflow thread Minimum values and Double.MIN_VALUE in Java?

Groovy Simplifies Native Integration

Although one of the advantages of scripting with Groovy is the ability to run Groovy scripts on any platform that supports a JVM, there are many times when scripts need to access the native operating system. Groovy has access to the native operating system via Java’s java.lang.Runtime and java.lang.Process. Groovy simplifies use of these classes through its GDK extension of the Process class.

The JDK Process class has a waitFor() method whose Javadoc description states (I added emphasis):

Causes the current thread to wait, if necessary, until the process represented by this Process object has terminated. This method returns immediately if the subprocess has already terminated. If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.

The class-level Javadoc for Process more clearly outlines the potential negative impact (I added emphasis):

Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, or even deadlock.

The excellent 2000 JavaWorld article When Runtime.exec() won’t shows examples of using Java code to write input and read output to avoid the block or deadlock, but Groovy’s Process GDK enhancement makes this far simpler to apply. For example, the Groovy GDK Process.waitForProcessOutput(Appendable, Appendable) method allows two StringBuilder instances, for example, representing standard output and standard error buffers to prevent “the process from blocking due to a full output buffer.”

The next two code listings and associated screen snapshots with the scripts’ outputs demonstrate this.

demoDeadlock.groovy – Process.waitFor() Deadlocks


#!/usr/bin/env groovy
def recursiveDirCmd = "cmd /c dir /s ${args[0]}"
println "Running command ${recursiveDirCmd}..."
def result = recursiveDirCmd.execute()
result.waitFor()
println result.in.text

demoNoDeadlock.groovy – Process.waitForProcessOutput(Appendable, Appendable) Does Not Deadlock


#!/usr/bin/env groovy
def recursiveDirCmd = "cmd /c dir /s ${args[0]}"
println "Running command ${recursiveDirCmd}..."
StringBuilder standard = new StringBuilder(450000)
StringBuilder error = new StringBuilder(450000)
def result = recursiveDirCmd.execute()
result.waitForProcessOutput(standard, error)
println standard

The above code listing and associated screen snapshots demonstrate that Groovy’s GDK extension of Process makes it easy to avoid blocking on commands executed against the underlying operating system. A good article on calling shell commands from Groovy code is Executing shell commands in Groovy.

Conclusion

Three different events this week reinforced my opinion of Groovy delivering a combination of Java’s power with Groovy’s scripting simplicity.

Original posting available at http://marxsoftware.blogspot.com/ (Inspired by Actual Events)

Continue reading

Posted in Groovy, Java (General), Syndicated | Comments Off on Sublime Simplicity of Scripting with Groovy