Evolution in Data Integration From EII to Big Data
Approaches to integrating data are changing with emergence of cloud computing.
The content has been bookmarked!
There was an error bookmarking this content! Please retry.
Posted by Alex Blewitt on Aug 23, 2010
Part of Project Coin is the ability to deal with Automatic Resource Management, or simply ARM. The purpose is to make it easier to work with external resources which need to be disposed or closed in case of errors or successful completion of a code block. Consider the following trivial file-copy operation, from the Java Bytestream Tutorial:
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("xanadu.txt");
out = new FileOutputStream("outagain.txt");
int c;
while ((c = in.read()) != -1)
out.write(c);
} finally {
if (in != null)
in.close();
if (out != null)
out.close();
}
Not only is there a lot of boiler plate, but the documentation for InputStream.close() suggests that it can throw an IOException. (An exception is far more likely on the OutputStream but in any case, there needs to be an outer catch or propagation in order to successfully compile this code.)
The lexical scope of the try-catch-finally block also requires the variable for FileInputStream in and FileOutputStream out to be declared lexically outside the block itself. (If they were defined inside the try block, then they wouldn't be available inside the catch or finally blocks.)
To eliminate this boilerplate code, and to tighten the lexical scoping of the resources used inside the block, a new addition has been made to the try block in the Java language. An initial specification of the try-with-resources blocks (or ARM blocks) was made available via an ininitial implementation, which has subsequently made its way into build 105 of JDK 7.
A new interface, java.lang.AutoCloseable, has been added to the proposed API, which defines a single method close() which throws Exception. This has been retro-fitted as a parent of java.io.Closeable, which means that all InputStream and OutputStream automatically take advantage of this behaviour. In addition, FileLock and ImageInputStream have also been fitted with the AutoCloseable interface.
This permits the above example to be written as:
try (
FileInputStream in = new FileInputStream("xanadu.txt");
FileOutputStream out = new FileOutputStream("outagain.txt")
) {
int c;
while((c=in.read()) != -1 )
out.write();
}
At the end of the try block, whether by completion normally or otherwise, both the out and in resources will have close() called automatically. Furthermore, unlike our original example, both out.close() and in.close() are guaranteed to be executed. (In the original example, had in.close() thrown an exception, then the subsequent out.close() would not have been executed.)
There are some subtle aspects to this which are worth noting:
() rather than the more usual {}, to separate it from the existing try body. If present, it must contain one or more resource definitions.final modifier is present. Any attempt to assign to the resource variable is a compile-time error.AutoCloseable; it is a compile-time error if this is not the case.out.close() is called prior to in.close(). This permits nested streams to be built and then closed from outer-in, which makes more sense than in order (e.g. for flushing buffers before the underlying stream is closed).getSuppressedExceptions().Suppressed: in these cases; the format of the serialized Throwable is now different as well. (This may impact Java 6 clients invoking remote services on Java 7 runtimes, or vice-versa.)javax.swing and java.sql do not participate in ARM at the current time; classes need to opt-in by inheriting from AutoCloseable to be used by ARM. JDBC 4.1, if part of JDK 7, will support ARM but it's not clear when this will happen.The ability to remove boilerplate code from the Java developer's work-flow is likely to be a minor productivity boost; but although it's available in JDK 7, it will be sometime before source code can be written to take advantage of that fact. Many libraries will need to be compiled to run against Java 6; and any use of the automatic resource management will only be applicable for code compiled with -target 7 (or similar). Once Java 6 is EOL and Java 8 has been released, then using ARM will become an automatic way of working.
Monitor your Production Java App - includes JMX! Low Overhead - Free download
Using Drools? See what you're missing! Get the Power of Drools with the Assurance of Red Hat
In today’s hyper-competitive world, later may be too late to adopt Agile development and this Roadmap for Success will help you get started. Download "Agile Development: A Manager's Roadmap for Success" now!
I think I've seen this somewhere before... maybe about 5 years ago? :-)
.
One of the first lessons we as parents teach to our children is: Learn from others.
Why does this not apply to programming languages?
Try-catch-finally is about error handling and not about ARM.
Thus, why complicate the try-catch-finally instead introducing "using" as .NET is using it?
Have a look at msdn.microsoft.com/en-us/library/yh598w02%28VS.... it's simple, clear and straight forward.
This way we can even rename "java.lang.AutoCloseable" to "java.lang.Closeable" as it's not about auto-closing but about a clearly programmed/stated behavior being part of "using".
It's all about taking advantage of the fillets of each language.
Note: I'm not going into a debate .NET vs. Java - I won't.
Try-catch-finally is about error handling and not about ARM.
I have to agree that using the try keyword for this doesn't seem very good. I have to guess that the reason a new keyword wasn't used (such as 'using') is because the fear that existing code will not compile. Although, this did not prevent enum from being added which was more likely (I guess) to be used as a name in existing code.
what if it could be implemented using closures? Would coin's new syntax be able to do something similar to this, but without the extra boilerplate:
Closeable.close(new FileInputStream("xanadu.txt")) {
public void read(FileInputStream in) {
in.read();
}
});
...where Closeable.close is a static generic method that returned an object specifically used for closing after reading. Could even be a static import, but you'd still have to define the read(T) override.
At least it would be re-using another feature of the language (closures) and not introducing another keyword.
When I see the using() {} statement in C# it makes me think of blocks in languages like Ruby/Groovy.
I'd have thought it would just be a method on Closeable. So you could do something like:
FileInputStream inputStream = new FileInputStream("xanadu.txt");
inputStream.with({ FileInputStream in ->
in.read();
});
Potentially if you made the instance variable final you wouldn't even need to pass it in as an argument to the lambda. The "with" method would call the closure in a try block and close itself cleanly in the finally block.
It does seem odd that this should be implemented at the same time as lambdas if lambdas would allow it to be implemented cleanly without further new syntax. Perhaps there's some subtlety to it that I'm missing.
Approaches to integrating data are changing with emergence of cloud computing.
Michele Ide-Smith presents the lessons learned in the process of introducing UX principles and techniques into a large organization through a series of small steps.
Dave Farley and Martin Thompson discuss solutions for doing low-latency high throughput transactions based on the Disruptor concurrency pattern.
Rajneesh Namta shares his thoughts, experiences, and some of the critical lessons learned while implementing software test automation on a recent Agile project.
Dale Schumacher presents several patterns of actor interaction that can be used in collaborative programs written in any language.
Rúnar Bjarnason discusses Scalaz, a Scala library of pure data structures, type classes, highly generalized functions, and concurrency abstractions to perform functional programming in Scala.
One of the main challenges when designing software architecture is considering quality attributes. Not only their design turns out to be difficult, but also the specification of these attributes.
Michael Feathers analyzes real code bases concluding that code is not nearly as beautiful as designers aspire to, discussing the everyday decisions that alter the code bit by bit.
6 comments
Watch Thread Reply