<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1214048633682585732</id><updated>2011-11-16T08:41:11.778-06:00</updated><category term='java jdk'/><category term='i/o'/><category term='jboss'/><category term='marshalling'/><category term='jsr-277'/><category term='river'/><category term='java'/><category term='jsr-294'/><category term='closures'/><category term='modularity'/><category term='jsr-310'/><category term='remoting'/><title type='text'>David M. Lloyd</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>38</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-2570803638416055397</id><published>2010-09-10T10:48:00.000-05:00</published><updated>2010-09-10T10:48:12.528-05:00</updated><title type='text'>Moving!</title><content type='html'>As of today, my blog is officially moving to a new home at&amp;nbsp;&lt;a href="http://in.relation.to/Bloggers/David"&gt;in.relation.to&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-2570803638416055397?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2570803638416055397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2570803638416055397'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2010/09/moving.html' title='Moving!'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-5569054252617157483</id><published>2010-02-23T14:45:00.003-06:00</published><updated>2010-02-23T14:52:26.889-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Safely downgrading a write lock with ReadWriteLock</title><content type='html'>A simple pattern to downgrade a write lock to a read lock safely:&lt;br /&gt;&lt;pre&gt;    ReadWriteLock rwl = getLock();&lt;br /&gt;   Lock lock = rwl.writeLock();&lt;br /&gt;   lock.lock();&lt;br /&gt;   try {&lt;br /&gt;       ... Perform write operation ...&lt;br /&gt;       // downgrade lock safely&lt;br /&gt;       final Lock readLock = rwl.readLock();&lt;br /&gt;       readLock.lock(); // Possible failure #1&lt;br /&gt;       try {&lt;br /&gt;           lock.unlock(); // Possible failure #2&lt;br /&gt;       } finally {&lt;br /&gt;           lock = readLock;&lt;br /&gt;       }&lt;br /&gt;   } finally {&lt;br /&gt;       lock.unlock();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;The reason this works is as follows:&lt;br /&gt;&lt;br /&gt;1. Anything which fails before possible failure #1 will cause the original lock to unlock, due to the &lt;code&gt;finally&lt;/code&gt; block.&lt;br /&gt;2. If possible failure #1 occurs, the read lock is never locked, thus the write lock is still unlocked in the outer &lt;code&gt;finally&lt;/code&gt; block.&lt;br /&gt;3. If possible failure #2 occurs, the now-locked read lock is stashed into &lt;code&gt;lock&lt;/code&gt; thanks to the inner &lt;code&gt;finally&lt;/code&gt; block, thus the read lock is released in the outer &lt;code&gt;finally&lt;/code&gt; block.  At this point, no matter what, the write lock is released.&lt;br /&gt;4. Any failure after possible failure #2 will cause the outer &lt;code&gt;finally&lt;/code&gt; block to release the read lock.&lt;br /&gt;&lt;br /&gt;The nice thing about this approach is that you can even downgrade the lock inside of a conditional and the structure is not broken.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-5569054252617157483?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/5569054252617157483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=5569054252617157483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5569054252617157483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5569054252617157483'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2010/02/safely-downgrading-write-lock-with.html' title='Safely downgrading a write lock with ReadWriteLock'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-6539486713462844463</id><published>2010-01-25T14:21:00.003-06:00</published><updated>2010-01-25T14:30:08.433-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 2.0.2 Bugfix Release</title><content type='html'>A new release of &lt;a href="http://jboss.org/xnio"&gt;XNIO&lt;/a&gt; is available which fixes several bugs.  For more information about XNIO 2.0, see &lt;a href="http://dmlloyd.blogspot.com/2009/11/xnio-200-has-landed.html"&gt;this previous post&lt;/a&gt;.  Users of XNIO 2.0.0 and 2.0.1 are encouraged to update to 2.0.2 to take advantage of these bug fixes:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href="https://jira.jboss.org/jira/browse/XNIO-82"&gt;XNIO-82&lt;/a&gt;] - Remove jboss-classloading.xml from artifact&lt;/li&gt;&lt;li&gt;[&lt;a href="https://jira.jboss.org/jira/browse/XNIO-83"&gt;XNIO-83&lt;/a&gt;] - Getting an option from a string fails due to typo&lt;/li&gt;&lt;li&gt;[&lt;a href="https://jira.jboss.org/jira/browse/XNIO-84"&gt;XNIO-84&lt;/a&gt;] - Enable all supported SSL cipher suites if none are explicitly enabled&lt;/li&gt;&lt;li&gt;[&lt;a href="https://jira.jboss.org/jira/browse/XNIO-85"&gt;XNIO-85&lt;/a&gt;] - Possible deadlock in SSL negotiation phase&lt;/li&gt;&lt;li&gt;[&lt;a href="https://jira.jboss.org/jira/browse/XNIO-86"&gt;XNIO-86&lt;/a&gt;] - CCE produced when casting a null option value&lt;/li&gt;&lt;li&gt;[&lt;a href="https://jira.jboss.org/jira/browse/XNIO-87"&gt;XNIO-87&lt;/a&gt;] - XNIO log messages don't preserve the source class/method name&lt;/li&gt;&lt;li&gt;[&lt;a href="https://jira.jboss.org/jira/browse/XNIO-88"&gt;XNIO-88&lt;/a&gt;] - Open listener specification is now optional; do not throw NPE if it is not provided&lt;/li&gt;&lt;/ul&gt;The release is available from the &lt;a href="http://jboss.org/xnio/downloads"&gt;downloads page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-6539486713462844463?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/6539486713462844463/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=6539486713462844463' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6539486713462844463'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6539486713462844463'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2010/01/xnio-202-bugfix-release.html' title='XNIO 2.0.2 Bugfix Release'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-1284709991522224541</id><published>2010-01-05T14:28:00.003-06:00</published><updated>2010-01-05T14:34:51.381-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='marshalling'/><category scheme='http://www.blogger.com/atom/ns#' term='river'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>JBoss Marshalling 1.2.0 Released, Website Upgraded</title><content type='html'>Some of you may have noticed that JBoss Marshalling 1.2.0.GA has been present &lt;a href="http://repository.jboss.org/maven2/org/jboss/marshalling/"&gt;in the maven repository&lt;/a&gt; for some time.  Now that &lt;a href="http://www.jboss.org/jbossmarshalling"&gt;the website&lt;/a&gt; upgrade is complete, I'm happy to announce that it is now available from &lt;a href="http://www.jboss.org/jbossmarshalling/downloads"&gt;the downloads page&lt;/a&gt; as well.&lt;br /&gt; &lt;br /&gt; JBoss Marshalling is a framework which wholly replaces Java Serialization with a new API and optional optimized wire format.  The standard wire format can also be used as well - giving compatibility with applications using standard serialization, but without the various bugs present therein, and with a potentially significant performance advantage.&lt;br /&gt; &lt;br /&gt; Other features that JBoss Marshalling provides which are missing from the Java Object*Stream API include:&lt;br /&gt; &lt;div id="proj_checklist"&gt; &lt;ul&gt;&lt;li&gt;Pluggable class resolvers, making it easy to customize classloader policy, by implementing a small interface (rather than having to subclass the &lt;code&gt;Object*Stream&lt;/code&gt; classes)&lt;/li&gt;&lt;li&gt;Pluggable object replacement (also without subclassing)&lt;/li&gt;&lt;li&gt;Pluggable predefined class tables, which can dramatically decrease stream size and serialization time for stream types which frequently use a common set of classes&lt;/li&gt;&lt;li&gt;Pluggable predefined instance tables, which make it easy to handle remote references&lt;/li&gt;&lt;li&gt;Pluggable externalizers which may be used to serialize classes which are not &lt;code&gt;Serializable&lt;/code&gt;, or for which an alternate strategy is needed&lt;/li&gt;&lt;li&gt;Customizable stream headers&lt;/li&gt;&lt;li&gt;Each marshaller instance is highly configurable and tunable to maximize performance based on expected usage patterns&lt;/li&gt;&lt;li&gt;A generalized API which can support many different protocol implementations, including protocols which do not necessarily provide all the above features&lt;/li&gt;&lt;li&gt;Inexpensive instance creation, beneficial to applications where many short-lived streams are used&lt;/li&gt;&lt;li&gt;Support for separate class and instance caches, if the protocol permits; useful for sending multiple messages or requests with a single stream, with separate object graphs but retaining the class cache&lt;/li&gt;&lt;/ul&gt; &lt;/div&gt;The 1.2.0 release features many more optimizations to the River protocol implementation, enhanced error reporting (the object stack is included with the exception stack trace), run-time detection of implementations via the &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?java/util/ServiceLoader.html"&gt;ServiceLoader&lt;/a&gt; mechanism, and helper classes to simplify integration with NIO-based applications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-1284709991522224541?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/1284709991522224541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=1284709991522224541' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1284709991522224541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1284709991522224541'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2010/01/jboss-marshalling-120-released-website.html' title='JBoss Marshalling 1.2.0 Released, Website Upgraded'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-906678225327663361</id><published>2009-12-09T21:33:00.006-06:00</published><updated>2009-12-09T22:06:13.518-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java jdk'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr-294'/><category scheme='http://www.blogger.com/atom/ns#' term='modularity'/><category scheme='http://www.blogger.com/atom/ns#' term='jsr-277'/><title type='text'>JSR 294/277: Why don't we have standard Java modularity?</title><content type='html'>Why is it so difficult to write a modularity specification for Java?  The requirements appear to be relatively simple:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Provide an API whereby a user can load a module and link to it (in other words, get a classloader which can be used to load exported classes), possibly with a mechanism to "run" a module, similar to how one can execute "java -jar foo.jar" today&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Support a per-module access control level, in the Java language and JVM&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Provide a way to specify what other modules are required/optional, and whether they are imported or imported and exported (in other words, "metadata")&lt;/li&gt;&lt;li&gt;Provide a way to recursively locate, load, register, and link referenced modules in an efficient manner (in other words, "resolution")&lt;/li&gt;&lt;/ol&gt;So what would it take to implement this?  Not much from what I can see.&lt;br /&gt;&lt;br /&gt;The user API would amount to a new ModuleLoader class which has API elements to load a module and return an instance of a new Module class, which has the ability to either access the exported classes therein directly, or get at a ClassLoader which can do so.&lt;br /&gt;&lt;br /&gt;A per-module access control level can be implemented by one simple rule: If a class is loaded from a module's ClassLoader, change "package-private" to mean "module-private" instead.  Otherwise, stick to the old rules.  Very straightforward.&lt;br /&gt;&lt;br /&gt;Metadata can be implemented very simply as plain data objects which are read by the appropriate ModuleLoader, or even as an implementation detail of ModuleLoader itself.&lt;br /&gt;&lt;br /&gt;Resolution could (and should) be a pluggable thing within a ModuleLoader.  This would enable customized handling like the ability to load modules right out of Maven, or the ability to download modules on demand from a trusted remote repository.&lt;br /&gt;&lt;br /&gt;So what's the deal?  Wouldn't this small group of classes (and one small JLS/JVM change) be sufficient to solve the problem?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-906678225327663361?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/906678225327663361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=906678225327663361' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/906678225327663361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/906678225327663361'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/12/jsr-294277-why-dont-we-have-standard.html' title='JSR 294/277: Why don&apos;t we have standard Java modularity?'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-4293118891827343888</id><published>2009-12-04T12:44:00.003-06:00</published><updated>2009-12-04T12:47:02.272-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 2.0.1 Bugfix Release</title><content type='html'>I've uploaded a minor bugfix release for XNIO 2.0.0.  It fixes a selector wakeup bug, as well as a minor API bug and a minor optimization for blocking I/O with the NIO-based provider.&lt;br /&gt;&lt;br /&gt;All users of 2.0.0 are encouraged to update to 2.0.1.  The release is available on &lt;a href="http://www.jboss.org/xnio/downloads"&gt;the download page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-4293118891827343888?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/4293118891827343888/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=4293118891827343888' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4293118891827343888'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4293118891827343888'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/12/xnio-201-bugfix-release.html' title='XNIO 2.0.1 Bugfix Release'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-8231283575347855972</id><published>2009-11-25T16:58:00.004-06:00</published><updated>2009-12-08T10:49:20.359-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 2.0.0 has landed</title><content type='html'>XNIO is a simplified low-level I/O layer which can be used anywhere you are using NIO today. It frees you from the hassle of dealing with Selectors and NIO's poor support for SSL, multicast sockets and non-socket I/O, while still maintaining all the capabilities present in NIO.  The XNIO 2.0.0 release includes all of the features of the 1.x series, including:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;API compatibility with NIO channels and APIs which consume them&lt;/li&gt;&lt;li&gt;Powerful callback-based API for channel status changes&lt;/li&gt;&lt;li&gt;Very simple API for data transfer on channels&lt;/li&gt;&lt;li&gt;Enhanced NIO buffer support, with many convenience methods to make traditionally difficult buffer manipulation tasks easier&lt;/li&gt;&lt;li&gt;TCP and UDP client and server support&lt;/li&gt;&lt;li&gt;API support for other socket types (such as UNIX domain sockets)&lt;/li&gt;&lt;li&gt;The ability to intermix blocking and non-blocking I/O operations freely and easily&lt;/li&gt;&lt;li&gt;JMX management for all channels&lt;/li&gt;&lt;li&gt;Powerful &lt;a href="http://docs.jboss.org/xnio/2.0/api/index.html?org/jboss/xnio/IoFuture.html"&gt;&lt;code&gt;IoFuture&lt;/code&gt;&lt;/a&gt; interface and support classes simplify asynchronous I/O operation support in XNIO as well as in your application&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;And these new features:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SSL channel types for easy SSL support - vastly simpler than the NIO-targeted &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?javax/net/ssl/SSLEngine.html"&gt;&lt;code&gt;SSLEngine&lt;/code&gt;&lt;/a&gt; API&lt;/li&gt;&lt;li&gt;New channel listener interface which makes implementing clients and servers even simpler&lt;/li&gt;&lt;li&gt;Runtime-switchable event listener registration for easy support of "state pattern"-based protocol implementations&lt;/li&gt;&lt;li&gt;Support for JMX-managed old-I/O &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?javax/net/SocketFactory.html"&gt;&lt;code&gt;SocketFactory&lt;/code&gt;&lt;/a&gt; and &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?javax/net/ServerSocketFactory.html"&gt;&lt;code&gt;ServerSocketFactory&lt;/code&gt;&lt;/a&gt; instances to retrofit legacy applications with management capabilities&lt;/li&gt;&lt;li&gt;Service location API which frees users from a compile-time dependency on an implementation JAR&lt;/li&gt;&lt;li&gt;A new &lt;a href="http://www.jboss.org/xnio/docs"&gt;User Guide&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Simplified channel API makes custom channel implementation easy&lt;/li&gt;&lt;li&gt;Improved generic configuration API via immutable &lt;a href="http://docs.jboss.org/xnio/2.0/api/index.html?org/jboss/xnio/OptionMap.html"&gt;&lt;code&gt;OptionMap&lt;/code&gt;&lt;/a&gt; class&lt;/li&gt;&lt;li&gt;Improved API to allow user applications to easily provide &lt;a href="http://docs.jboss.org/xnio/2.0/api/index.html?org/jboss/xnio/IoFuture.html"&gt;&lt;code&gt;IoFuture&lt;/code&gt;&lt;/a&gt; implementations&lt;/li&gt;&lt;li&gt;Improved zero-copy integration with NIO's &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?java/nio/channels/FileChannel.html"&gt;&lt;code&gt;FileChannel&lt;/code&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;And many more...&lt;/li&gt;&lt;/ul&gt;The project page is at &lt;a href="http://www.jboss.org/xnio"&gt;http://www.jboss.org/xnio&lt;/a&gt;.  Download the release from the &lt;a href="http://www.jboss.org/xnio/downloads"&gt;download page&lt;/a&gt;, or in the &lt;a href="http://repository.jboss.org/maven2"&gt;JBoss Maven repository&lt;/a&gt; under the &lt;a href="http://repository.jboss.org/maven2/org/jboss/xnio"&gt;&lt;code&gt;org.jboss.xnio&lt;/code&gt;&lt;/a&gt; group ID.  The documentation, including Javadoc and the user manual, are available on &lt;a href="http://www.jboss.org/xnio/docs"&gt;the docs page&lt;/a&gt;.  Issues can be filed in the project's &lt;a href="https://jira.jboss.org/jira/browse/XNIO"&gt;JIRA bug tracker&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-8231283575347855972?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/8231283575347855972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=8231283575347855972' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/8231283575347855972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/8231283575347855972'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/11/xnio-200-has-landed.html' title='XNIO 2.0.0 has landed'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-6028871423199557753</id><published>2009-11-02T14:30:00.003-06:00</published><updated>2009-11-02T17:20:05.463-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 2.0.0.CR4 Released</title><content type='html'>XNIO 2.0 is getting very close to completion.  The latest CR, 2.0.0.CR4, is now available from &lt;a href="http://www.jboss.org/xnio/downloads"&gt;the downloads page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The main change since CR3 is the introduction of a new "Result" interface which acts as feed-in to an IoFuture.  This makes it easy for developers to create an API which exposes IoFuture results to the user, without worrying as much about implementation details.  Various support classes have also been added for this purpose.  In addition, the implementation classes have been ported to use the new API.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-6028871423199557753?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/6028871423199557753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=6028871423199557753' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6028871423199557753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6028871423199557753'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/11/xnio-200cr4-released.html' title='XNIO 2.0.0.CR4 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-5547049894569913170</id><published>2009-09-22T11:44:00.003-05:00</published><updated>2009-09-22T12:16:12.160-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='marshalling'/><category scheme='http://www.blogger.com/atom/ns#' term='river'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>New XNIO, JBoss Marshalling, and More...</title><content type='html'>Since my last post several months ago, I've been quite busy with a number of project releases.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;JBoss Marshalling version 1.2.0.CR3 - download &lt;a href="http://jboss.org/jbossmarshalling/downloads/"&gt;here&lt;/a&gt;, JIRA &lt;a href="https://jira.jboss.org/jira/browse/JBMAR"&gt;here&lt;/a&gt;.  Includes a much more efficient River protocol implementation, and the Java-compatible Serial implementation, both of which have been measured to outperform Java serialization by 50% or more in some cases, while retaining compliance with the Serialization specification.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;XNIO 2.0.0.CR2 - download &lt;a href="http://jboss.org/xnio/downloads/"&gt;here&lt;/a&gt;, JIRA &lt;a href="https://jira.jboss.org/jira/browse/XNIO"&gt;here&lt;/a&gt;.  Includes an improved API, as well as SSL support, which I think will be quite appreciated by anyone who has ever tried to use &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?javax/net/ssl/SSLEngine.html"&gt;SSLEngine&lt;/a&gt; with NIO.&lt;/li&gt;&lt;li&gt;JBoss LogManager 1.1.0.GA - available from the &lt;a href="http://repository.jboss.org/maven2/org/jboss/logmanager/jboss-logmanager/1.1.0.GA/"&gt;JBoss Maven Repository&lt;/a&gt;.  A complete re-implementation of the bug-ridden JDK &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?java/util/logging/LogManager.html"&gt;LogManager implementation&lt;/a&gt;, with additional handler types (including log4j compatibility), designed specifically to provide a highly efficient and cleanly implemented logging layer for JBossAS.&lt;/li&gt;&lt;li&gt;JBoss Logging 2.2.0.CR1 - available from the &lt;a href="http://repository.jboss.org/maven2/org/jboss/logging/"&gt;JBoss Maven Repository&lt;/a&gt;.  An improved version of the logging facade historically used by JBoss projects which run within JBossAS.  This new version improves memory usage by providing the ability for backend implementations to cache and reuse instances in a way that is not subject to the classical ClassLoader issues of other similar frameworks.  Also provides logging methods which take advantage of the JDK5 &lt;a href="http://java.sun.com/javase/6/docs/api/index.html?java/util/Formatter.html"&gt;java.util.Formatter&lt;/a&gt; class.&lt;/li&gt;&lt;/ul&gt;There are a number of other projects in the works as well, so stay tuned!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-5547049894569913170?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/5547049894569913170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=5547049894569913170' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5547049894569913170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5547049894569913170'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/09/new-xnio-jboss-marshalling-and-more.html' title='New XNIO, JBoss Marshalling, and More...'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-1641620366789550974</id><published>2009-02-25T17:48:00.004-06:00</published><updated>2009-02-25T22:48:36.037-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java jdk'/><title type='text'>Class-local data</title><content type='html'>&lt;p&gt;Today I ran across a problem that I've hit frequently in the past, this time while designing an extension to &lt;a href="http://www.jboss.org/jbossmarshalling"&gt;JBoss Marshalling&lt;/a&gt; which allows users to annotate classes which are to be specially externalized.  The problem is that one wants to "remember" what &lt;tt&gt;Externalizer&lt;/tt&gt; instances go with what classes on a semi-permanent basis; however, one does not wish to leak class references (which can lead to the permanent generation filling up, and your application crashing with an &lt;tt&gt;OutOfMemoryError&lt;/tt&gt;, especially if you're frequently loading and unloading classes).&lt;p&gt;The traditional solution to keep a leak-resistant cache is to employ a &lt;tt&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/util/WeakHashMap.html"&gt;WeakHashMap&lt;/a&gt;&lt;/tt&gt; like so (usually in conjunction with some concurrency strategy, like a &lt;tt&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/locks/Lock.html"&gt;Lock&lt;/a&gt;&lt;/tt&gt;):&lt;pre&gt;&lt;br /&gt;  private static final Map&amp;lt;Class&amp;lt;?&amp;gt;, Externalizer&amp;gt; cache = new WeakHashMap&amp;lt;Class&amp;lt;?&amp;gt;, Externalizer&amp;gt;();&lt;br /&gt;&lt;/pre&gt;The &lt;tt&gt;WeakHashMap&lt;/tt&gt; retains a weak reference to the key values (in this case, the &lt;tt&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/java/lang/Class.html"&gt;Class&lt;/a&gt;&lt;/tt&gt; instance), so if no strong references remain, the &lt;tt&gt;Class&lt;/tt&gt; is unloaded, and all is well.  However, in this particular use case, the &lt;tt&gt;Externalizer&lt;/tt&gt; instance very likely will itself hold a strong reference to the &lt;tt&gt;Class&lt;/tt&gt;.  Why?  Because in JBoss Marshalling, &lt;tt&gt;Externalizer&lt;/tt&gt; instances may be custom-designed with a single class in mind; thus, it might have a field or a constructor call of that class' type, which means strong reference.  Since &lt;tt&gt;WeakHashMap&lt;/tt&gt; retains a strong reference to its value, this means that there is a strong reference from my cache to the class after all, so all is for naught.&lt;p&gt;So I got to thinking - what if I could stash my &lt;tt&gt;Externalizer&lt;/tt&gt; instance on the &lt;tt&gt;Class&lt;/tt&gt; itself?  Then I wouldn't even need to keep a cache at all, and the only reference to the &lt;tt&gt;Class&lt;/tt&gt; that I could cause to be would be from the &lt;tt&gt;Class&lt;/tt&gt; itself. That would be awesome! Of course, we wouldn't want anyone else to be able to get at my data; it could be private to me, after all.  And we wouldn't want it to leak the other way - the &lt;tt&gt;Class&lt;/tt&gt; should not hold a direct strong reference to my class, yet we don't exactly want it to be a weak reference either (because then the data might disappear before I've had a chance to use it).&lt;p&gt;So my idea is to create a new type of storage: class-local data.  You'd access it similarly to thread-local data, except instead of being keyed from the current thread, you'd give it a class:&lt;pre&gt;&lt;br /&gt;  // The methods are similar to the corresponding methods on Map and ConcurrentMap&lt;br /&gt;  public final class ClassLocal&amp;lt;T&amp;gt; {&lt;br /&gt;     public T get(Class&amp;lt;?&amp;gt; clazz) { ... }&lt;br /&gt;     public T put(Class&amp;lt;?&amp;gt; clazz, T value) { ... }&lt;br /&gt;     public boolean hasData(Class&amp;lt;?&amp;gt; clazz) { ... }&lt;br /&gt;     public T putIfAbsent(Class&amp;lt;?&amp;gt; clazz, T value) { ... }&lt;br /&gt;     public T remove(Class&amp;lt;?&amp;gt; clazz) { ... }&lt;br /&gt;     public boolean remove(Class&amp;lt;?&amp;gt; clazz, T oldValue) { ... }&lt;br /&gt;     public T replace(Class&amp;lt;?&amp;gt; clazz, T newValue) { ... }&lt;br /&gt;     public boolean replace(Class&amp;lt;?&amp;gt; clazz, T oldValue, T newValue) { ... }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  private final ClassLocal&amp;lt;Externalizer&amp;gt; classLocal = new ClassLocal&amp;lt;Externalizer&amp;gt;();&lt;br /&gt;&lt;br /&gt;  ...in some method...&lt;br /&gt;  Externalizer externalizer = classLocal.get(SomeClass.class);&lt;br /&gt;&lt;/pre&gt;A &lt;tt&gt;ClassLocal&lt;/tt&gt; instance looks and acts a lot like a map, but with one important difference: the data itself is stored on the &lt;tt&gt;Class&lt;/tt&gt; instance, not in the &lt;tt&gt;ClassLocal&lt;/tt&gt;.  Implementation-wise this could be accomplished via a &lt;tt&gt;WeakHashMap&lt;/tt&gt; or similar structure on the &lt;tt&gt;Class&lt;/tt&gt; itself (with a concurrency strategy) similar to this:&lt;pre&gt;&lt;br /&gt;  public final class Class&amp;lt;T&amp;gt; {&lt;br /&gt;     ...&lt;br /&gt;     final Map&amp;lt;ClassLocal&amp;lt;?&amp;gt;, Object&amp;gt; classLocalData = Collections.synchronizedMap(new WeakHashMap&amp;lt;ClassLocal&amp;lt;?&amp;gt;, Object&amp;gt;());&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;...which could then be accessed directly by the &lt;tt&gt;ClassLocal&lt;/tt&gt; implementation.  Real JDK experts could probably think of a few ways to optimize this - e.g. avoid creating a map instance until someone puts data there, come up with a more clever locking strategy, etc.&lt;p&gt;&lt;b&gt;Update:&lt;/b&gt; As I ought to have expected, I'm nowhere near the first person ever to let their mind wander down this path - there's a &lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6493635"&gt;Sun bug (#6493635)&lt;/a&gt; about it, as well as articles by such clever folks as &lt;a href="http://crazybob.org/2006/12/caching-class-related-information.html"&gt;Crazy Bob&lt;/a&gt; and &lt;a href="http://weblogs.java.net/blog/jhook/archive/2006/12/class_metadata.html"&gt;Jacob Hookom&lt;/a&gt; about this very topic.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-1641620366789550974?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/1641620366789550974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=1641620366789550974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1641620366789550974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1641620366789550974'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/02/class-local-data.html' title='Class-local data'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-2714053744680632513</id><published>2009-02-06T14:35:00.004-06:00</published><updated>2009-02-07T08:06:35.353-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='marshalling'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>New protocols in JBoss Marshalling</title><content type='html'>It's official... I've checked in the first cut of the Java Serialization from-scratch implementation.  &lt;strike&gt;It's not complete yet - it doesn't even pass all the tests&lt;/strike&gt; (Update: everything works now - check it out from SVN and try it!) - but I expect that it will be fully functional by the 1.1.0 release (and, coincidentally, by the time I will be giving &lt;a href="http://javasymposium.techtarget.com/html/architecture.html?track=NL-476&amp;ad=684048&amp;Offer=JSemtssunsc112h&amp;asrc=EM_UTC_5542644&amp;uid=7850586#DLloydMarsh"&gt;my JBoss Marshalling talk at TSSJS&lt;/a&gt;).  Also in progress is Ron Sigal's JBoss Serialization implementation, which should be in 1.2.0 at the latest.&lt;p&gt;Look for the 1.1.0.GA release the week of February 23rd.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-2714053744680632513?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/2714053744680632513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=2714053744680632513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2714053744680632513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2714053744680632513'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/02/new-protocols-in-jboss-marshalling.html' title='New protocols in JBoss Marshalling'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-7276472392596985586</id><published>2009-01-13T18:09:00.003-06:00</published><updated>2009-01-13T19:11:02.301-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.2.0.GA Released</title><content type='html'>The final GA release of XNIO 1.2.0 is &lt;a href="http://www.jboss.org/xnio/downloads"&gt;available for download&lt;/a&gt;.  This release represents a "settling in" to a 16-week release cycle that should continue from now on.  Here's a complete changelog since 1.1.0.GA:&lt;p&gt;&lt;h2&gt;Bugs&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-56'&gt;XNIO-56&lt;/a&gt;] -         Xnio.create() fails for the default provider&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-57'&gt;XNIO-57&lt;/a&gt;] -         NioSocketChannelImpl suspendWrites method suspends reads instead of writes&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-58'&gt;XNIO-58&lt;/a&gt;] -         NPE bug in AllocatedMessageChannelStreamChannelHandler&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-60'&gt;XNIO-60&lt;/a&gt;] -         NIO: When pooled selectors are exhausted, an exception is thrown&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-65'&gt;XNIO-65&lt;/a&gt;] -         NioPipeTestCase.testOneWayPipeSinkClose fails under Java 5&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-67'&gt;XNIO-67&lt;/a&gt;] -         TCP tests fail under Java 5, not Java 6&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;h2&gt;Feature Request&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-19'&gt;XNIO-19&lt;/a&gt;] -         Add ability to switch a channel between blocking and non-blocking&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-50'&gt;XNIO-50&lt;/a&gt;] -         Mitigate the performance impact of Selector.wakeup()&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-54'&gt;XNIO-54&lt;/a&gt;] -         API for one-time servers&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-64'&gt;XNIO-64&lt;/a&gt;] -         IoFuture notifiers with attachments (&lt;b&gt;see below&lt;/b&gt;)&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-66'&gt;XNIO-66&lt;/a&gt;] -         Add static blocking read/write methods to Channels&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;h2&gt;Task&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-17'&gt;XNIO-17&lt;/a&gt;] -         Add monitoring via JMX&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-39'&gt;XNIO-39&lt;/a&gt;] -         Remove deprecated Xnio.createNio() methods&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-48'&gt;XNIO-48&lt;/a&gt;] -         Create a UNIX domain socket API&lt;/li&gt;&lt;li&gt;[&lt;a href='https://jira.jboss.org/jira/browse/XNIO-64'&gt;XNIO-64&lt;/a&gt;] -         IoFuture notifiers with attachments&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;h2&gt;Links&lt;/h2&gt;&lt;p&gt;Download: &lt;a href="http://www.jboss.org/xnio/downloads"&gt;http://www.jboss.org/xnio/downloads&lt;/a&gt;&lt;br&gt;Javadoc: &lt;a href="http://docs.jboss.org/xnio/1.2.0.GA/api"&gt;http://docs.jboss.org/xnio/1.2.0.GA/api&lt;/a&gt;&lt;br&gt;Project page: &lt;a href="http://www.jboss.org/xnio"&gt;http://www.jboss.org/xnio&lt;/a&gt;&lt;br&gt;Bug tracker: &lt;a href="https://jira.jboss.org/jira/browse/XNIO"&gt;https://jira.jboss.org/jira/browse/XNIO&lt;/a&gt;&lt;p&gt;Just a reminder that the 1.2.0.GA release is &lt;b&gt;not 100% binary- and source-compatible with 1.1.x&lt;/b&gt;, so if you choose to move to 1.2.0.GA, make sure you do a clean build of your project to identify any potential problems with the changes surrounding the new &lt;code&gt;IoFuture&lt;/code&gt; attachment feature.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-7276472392596985586?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/7276472392596985586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=7276472392596985586' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7276472392596985586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7276472392596985586'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/01/xnio-120ga-released.html' title='XNIO 1.2.0.GA Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-4714323323280886153</id><published>2009-01-07T20:47:00.003-06:00</published><updated>2009-01-07T21:04:24.128-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.2.0.CR2 Released</title><content type='html'>The XNIO 1.2.0.CR2 release is up on &lt;a href="http://www.jboss.org/xnio"&gt;the project page&lt;/a&gt;.  This release features cleaned up Javadoc, several bug fixes, and a few handy new features (in particular, static methods to perform blocking reads/writes for most common channel types).&lt;p&gt;The biggest change is the ability to pass an attachment in to an &lt;code&gt;IoFuture&lt;/code&gt; instance, via the &lt;a href="http://docs.jboss.org/xnio/1.2.0.CR2/api/org/jboss/xnio/IoFuture.html#addNotifier(org.jboss.xnio.IoFuture.Notifier,%20A)"&gt;&lt;code&gt;IoFuture.addNotifier()&lt;/code&gt;&lt;/a&gt; method.  This allows users to reuse notifier instances, which is a very powerful capability.  Unfortunately there was no clean way to add this feature without breaking compatibility in some way, so I went for the cleanest implementation possible, which means that &lt;b&gt;XNIO 1.2.x is not 100% binary- and source-compatible with XNIO 1.1.x&lt;/b&gt;.  I hope that this feature is useful enough that you will all forgive me for that change.  Because of this change I will maintain the 1.1.x series for longer than I otherwise might, in case there are users out there who are committed to the old API.&lt;p&gt;Read the Javadoc &lt;a href="http://docs.jboss.org/xnio/1.2.0.CR2/api"&gt;here&lt;/a&gt;, download the release &lt;a href="http://www.jboss.org/xnio/downloads/"&gt;here&lt;/a&gt;, report bugs &lt;a href="http://jira.jboss.org/jira/browse/XNIO"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-4714323323280886153?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/4714323323280886153/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=4714323323280886153' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4714323323280886153'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4714323323280886153'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2009/01/xnio-120cr2-released.html' title='XNIO 1.2.0.CR2 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-8222611585744880005</id><published>2008-12-18T21:23:00.002-06:00</published><updated>2008-12-18T21:35:26.493-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='remoting'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Remoting 3.0.0.Beta2 Released</title><content type='html'>This is the last Beta before the CR (candidate for release) series.  As always, the download is available at &lt;a href="http://www.jboss.org/jbossremoting/downloads"&gt;the Remoting download page&lt;/a&gt;.  This release differs from Beta1 in several ways, not the least of which is the more complete distribution, which includes source JARs and API Javadoc as well as the Remoting JARs themselves.  View the &lt;a href="http://jira.jboss.com/jira/secure/ReleaseNote.jspa?version=12312965&amp;styleName=Text&amp;projectId=10031&amp;Create=Create"&gt;release notes&lt;/a&gt; for the full list of differences.&lt;p&gt;The online Javadoc is &lt;a href="http://docs.jboss.org/remoting/3.0.0.Beta2/api/"&gt;available here&lt;/a&gt;.  Also, there are &lt;a href="http://anonsvn.jboss.org/repos/jbossremoting/remoting3/tags/3.0.0.Beta2/samples/src/main/java/org/jboss/remoting/samples/simple/"&gt;a few code samples&lt;/a&gt; available in the Subversion repository.  Please feel free to report bugs in &lt;a href="http://jira.jboss.com/jira/browse/JBREM"&gt;the Remoting JIRA bug tracker&lt;/a&gt;, making sure to mark the proper version when doing so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-8222611585744880005?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/8222611585744880005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=8222611585744880005' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/8222611585744880005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/8222611585744880005'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/12/remoting-300beta2-released.html' title='Remoting 3.0.0.Beta2 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-3354772759198764660</id><published>2008-12-16T18:56:00.002-06:00</published><updated>2008-12-16T19:06:18.819-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.2.0.CR1 Released</title><content type='html'>XNIO 1.2.0.CR1 is available for download at &lt;a href="http://www.jboss.org/xnio/downloads/"&gt;the XNIO project download page&lt;/a&gt;, sporting lots of cool new features, like:&lt;ul&gt;&lt;li&gt;The ability to switch between blocking and non-blocking modes&lt;/li&gt;&lt;li&gt;Wrapper Input/OutputStreams for channels&lt;/li&gt;&lt;li&gt;JMX monitoring&lt;/li&gt;&lt;li&gt;A restructured API/SPI system&lt;/li&gt;&lt;li&gt;A one-time server API (for services like IRC DCC and FTP that need to create one-shot server sockets)&lt;/li&gt;&lt;li&gt;The ability to change a server's bind address(es) after it has been started&lt;/li&gt;&lt;/ul&gt;...not to mention several performance improvements and code and documentation cleanup changes as well.  Check out the &lt;a href="http://docs.jboss.org/xnio/1.2.0.CR1/api/"&gt;API Javadocs&lt;/a&gt; as well.  Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-3354772759198764660?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/3354772759198764660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=3354772759198764660' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/3354772759198764660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/3354772759198764660'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/12/xnio-120cr1-released.html' title='XNIO 1.2.0.CR1 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-1287628729788908690</id><published>2008-11-14T17:07:00.003-06:00</published><updated>2008-11-14T17:57:26.530-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='remoting'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Remoting 3.0.0.Beta1 Released</title><content type='html'>The download is available at &lt;a href="http://www.jboss.org/jbossremoting/downloads/"&gt;the Remoting download page&lt;/a&gt;.  The structure is similar to the milestone releases; though it may be changing slightly for the next Beta.  I expect that there will be at most one more Beta, followed by a CR series.&lt;p&gt;Javadoc is available online at &lt;a href="http://docs.jboss.org/remoting/3.0.0.Beta1/api/"&gt;the docs site&lt;/a&gt;; bugs should be reported &lt;a href="https://jira.jboss.org/jira/secure/project/ViewProject.jspa?pid=10031"&gt;in the bug tracker&lt;/a&gt; (make sure you report the bug in the 3.0.0.Beta1 release).  See &lt;a href="http://www.jboss.org/jbossremoting/"&gt;the project page&lt;/a&gt; for more information.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-1287628729788908690?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/1287628729788908690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=1287628729788908690' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1287628729788908690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1287628729788908690'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/11/remoting-300beta1-released.html' title='Remoting 3.0.0.Beta1 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-1318971048837975634</id><published>2008-11-14T14:20:00.003-06:00</published><updated>2008-11-14T14:30:11.437-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='marshalling'/><category scheme='http://www.blogger.com/atom/ns#' term='river'/><category scheme='http://www.blogger.com/atom/ns#' term='remoting'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>JBoss Marshalling, River Protocol 1.0.0.GA Released</title><content type='html'>JBoss Marshalling is an alternative serialization API that fixes many of the problems found in the JDK serialization API while remaining fully compatible with &lt;code&gt;java.io.Serializable&lt;/code&gt; and its relatives, and adds several new tunable parameters and additional features, all of which are pluggable via factory configuration (externalizers, class/instance lookup tables, class resolution, and object replacement, to name a few).&lt;p/&gt;This project doesn't yet have an official home, but you can view the &lt;a href="http://docs.jboss.org/river/1.0.0.GA/api/"&gt;online API documentation right here&lt;/a&gt;, and the project is available for download at &lt;a href="http://repository.jboss.org/jboss/marshalling/1.0.0.GA/lib/"&gt;this location within the JBoss repository&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-1318971048837975634?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/1318971048837975634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=1318971048837975634' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1318971048837975634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1318971048837975634'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/11/jboss-marshalling-river-protocol-100ga.html' title='JBoss Marshalling, River Protocol 1.0.0.GA Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-7217900821442788757</id><published>2008-11-12T18:39:00.002-06:00</published><updated>2008-11-12T18:47:01.093-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.1.1.GA Released</title><content type='html'>The release available on &lt;a href="http://www.jboss.org/xnio/downloads/"&gt;the downloads page&lt;/a&gt;.  This is a bugfix release; I encourage all users of 1.1.0.GA to upgrade.&lt;p&gt;Here's the list of changes:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Fix a problem in the &lt;code&gt;Xnio.create()&lt;/code&gt; method's default provider lookup&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fix a problem where thread interruption could cause a tight spinloop&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fix a minor problem in the logger init code&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Merge the improved test log formatter from trunk&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-7217900821442788757?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/7217900821442788757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=7217900821442788757' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7217900821442788757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7217900821442788757'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/11/xnio-111ga-released.html' title='XNIO 1.1.1.GA Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-5165047736222031558</id><published>2008-10-23T10:58:00.003-05:00</published><updated>2008-10-23T11:06:00.376-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Binding to privileged ports with XNIO</title><content type='html'>A couple random ideas about how to bind privileged (&lt;1024) port numbers using XNIO.  It might be possible to utilize the UNIX domain socket API (slated for 1.2.0) and use the file descriptor-passing mechanism.  A root-privileged server (written in C) could be started that binds to a UNIX domain socket on the filesystem, whose access permissions are limited.  The XNIO-based application can use this domain socket to request bound ports and get the file descriptor back, which it would use to construct a server.&lt;p/&gt;Another idea would be to turn it around, and have the XNIO process run a setuid root program (via ProcessBuilder) which binds the port and hands it back through a socket created by the Java program.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-5165047736222031558?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/5165047736222031558/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=5165047736222031558' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5165047736222031558'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5165047736222031558'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/binding-to-privileged-ports-with-xnio.html' title='Binding to privileged ports with XNIO'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-4209399981956928023</id><published>2008-10-16T22:43:00.004-05:00</published><updated>2008-12-19T18:54:31.764-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='marshalling'/><category scheme='http://www.blogger.com/atom/ns#' term='river'/><category scheme='http://www.blogger.com/atom/ns#' term='remoting'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>JBoss Marshalling Framework 1.0.0.Beta2 Released</title><content type='html'>I'm pleased to announce that the second beta of the new marshalling framework has arrived.  The API is pretty much final at this point; now it's just a bug quest before the first CR is released in a couple weeks.  For more information about the features of the framework, please see &lt;a href="/2008/10/jboss-marshalling-framework-100beta1.html"&gt;the original Beta1 announcement&lt;/a&gt;.&lt;p&gt;Download the JARs from &lt;a href="http://repository.jboss.org/jboss/marshalling/1.0.0.Beta2/"&gt;the repository&lt;/a&gt;.  The documentation is available &lt;a href="http://docs.jboss.org/river/1.0.0.Beta2/api"&gt;here at the JBoss docs site&lt;/a&gt;.  Please report any bugs &lt;a href="https://jira.jboss.org/jira/browse/JBMAR"&gt;in the JBoss Marshalling bug tracker&lt;/a&gt;.&lt;p&gt;Many thanks to Ron Sigal, author of the Java serializaiton-compatible module, and the one who flushed out &lt;strike&gt;some&lt;/strike&gt; &lt;strike&gt;most&lt;/strike&gt; all of the bugs from the Beta1 River protocol implementation that were fixed in this version.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-4209399981956928023?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/4209399981956928023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=4209399981956928023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4209399981956928023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4209399981956928023'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/jboss-marshalling-framework-100beta2.html' title='JBoss Marshalling Framework 1.0.0.Beta2 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-7161686457740599621</id><published>2008-10-16T12:17:00.002-05:00</published><updated>2008-10-16T12:27:35.426-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Minor XNIO re-org for 1.2.0</title><content type='html'>For XNIO 1.2.0, I'm doing away with the separated API versus standalone JAR.  My original notion was that the standalone JAR would contain the whole API, plus the &lt;code&gt;Xnio&lt;/code&gt; bootstrapping class, plus at least one implementation (NIO right now, as that is currently the only complete implementation).  But I think it will be simpler going forward to just add &lt;code&gt;Xnio&lt;/code&gt; into the API itself, and ship an API JAR plus one JAR per implementation.  So from now on (including any future snapshots), the JARs will follow this new structure instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-7161686457740599621?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/7161686457740599621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=7161686457740599621' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7161686457740599621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7161686457740599621'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/minor-xnio-re-org-for-120.html' title='Minor XNIO re-org for 1.2.0'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-2473407533474328380</id><published>2008-10-13T13:39:00.003-05:00</published><updated>2008-10-13T13:49:08.797-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.1.0.GA Released</title><content type='html'>XNIO 1.1.0.GA is available &lt;a href="https://www.jboss.org/xnio/downloads/"&gt;on the XNIO downloads page&lt;/a&gt;.  Not much change since 1.1.0.CR1.  Just a Javadoc update, and one interface rename: &lt;code&gt;TcpClient&lt;/code&gt; has been renamed to &lt;code&gt;TcpChannelSource&lt;/code&gt; (see &lt;a href="https://jira.jboss.org/jira/browse/XNIO-55"&gt;XNIO-55&lt;/a&gt; for more information).  Also see the &lt;a href="http://docs.jboss.org/xnio/1.1.0.GA/api/index.html"&gt;online Javadocs&lt;/a&gt; for usage information.&lt;p&gt;Have fun!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-2473407533474328380?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/2473407533474328380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=2473407533474328380' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2473407533474328380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2473407533474328380'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/xnio-110ga-released.html' title='XNIO 1.1.0.GA Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-1555980646451618939</id><published>2008-10-08T08:04:00.003-05:00</published><updated>2008-10-08T09:09:24.223-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><title type='text'>Feedback about Dave's Dumb Closures</title><content type='html'>I've gotten some feedback about &lt;a href="/2008/09/daves-dumb-closures.html"&gt;my closure idea&lt;/a&gt;.  Some of it bad, some of it... also bad.  I thought I'd reply to all the comments in a new posting here rather than try to squeeze it all in to the crappy comment thing.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Rémi Forax said...&lt;br /&gt;&lt;br /&gt;You can't get ride of exception transparency, at least if you want to keep checked exceptions.&lt;br /&gt;&lt;br /&gt;Here is an interresting email from Neal Gafter:&lt;br /&gt;http://mail.openjdk.java.net/pipermail/closures-dev/2008-July/000174.html&lt;br /&gt;&lt;br /&gt;Do you have a way to write StringSwitch with your syntax/semantics ?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Rémi raises two separate points here, so I'll address them separately.  Firstly, there's the question of "exception transparency".  In response to this, please consider the following.  First, in my proposal, the passed in code block may only be directly executed from within the receiving method.  Therefore, the set of exceptions that may be thrown can be statically determined.  The JVM can thus "safely" throw undeclared checked exceptions from the closure body as long as the calling method can handle it.  The JVM would be able to verify this statically during bytecode validation.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Secondly, the question is whether one could use closures to write a StringSwitch as shown in Neal Gafter's email above.  The short answer is: no.  It is not possible to use closures in this way in Java.  The reason is that Java has a linear stack; therefore a closure in Java may not outlive its lexical scope.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Now I know you're thinking, "Pfft, this is proof that BGGA closures are better".  However this is where I point out that BGGA closures aren't closures, not in a JVM sense.  They're just a syntax shortcut for anonymous inner classes.  And the only way the so-called StringSwitch could possibly be implemented is basically as a syntactical wrapper around &lt;code&gt;Map&amp;lt;String,Runnable&amp;gt;&lt;/code&gt;, with some magic to produce anonymous inner classes.  This is not any different from what we have today; except possibly that today there is a rough correlation between amount of code written and efficiency of execution.  With BGGA that all changes... it almost becomes easier to write bad code than good code.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Yardena said...&lt;br /&gt;&lt;br /&gt;    Hi,&lt;br /&gt;&lt;br /&gt;    In languages that have closures, they are often used for "delayed evaluation", wrapping a block of code in a closure and passing on to some other object makes the code execute when the other object needs it and not right now. So closure can be used as an event handler, command, etc.&lt;br /&gt;&lt;br /&gt;    Unless I missed something major in your proposal, it does not support such a usage, since you don't support references to closures (I think this is what Remi is implying too).&lt;br /&gt;&lt;br /&gt;    So to get the record straight - you propose something much less powerful than BGGA, and not equivalent to closures in other languages.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;You can still have delayed execution; however the delayed execution must occur within the lifetime of the called method.  This is, as I mentioned, a consequence of how lexical scoping works in Java.  In languages that support "keeping" the closure past its declaration, the lexical scope is either not defined by the stack, or the stack is "forked" so that stack frames can be preserved even after they're out of scope.  Java's stack is linear, and lexical scope is defined by the stack, so if you want closures, you're stuck with that.  Of course BGGA does not have this limitation because BGGA isn't really closures.  It's an abbreviated syntax over anonymous inner classes.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;This all isn't to say that this problem is without solution.  One could propose a JVM change to add support for forked stacks, for example.  But I for one think that interfaces already solve this problem much more idiomatically (and honestly).  Idiomatic because it's done that way today, and there's really nothing seriously wrong with the solution.  Honest because you get what you pay for - you're saying you want to create an object, and that's what the JVM does - unlike BGGA in which you say you want to pass in a closure, and it goes ahead and creates an object anyway.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Ricky Clarkson said...&lt;br /&gt;&lt;br /&gt;    "Basically this translates to Java as two things: A lexically-scoped block of code, and a means to execute that code or pass it on to another method for delayed execution."&lt;br /&gt;&lt;br /&gt;    Your proposal seems not to fit that second part, the delayed execution.&lt;br /&gt;    Suppose we're using a closurific wrapper around SwingUtilities.invokeLater:&lt;br /&gt;&lt;br /&gt;    doLaterClosurely() {&lt;br /&gt;    . . some gui stuff;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    How would your proposal work for this?&lt;br /&gt;&lt;br /&gt;    It would be handy if you suggested what Java 5 code your examples translate to.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Since I've answered the former question already, I'll jump right to the end: There &lt;b&gt;is&lt;/b&gt; no Java 5 translation for my closure proposal.  This is the whole point.  Today the JVM does not have closures; after BGGA, the JVM still would not have closures.  With my proposal, the JVM gets closures - real closures that really close over the actual lexical scope.  This means support on a JVM level.  My proposal simply assumes the minimum amount of change to make this so, which is limited to not adding support for forked stacks (which, by the way, would imply the need to deal with multiple threads accessing a single stack frame).&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Again I need to emphasize that BGGA is moving away from the notion that what you write is what you get.  Much like autoboxing, a mistake we continue to have to live with to this day, BGGA results in objects being automatically created on your behalf without your direct intention to do so.  One end result of this is that brevity of code has a greatly reduced correlation to efficiency of bytecode or efficiency of execution.  This is a mistake in my opinion.  One reason that Java is considered to be so fast now is that the virtual machine maps very cleanly to a real machine, and the Java language maps cleanly to the virtual machine.  So things that are easy to do in Java, by and large, can execute quickly on a real machine.  Programmers who come from a C background, like myself, tend to find that things function and perform "as expected" on a real machine.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;The advent of BGGA represents a departure in correlating language features with JVM capabilities, and thus the language no longer maps cleanly to a real machine.  The natural side-effect of this is that you have to perform a lot of trickery (such as implicitly converting local variables to fields) to make it work.  It is an undeniable fact that field accesses are slower than local variable accesses.  It is an undeniable fact that a direct subroutine invocation (such as what you'd get with the JVM "jsr" instruction) is much faster than a virtual method lookup and invocation.  Programs using BGGA closures are going to appear to be "slower" than programs that don't, because they will use more anonymous inner classes, and they will suffer from the implicit local variable-to-field conversion and virtual method invocation.  I guarantee that this will be the case.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;WarpedJavaGuy said...&lt;br /&gt;&lt;br /&gt;    Why are new language constructs so often perceived as mutilations? Is changing the semantics of existing keywords and constructs not a mutilation?&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;I actually have a fairly simple set of criteria here for Java.  I have no problem with constructs that map to the virtual machine in simple, well-defined ways.  Today, a local variable in Java means a local variable in the JVM.  Even so-called "hacks" such as inner classes have a fairly clean JVM mapping when it comes down to it - they're still classes after all.  Anonymous inner classes push things with their implicit copying of local variables into final fields.  BGGA is over the line.  With BGGA, you could measurably impede the performance of a method body (not to mention completely change 100% of the method bytecode) simply by putting a closure inside of it somewhere which accesses those local variables.  &lt;b&gt;This&lt;/b&gt; is what I call a "mutilation".  You don't get what you pay for when you use BGGA closures.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;All my proposal would require is either a way to define code blocks as an attribute of the calling method, with a way to correlate the lexical scope, or a way to jsr into other methods with parameters (see the "Nuts &amp; Bolts" section of the original posting).  This would make my closures a very simple mapping to JVM bytecode.&lt;br /&gt;&lt;p&gt;&lt;br /&gt;Thanks everyone for your questions - please feel free to send in more.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-1555980646451618939?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/1555980646451618939/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=1555980646451618939' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1555980646451618939'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/1555980646451618939'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/feedback-about-daves-dumb-closures.html' title='Feedback about Dave&apos;s Dumb Closures'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-5979366311763447409</id><published>2008-10-07T10:42:00.002-05:00</published><updated>2008-10-07T10:47:44.163-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><title type='text'>More uses for Dave's Dumb Closures</title><content type='html'>Truly pluggable locking strategies:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public interface Locker {&lt;br /&gt;        void hold() for myBlock();&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public class SynchLocker {&lt;br /&gt;        private final Object lock;&lt;br /&gt;        public SynchLocker(Object lock) { this.lock = lock; }&lt;br /&gt;        public void hold() for myBlock() {&lt;br /&gt;            synchronized (lock) {&lt;br /&gt;                myBlock();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    public class LockLocker {&lt;br /&gt;        private final Lock lock;&lt;br /&gt;        public LockLocker(Lock lock) { this.lock = lock; }&lt;br /&gt;        public void hold() for myBlock() {&lt;br /&gt;            lock.lock();&lt;br /&gt;            try {&lt;br /&gt;                myBlock();&lt;br /&gt;            } finally {&lt;br /&gt;                lock.unlock();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ...later...&lt;br /&gt;    Locker l = ...take your pick...;&lt;br /&gt;    l.hold() {&lt;br /&gt;        ...do stuff...&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Let's see you do that efficiently with anonymous inner classes or BGGA.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-5979366311763447409?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/5979366311763447409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=5979366311763447409' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5979366311763447409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5979366311763447409'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/more-uses-for-daves-dumb-closures.html' title='More uses for Dave&apos;s Dumb Closures'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-3208700276245880274</id><published>2008-10-06T19:46:00.005-05:00</published><updated>2008-10-07T08:50:42.990-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='marshalling'/><category scheme='http://www.blogger.com/atom/ns#' term='river'/><category scheme='http://www.blogger.com/atom/ns#' term='remoting'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>JBoss Marshalling Framework 1.0.0.Beta1 Released</title><content type='html'>As a part of the JBoss Remoting project (and hopefully several other projects as well), I've developed a separated marshalling (a.k.a. serialization) framework.  This framework was inspired by the need for certain features unavailable with the standard &lt;code&gt;Object*Stream&lt;/code&gt; classes:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Pluggable class resolvers, making it easy to customize classloader policy, by implementing a small interface (rather than having to subclass the &lt;code&gt;Object*Stream&lt;/code&gt; classes)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pluggable object replacement (also without subclassing)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pluggable predefined class tables, which can dramatically decrease stream size and serialization time for stream types which frequently use a common set of classes&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pluggable predefined instance tables, which make it easy to handle remote references&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Pluggable externalizers which may be used to serialize classes which are not &lt;code&gt;Serializable&lt;/code&gt;, or for which an alternate strategy is needed&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Customizable stream headers&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Each marshaller instance is highly configurable and tunable to maximize performance based on expected usage patterns&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A generalized API which can support many different protocol implementations, including protocols which do not necessarily provide all the above features&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Inexpensive instance creation, beneficial to applications where many short-lived streams are used&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Support for separate class and instance caches, if the protocol permits; useful for sending multiple messages or requests with a single stream, with separate object graphs but retaining the class cache&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;The default implementation, known as "River", is also available as a separate JAR.&lt;p&gt;This project does not have a home page, but the binaries have been uploaded to &lt;a href="http://repository.jboss.org/jboss/marshalling/1.0.0.Beta1/lib/"&gt;repositry.jboss.org&lt;/a&gt; and the Javadocs are available online at &lt;a href="http://docs.jboss.org/river/1.0.0.Beta1/api/"&gt;docs.jboss.org&lt;/a&gt;.  The source code may be found in &lt;a href="http://anonsvn.jboss.org/repos/sandbox/david.lloyd/jboss-marshalling/trunk/"&gt;my sandbox repository&lt;/a&gt; for now, until it gets a permanent home.&lt;p&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-3208700276245880274?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/3208700276245880274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=3208700276245880274' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/3208700276245880274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/3208700276245880274'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/jboss-marshalling-framework-100beta1.html' title='JBoss Marshalling Framework 1.0.0.Beta1 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-5306206089641478691</id><published>2008-10-01T17:56:00.002-05:00</published><updated>2008-10-01T18:14:14.389-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.1.0.CR1 Released</title><content type='html'>As the title states - 1.1.0.CR1 is available &lt;a href="http://www.jboss.org/xnio/downloads/"&gt;at the XNIO project download page&lt;/a&gt;.  The main list of changes:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Added API support for creating one-way and two-way pipes.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Improved separation of the NIO implementation by moving packages and moving the factory classes to a &lt;code&gt;XnioNio&lt;/code&gt; class.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Add a &lt;code&gt;java.util.concurrent.Future&lt;/code&gt; wrapper for &lt;code&gt;IoFuture&lt;/code&gt; objects.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fix a bug with &lt;code&gt;IoFuture.get()&lt;/code&gt; so that it throws a more specific &lt;code&gt;CancellationException&lt;/code&gt; when an operation is cancelled.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Replace SPI module with a more logical abstraction for provider implementations, including some abstract implementations.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Make &lt;code&gt;IoFuture.await()&lt;/code&gt; parameter order consistent with other standard timed wait methods.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Servers changed to bind to &lt;code&gt;0.0.0.0&lt;/code&gt; by default.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added some handy util classes for dealing with &lt;code&gt;Closeable&lt;/code&gt; resources.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Consolidated the &lt;code&gt;IoFuture.Status&lt;/code&gt; value &lt;code&gt;TIMED_OUT&lt;/code&gt; into &lt;code&gt;WAITING&lt;/code&gt;, since the two are synonymous anyway, which will simplify &lt;code&gt;IoFuture.Notifier&lt;/code&gt; implementation among other things.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added an abstract base class to allow implementation of one-line &lt;code&gt;IoFuture.Notifier&lt;/code&gt; implementations.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-5306206089641478691?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/5306206089641478691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=5306206089641478691' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5306206089641478691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5306206089641478691'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/10/xnio-110cr1-released.html' title='XNIO 1.1.0.CR1 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-6893742512078665333</id><published>2008-09-30T11:23:00.003-05:00</published><updated>2008-09-30T11:37:59.118-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java Language Support for Tail Recursion</title><content type='html'>Everyone wants tail recursion.  I've heard that some JVMs automatically detect tail recursion even.  How about a simple syntax change to do it at a language level?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public int factorial(int number) {&lt;br /&gt;        if (number == 0) {&lt;br /&gt;            return 1;&lt;br /&gt;        } else {&lt;br /&gt;            goto factorial(number, 1);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private int factorial(int current, int sum) {&lt;br /&gt;        if (current == 1) {&lt;br /&gt;            return sum;&lt;br /&gt;        } else {&lt;br /&gt;            goto factorial(current - 1, sum * current);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Long live &lt;code&gt;goto&lt;/code&gt;!  In this example, &lt;code&gt;goto&lt;/code&gt; means "replace the current stack frame with a call to this method", where the given method can be any method whose return value is compatible with, or equivalent to, the calling method's return value.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-6893742512078665333?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/6893742512078665333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=6893742512078665333' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6893742512078665333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6893742512078665333'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/09/java-language-support-for-tail.html' title='Java Language Support for Tail Recursion'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-5499541474179917709</id><published>2008-09-30T02:12:00.009-05:00</published><updated>2008-09-30T11:18:26.946-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='closures'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Dave's Dumb Closures</title><content type='html'>&lt;h4&gt;Or: How to add closures to Java without mutilating the language&lt;/h4&gt;Those of you know have spoken with me via any media for more than about 45 seconds consecutively know that I am vehemently opposed to the various closure implementations for Java that have been proposed for inclusion in to Java 7.  I'm not opposed to closures, mind you - I just really dislike the implementation options that are currently on the table.  At one point I had visualized writing The Final Blog Post On The Subject, which would be so sharp of wit that any possible counterargument simply could not stand in the face of it.  It would be eloquent, noble, and completely irrefutable - even the staunchest BGGA supporter would be won over.&lt;p/&gt;Then reality sets in, and one is reminded that pretty much every such argument against the different closure ideas has been made, and promptly deflected.  So rather than add to that particular category of noise, I thought I'd present a rough outline of a closure implementation that would sit much better with me, in the hopes that there are folks out there who have the same misgivings as I do about the current state of things.&lt;h4&gt;What is a Closure?&lt;/h4&gt;A closure is defined in &lt;a href="http://foldoc.org/?closures"&gt;FOLDOC&lt;/a&gt; as "a data structure that holds an expression and an environment of variable bindings in which that expression is to be evaluated."&lt;p/&gt;Basically this translates to Java as two things: A lexically-scoped block of code, and a means to execute that code or pass it on to another method for delayed execution.&lt;p/&gt;The use cases for these things are numerous.  Other imperative languages have used them for such things as customized control flow structures, continuations, resource management, and so on.  Here in Javaland though, we are left out in the cold - the closest thing we get to these fun toys are anonymous inner classes.  And while anonymous inner classes give the impression of being a sort of limited closure (with the caveat that it can only access local variables that were declared final - they're actually copied to fields transparently), they're obviously not the real deal.&lt;p/&gt;The current leader, BGGA, takes the approach of taking the anonymous inner class notion a few steps farther - local variables aren't just copied to fields, they &lt;b&gt;become&lt;/b&gt; fields (and thus read/write) - along with lots of language glue (magic dynamically-generated types, lots of new syntax and rules, some special annotations) to make it all work sanely.  I'm not going to go into an exhaustive list of What's Wrong With BGGA; rather I'm going to demonstrate a completely different notion of a closure in Java from what you've seen in BGGA and the other competing specs.&lt;h4&gt;A Closure is a Procedure&lt;/h4&gt;My view of a closure in Java is simply an inner method - or more accurately, an inner procedure.  This differs from BGGA (and anonymous inner classes) in a few ways:&lt;ul&gt;&lt;li&gt;Local variables are local variables.  They're all on the stack; the stack is still the regular linear LIFO we're all used to.  This means no surprises with respect to concurrent access or comparatively slow field accesses behind the scenes.&lt;/li&gt;&lt;li&gt;No objects floating out on the heap represent the current lexical scope.  No heap means no GC cost - exiting the calling method instantly cleans up the scope.&lt;/li&gt;&lt;li&gt;Exception handling is greatly simplified - the exception types can be inferred from the inner block.&lt;/li&gt;&lt;li&gt;Closures are (obviously) not inner classes anymore; they cannot be used outside of the lexical scope of the calling method.&lt;/li&gt;&lt;li&gt;The whole function-type interface hierarchy is gone.  This means that calling your closure is no longer a virtual method dispatch.  It becomes a simple pointer dereference.&lt;/li&gt;&lt;/ul&gt;These facts come about because the implementation I describe creates &lt;b&gt;real closures&lt;/b&gt; (not closures emulated with objects) over &lt;b&gt;real lexical scopes&lt;/b&gt; (not lexical scopes that are really collections of fields in a synthetic object class).&lt;p/&gt;Since many people are visual in nature, allow me to demonstrate a possible syntax and usage for these things.&lt;p/&gt;This first example would be a typical ARM (automatic resource management) scenario.  Imagine a Lock interface with a method like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public interface Lock {&lt;br /&gt;        void hold() for theBlock();&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Notice the use of the "for" keyword.  Yeah, I stole that idea from BGGA.  Anyway, here's how you'd implement it:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public class MyLock implements Lock {&lt;br /&gt;        // ...stuff...&lt;br /&gt;        public void hold() for theBlock() {&lt;br /&gt;            ...acquire the lock using ninja CAS techniques...&lt;br /&gt;            try {&lt;br /&gt;                theBlock();&lt;br /&gt;            } finally {&lt;br /&gt;                ...release the lock unconditionally...&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Finally you'd use it like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    private final Lock lock = new MyLock();&lt;br /&gt;&lt;br /&gt;    public void doStuff() throws TheException {&lt;br /&gt;        // we need to access the shared resource!&lt;br /&gt;        lock.hold() for() {&lt;br /&gt;            // ok, let's do some test&lt;br /&gt;            if (someConditionIsWrong) {&lt;br /&gt;                throw new TheException("Failure...");&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or we could ditch the "for" on usage if there's no parameters:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    lock.hold() {&lt;br /&gt;        // do stuff&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Niiiiice.&lt;p/&gt;Now think about this for a moment.  Not only does it &lt;i&gt;look&lt;/i&gt; awesome, but we've removed the virtual method invocations you'd get with BGGA thereby making this potentially super-fast, eliminated an entire &lt;i&gt;category&lt;/i&gt; of new magi-types from the language, and solved the Big Exception Conundrum.&lt;p/&gt;Did I go too fast?  Let me back up and cover those points.&lt;p/&gt;First - it looks awesome, you can't deny it.  No goofy arrows pointing from nothing to whatever, no weird &lt;code&gt;({()})&lt;/code&gt; crap, etc.  It reads easily in declaration, definition, and invocation, and it's not a lot of typing.&lt;p/&gt;Next - consider what this closure structure does for performance.  With one single method invocation, we are locking the resource, executing the user block, and unlocking the resource.  You can't even beat that using try/finally today - at best you've got a method call to lock and a method call to unlock, with your code in between (I'll get into the mechanics of how the call to the block actually occurs down below, for you skeptics out there).&lt;p/&gt;I won't cover the magical auto-created interface types in BGGA - if you know what I'm talking about, well, then you know what I'm talking about.  If not - you don't want to know, believe me.&lt;p/&gt;Finally, the Big Exception Conundrum.  Due to the fact that the closure is really and truly lexically scoped - not fakey-lexical-scoping like anonymous inner classes and their big BGGA brother - all kinds of tricky issues about exception propagation simply disappear.  The complete relevant part of the call stack is statically known at compile-time!  Therefore there's no need to put in special plumbing for the closure to have some fancy dynamic &lt;code&gt;throws&lt;/code&gt; list, or for the method which invokes the closure to have any knowledge or regard for what the closure may throw.  It will throw whatever the closure's parent method can catch or propagate at the point that the closure is defined, just like a regular code block.  And nonlocal returns can be trivially implemented using the same techniques.&lt;h4&gt;Some More Lovely Examples&lt;/h4&gt;The oft-wished-for Map pairs iteration - interface:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    interface Map&amp;lt;K, V&gt; {&lt;br /&gt;        // ...&lt;br /&gt;        void iterate() for block(K key, V value);&lt;br /&gt;        // ...&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Implementation:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public class FooMap&amp;lt;K, V&gt; implements Map&amp;lt;K, V&gt; {&lt;br /&gt;        // ...&lt;br /&gt;        // cheapo implementation just uses good old entrySet()&lt;br /&gt;        public void iterate() for block(K key, V value) {&lt;br /&gt;            Set&amp;lt;Entry&amp;lt;K, V&gt;&gt; entrySet = entrySet();&lt;br /&gt;            for (Entry&amp;lt;K, V&gt; e : entrySet) {&lt;br /&gt;                block(e.getKey(), e.getValue());&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        // ...&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Usage:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    Map&amp;lt;String, Thing&gt; things = new FooMap&amp;lt;String, Thing&gt;();&lt;br /&gt;    // ...later...&lt;br /&gt;    things.iterate() for (String key, Thing value) {&lt;br /&gt;        System.out.println("The string " + key + " is for the thing " + value);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Think how difficult it was for the BGGA crowd to get control structures in there!  And they're still pretty ugly if you ask me (at least in v0.5 of the draft):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    // weird BGGA stuff...&lt;br /&gt;    &amp;lt;R, T extends java.io.Closeable, throws E&gt;&lt;br /&gt;    R with(T t, {T=&gt;R throws E} block) throws E {&lt;br /&gt;        try {&lt;br /&gt;            return block.invoke(t);&lt;br /&gt;        } finally {&lt;br /&gt;            try { t.close(); } catch (IOException ex) {}&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This same safe-close control structure would be done like this (notice how absolutely no type parameters are needed):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    public static void with(Closeable resource) for block() {&lt;br /&gt;        try {&lt;br /&gt;            block();&lt;br /&gt;        } finally {&lt;br /&gt;            try {&lt;br /&gt;                resource.close();&lt;br /&gt;            } catch (Throwable t) {&lt;br /&gt;                // log it, of course!&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then the usage would be:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    InputStream is;&lt;br /&gt;    with (is = new InputStream("foo.txt")) {&lt;br /&gt;        // read me my bytes!&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or how about slick user transaction management (usage only shown):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    txn.begin() {&lt;br /&gt;        // do some JDBC or Hibernate or something!&lt;br /&gt;    }&lt;br /&gt;    // or keep a threadlocal with the context and you could do:&lt;br /&gt;    transaction() {&lt;br /&gt;        // do some JDBC or Hibernate or something!&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Or a nice way to handle streaming result sets from a file or database (usage only shown):&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    data.fetch() for (String lastName, String firstName, BigDecimal balance) {&lt;br /&gt;        // Take a hike, data objects.  These are all local variables!  Talk about cheap GC!&lt;br /&gt;        System.out.println(lastName + ", " + firstName + " owes us $" + balance);&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Privileged actions get a performance boost (no object creation, no virtual method dispatch) - and say goodbye and good riddance to PrivilegedExceptionAction:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    AccessController.doPrivileged() {&lt;br /&gt;        secretStuff.activate();&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;Nuts &amp; Bolts&lt;/h4&gt;The way I describe these closures is based on a few key technical ideas.&lt;ul&gt;&lt;li&gt;The code block, when it executes, &lt;b&gt;maintains a "link" to the outer stack frame&lt;/b&gt;.  This is what allows the outer variables to be accessed.  All local variables continue to live on the stack.&lt;/li&gt;&lt;li&gt;As such, the actual internal value of the closure parameter is either a pair consisting of the parent stack frame address and the code block address, or a pointer to a &lt;b&gt;trampoline&lt;/b&gt; - a small bit of machine code, generated at runtime, which resides on the stack and initializes the child stack frame with said pointer before passing execution to the inner code block.&lt;/li&gt;&lt;li&gt;A code block would probably have to have its own type designation, as a new primitive type (they're like methods, but without a return value and with no exception list).&lt;/li&gt;&lt;li&gt;I assume that all returns are nonlocal, though it is not required by this design.  Nonlocal returns still pass through all the &lt;code&gt;finally&lt;/code&gt; blocks that would be on the call stack.&lt;/li&gt;&lt;li&gt;A code block may implicitly throw any checked exception that is catchable at the point that the method (the one which accepts the closure) is implemented.  This includes, of course, any checked exceptions declared on the (closure-accepting) method itself.&lt;/li&gt;&lt;li&gt;Variables may not be declared as a closure type.  This helps keep the magic smoke inside the computer.&lt;/li&gt;&lt;li&gt;Closures only live for the duration of their lexical scope.  Their REAL lexical scope, not a pretend scope that's really an object.&lt;/li&gt;&lt;li&gt;In fact, the implementation may not consist of an object to substitute for a lexical scope.  Violators will get scowled at, and possibly called rude names.&lt;/li&gt;&lt;li&gt;No fancy parser acrobatics are needed - only the &lt;code&gt;for&lt;/code&gt; epilogue to method declarations and the method-call postfix parameters and code block are needed.  No additional operators are introduced.&lt;/li&gt;&lt;li&gt;The bytecode file format would be enhanced to include attribute sections for code blocks; these need only be indexed by number.&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Other Ideas Based On Real Closures&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;Inner methods!  For all those pesky private/private-static methods you have that only ever get called from one method.  Inner methods can be referenced directly without looking them up by name, since they cannot be accessed outside of their lexical scope (not even through reflection).&lt;/li&gt;&lt;li&gt;Very cheap threadlocal storage.  The lexical scope is guaranteed to be locked to a single thread's stack.  This could be taken advantage of... somehow.&lt;/li&gt;&lt;/ul&gt;What other weird and wonderful stuff can you think of?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-5499541474179917709?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/5499541474179917709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=5499541474179917709' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5499541474179917709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5499541474179917709'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/09/daves-dumb-closures.html' title='Dave&apos;s Dumb Closures'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-7453549791459437041</id><published>2008-07-28T22:22:00.005-05:00</published><updated>2009-03-03T14:43:25.499-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Proper resource management</title><content type='html'>One of the most common problems that I see users having on the ##java IRC channel is improper resource management.  By "resource management", I mean "things that need cleaning up after", such as streams, files, sockets, JDBC statements, etc.  The tendency is not so much to ignore the problem, but to use an improper, unsafe, or just unnecessarily complex or ugly approach to solving it.&lt;br /&gt;&lt;br /&gt;The problem is basically this.  Suppose you open one or more resources, and some intermediate operation the middle of the code block fails.  An exception is thrown, and without proper resource management, none of your files/sockets/database statements end up getting closed.  This causes the reference to hang around until at least the next GC cycle, which can cause secondary problems like file descriptor exhaustion that are tough to diagnose.&lt;br /&gt;&lt;br /&gt;To solve this problem, you don't need fancy closures or automatic resource management blocks.  Java has a simple, rock-solid way to completely avoid this issue already built into the language: finally blocks.  Proper usage of this mechanism can produce code that is very safe and just as readable and elegant as the more recent "trendy" language proposals.&lt;br /&gt;&lt;br /&gt;Consider this (incorrect) example which reads a couple lines from a file:&lt;pre class="code"&gt;// Example of INCORRECT code - DO NOT do this&lt;br /&gt;try {&lt;br /&gt;    InputStream is = new FileInputStream("file.txt");&lt;br /&gt;    Reader r = new InputStreamReader(is);&lt;br /&gt;    BufferedReader br = new BufferedReader(r);&lt;br /&gt;    System.out.println("The first line is " + br.readLine());&lt;br /&gt;    System.out.println("The second line is " + br.readLine());&lt;br /&gt;    br.close();&lt;br /&gt;    r.close();&lt;br /&gt;    is.close();&lt;br /&gt;} catch (IOException ex) {&lt;br /&gt;    // it failed :(&lt;br /&gt;    ex.printStackTrace();&lt;br /&gt;}&lt;/pre&gt;It works perfectly as long as nothing fails.  Of course if anything at all throws an exception in that block, then you may leak one or more resources (since the &lt;code&gt;close()&lt;/code&gt; methods may not all be reached).  There are many naive solutions to the problem, like this one that illustrates a couple different common errors:&lt;pre class="code"&gt;// INCORRECT solution - DO NOT do this&lt;br /&gt;InputStream is = null;&lt;br /&gt;Reader r = null;&lt;br /&gt;BufferedReader br = null;&lt;br /&gt;try {&lt;br /&gt;    is = new FileInputStream("file.txt");&lt;br /&gt;    r = new InputStreamReader(is);&lt;br /&gt;    br = new BufferedReader(r);&lt;br /&gt;    System.out.println("The first line is " + br.readLine());&lt;br /&gt;    System.out.println("The second line is " + br.readLine());&lt;br /&gt;} finally {&lt;br /&gt;    is.close();&lt;br /&gt;    r.close();&lt;br /&gt;    br.close();&lt;br /&gt;}&lt;/pre&gt;The first problem is simply that the values of &lt;code&gt;is&lt;/code&gt;, &lt;code&gt;r&lt;/code&gt;, and &lt;code&gt;br&lt;/code&gt; are not checked for &lt;code&gt;null&lt;/code&gt;.  The solution here could simply be to check for &lt;code&gt;null&lt;/code&gt; before calling &lt;code&gt;close&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The second problem is that any of those three &lt;code&gt;close&lt;/code&gt; statements can also throw an exception; this causes two additional problems: throwing an exception from a finally block will obscure any earlier exception, and if an earlier &lt;code&gt;close&lt;/code&gt; fails, the later one will never be called.  Solve this one by giving each &lt;code&gt;close&lt;/code&gt; its own little &lt;code&gt;try/catch&lt;/code&gt; block.&lt;br /&gt;&lt;br /&gt;And the third (and maybe most subtle) problem is that even if you solved the prior two issues you miss one important thing.  With many resources, you cannot consider an operation to be a success unless the &lt;code&gt;close&lt;/code&gt; is also successful.  And in general it is a good idea to always assume this is the case, and take advantage of the idempotency of the &lt;code&gt;close&lt;/code&gt; operation (in other words, you can safely call it more than once without any additional effects beyond the first call).  The solution here is to put a call to &lt;code&gt;close&lt;/code&gt; for each resource inside the &lt;code&gt;try&lt;/code&gt; block as well, so that exceptions are propagated but resources are also cleaned up.&lt;br /&gt;&lt;br /&gt;So implementing these suggestions might leave us with something like this monstrosity:&lt;pre class="code"&gt;// Safe but very ugly example - I recommend against it&lt;br /&gt;InputStream is = null;&lt;br /&gt;Reader r = null;&lt;br /&gt;BufferedReader br = null;&lt;br /&gt;try {&lt;br /&gt;    is = new FileInputStream("file.txt");&lt;br /&gt;    r = new InputStreamReader(is);&lt;br /&gt;    br = new BufferedReader(r);&lt;br /&gt;    System.out.println("The first line is " + br.readLine());&lt;br /&gt;    System.out.println("The second line is " + br.readLine());&lt;br /&gt;    br.close();&lt;br /&gt;    r.close();&lt;br /&gt;    is.close();&lt;br /&gt;} catch (IOException e) {&lt;br /&gt;    e.printStackTrace();&lt;br /&gt;} finally {&lt;br /&gt;    if (is != null) try {&lt;br /&gt;        is.close();&lt;br /&gt;    } catch (IOException e) {&lt;br /&gt;        e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt;    if (r != null) try {&lt;br /&gt;        r.close();&lt;br /&gt;    } catch (IOException e) {&lt;br /&gt;        e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt;    if (br != null) try {&lt;br /&gt;        br.close();&lt;br /&gt;    } catch (IOException e) {&lt;br /&gt;        e.printStackTrace();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;That's 30 lines of code to read and print two lines from a file - yuck!  There is in fact a more elegant way to solve this problem.  The first step is to restructure the code with separate &lt;code&gt;try/finally&lt;/code&gt; blocks for each resource:&lt;pre class="code"&gt;// Safe, but really just as ugly...&lt;br /&gt;try {&lt;br /&gt;    final InputStream is = new FileInputStream("file.txt");&lt;br /&gt;    try {&lt;br /&gt;        final Reader r = new InputStreamReader(is);&lt;br /&gt;        try {&lt;br /&gt;            final BufferedReader br = new BufferedReader(r);&lt;br /&gt;            try {&lt;br /&gt;                System.out.println("The first line is " + br.readLine());&lt;br /&gt;                System.out.println("The second line is " + br.readLine());&lt;br /&gt;                br.close();&lt;br /&gt;                r.close();&lt;br /&gt;                is.close();&lt;br /&gt;            } finally {&lt;br /&gt;                try {&lt;br /&gt;                    br.close();&lt;br /&gt;                } catch (IOException e) {&lt;br /&gt;                    e.printStackTrace();&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        } finally {&lt;br /&gt;            try {&lt;br /&gt;                r.close();&lt;br /&gt;            } catch (IOException e) {&lt;br /&gt;                e.printStackTrace();&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    } finally {&lt;br /&gt;        try {&lt;br /&gt;            is.close();&lt;br /&gt;        } catch (IOException e) {&lt;br /&gt;            e.printStackTrace();&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;} catch (IOException e) {&lt;br /&gt;    // failure&lt;br /&gt;    e.printStackTrace();&lt;br /&gt;}&lt;/pre&gt;Notice two things - first, I've switched to &lt;code&gt;final&lt;/code&gt; variables to hold the resource.  This really underlines the point that we do not need a &lt;code&gt;null&lt;/code&gt; check anymore for each resource.  That's one problem solved.  Second, there's more of a structure to the resource management that emphasizes their lexical scoping.  But look how huge it is - we're actually doing worse by about 7 lines!&lt;br /&gt;&lt;br /&gt;The final enhancement is the addition of a static method to safely clean up a resource.  It looks like this:&lt;pre class="code"&gt;// put this anywhere you like in your common code.&lt;br /&gt;public static void safeClose(Closeable c) {&lt;br /&gt;    try {&lt;br /&gt;        c.close();&lt;br /&gt;    } catch (Throwable t) {&lt;br /&gt;        // Resource close failed!  There's only one thing we can do:&lt;br /&gt;        // Log the exception using your favorite logging framework&lt;br /&gt;        t.printStackTrace();&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Now our code can be changed to look like this:&lt;pre class="code"&gt;// Now this is more like it - readable and foolproof!&lt;br /&gt;try {&lt;br /&gt;    final InputStream is = new FileInputStream("file.txt");&lt;br /&gt;    try {&lt;br /&gt;        final Reader r = new InputStreamReader(is);&lt;br /&gt;        try {&lt;br /&gt;            final BufferedReader br = new BufferedReader(r);&lt;br /&gt;            try {&lt;br /&gt;                System.out.println("The first line is " + br.readLine());&lt;br /&gt;                System.out.println("The second line is " + br.readLine());&lt;br /&gt;                br.close();&lt;br /&gt;                r.close();&lt;br /&gt;                is.close();&lt;br /&gt;            } finally {&lt;br /&gt;                safeClose(br);&lt;br /&gt;            }&lt;br /&gt;        } finally {&lt;br /&gt;            safeClose(r);&lt;br /&gt;        }&lt;br /&gt;    } finally {&lt;br /&gt;        safeClose(is);&lt;br /&gt;    }&lt;br /&gt;} catch (IOException e) {&lt;br /&gt;    // failure&lt;br /&gt;    e.printStackTrace();&lt;br /&gt;}&lt;/pre&gt;All of the original problems are solved, and in addition it is a lot easier to see what is going on in terms of resource cleanup.  This is by no means the only solution to the problem, and certainly not the shortest, but I believe it is the cleanest and safest (in terms of human error).&lt;br /&gt;&lt;br /&gt;The same kind of thing can be applied to JDBC handles (just write a &lt;code&gt;safeClose()&lt;/code&gt; method for connections and statements) or just about anything else that needs cleaning up after.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-7453549791459437041?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/7453549791459437041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=7453549791459437041' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7453549791459437041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7453549791459437041'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/07/proper-resource-management.html' title='Proper resource management'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-4612647705814574223</id><published>2008-07-21T20:29:00.003-05:00</published><updated>2008-07-21T20:39:55.250-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.0.0.GA Released</title><content type='html'>The first GA release of XNIO is now available.  There is only one substantial fix in this release.  The standalone API did not present a way to close ChannelSource and Connector instances that were created via an Xnio instance.  This has been fixed, and I think the wait has been long enough.&lt;br /&gt;&lt;br /&gt;Find the release at the &lt;a href="http://www.jboss.org/xnio/downloads/"&gt;downloads page&lt;/a&gt; of the &lt;a href="http://www.jboss.org/xnio/"&gt;XNIO project website&lt;/a&gt;.  Also check out the &lt;a href="http://docs.jboss.org/xnio/1.0/api/index.html"&gt;online documentation&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-4612647705814574223?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/4612647705814574223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=4612647705814574223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4612647705814574223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/4612647705814574223'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/07/xnio-100ga-released.html' title='XNIO 1.0.0.GA Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-590309094434371504</id><published>2008-07-07T19:50:00.005-05:00</published><updated>2008-07-21T22:05:17.133-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.0.0.CR3 Released</title><content type='html'>Well, I lied.  I've found a couple more minor API issues which I've fixed for CR3 - a misspelling in a method name ("interruptible", not "interruptable"), a typo which prevented junit from being downloaded, one interface rename ("Client" becomes "ChannelSource"), and a few other minor fixes are included in this release.  I think this one will become GA unless I find a glaring bug in the next week or so.&lt;br /&gt;&lt;br /&gt;Once again, the release is available at the &lt;a href="http://www.jboss.org/xnio/downloads/"&gt;downloads page&lt;/a&gt; of the &lt;a href="http://www.jboss.org/xnio/"&gt;XNIO project website&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Release Notes - XNIO - Version 1.0.0.CR3&lt;br /&gt;&lt;h2&gt;Bug&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-27"&gt;XNIO-27&lt;/a&gt;] - "Interruptibly" is misspelled&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-28"&gt;XNIO-28&lt;/a&gt;] - Streams classes do not belong in XNIO&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-30"&gt;XNIO-30&lt;/a&gt;] - Build fails due to incorrect license name for junit&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-31"&gt;XNIO-31&lt;/a&gt;] - Logging methods might throw exceptions&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Task&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-14"&gt;XNIO-14&lt;/a&gt;] - Use a service locator pattern to locate XNIO providers in the standalone API&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-29"&gt;XNIO-29&lt;/a&gt;] - Rename org.jboss.xnio.Client to "ChannelSource"&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-590309094434371504?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/590309094434371504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=590309094434371504' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/590309094434371504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/590309094434371504'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/07/xnio-100cr3-released.html' title='XNIO 1.0.0.CR3 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-6472765329370914891</id><published>2008-06-30T18:30:00.008-05:00</published><updated>2008-06-30T19:07:04.352-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>A modified approach to asynchronous reads</title><content type='html'>In a &lt;a href="http://dmlloyd.blogspot.com/2008/05/aio-versus-network-servers.html"&gt;previous post&lt;/a&gt;, I talked about the impracticality of asynchronous reads in a scalable server situation.  The problem I cited was that if there are large amounts of pending reads, each with its own preallocated buffer, a large quantity of resources can possibly be consumed, thus impeding scalability.&lt;br /&gt;&lt;br /&gt;I've been thinking about the problem some more and I've come up with an alternate approach.  Basically, the solution to the problem is to simply not allocate a buffer until the read takes place.  This is made pretty simple by use of the &lt;a href="http://docs.jboss.org/xnio/1.0/api/org/jboss/xnio/BufferAllocator.html"&gt;&lt;code&gt;BufferAllocator&lt;/code&gt; interface&lt;/a&gt; in &lt;a href="http://www.jboss.org/xnio/"&gt;XNIO&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Using this interface, the signature of the asynchronous read method would look like this:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;IoFuture&amp;lt;ByteBuffer&gt; asyncRead(BufferAllocator&amp;lt;ByteBuffer&gt; allocator) throws IOException;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The buffer is allocated only when the channel is readable.  And if an NIO.2-style (or similar) async read is used "under the covers" for whatever reason, then the allocation can simply happen right upfront.&lt;br /&gt;&lt;br /&gt;Look for this feature in XNIO 1.1!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-6472765329370914891?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/6472765329370914891/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=6472765329370914891' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6472765329370914891'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6472765329370914891'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/06/modified-approach-to-asynchronous-reads.html' title='A modified approach to asynchronous reads'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-811491562689292023</id><published>2008-06-23T19:55:00.009-05:00</published><updated>2008-07-21T22:07:12.230-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.0.0.CR2 Released</title><content type='html'>&lt;p&gt;This new version fixes several problems in CR1 and is closer to a final product now.  I do not anticipate any further API changes, so this version is safe to develop against in anticipation for the final GA release (which I have marked for July 28 - not too far in the future, but hopefully far enough that any remaining bugs will be found and flushed out).&lt;/p&gt;&lt;p&gt;For those new to XNIO, it is a replacement for NIO that vastly simplifies the handling of non-blocking I/O.  To quote my tag line from last time: XNIO gives you the full power of NIO channels while eliminating the headache of thread and Selector management.&lt;/p&gt;&lt;p&gt;The release is available at the &lt;a href="http://www.jboss.org/xnio/downloads/"&gt;downloads page of the XNIO project&lt;/a&gt;.&lt;/p&gt;Release Notes - XNIO - Version 1.0.0.CR2&lt;h2&gt;Bug&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-20"&gt;XNIO-20&lt;/a&gt;] - Channel options support is incomplete&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-22"&gt;XNIO-22&lt;/a&gt;] - No way to shut down server connections&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-23"&gt;XNIO-23&lt;/a&gt;] - An exception in handleOpened should always close the connection&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-25"&gt;XNIO-25&lt;/a&gt;] - Standalone API isn't locking properly&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Feature Request&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-21"&gt;XNIO-21&lt;/a&gt;] - Samples directory with a few simple examples&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;Task&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-18"&gt;XNIO-18&lt;/a&gt;] - License files and file headers&lt;/li&gt;&lt;li&gt;[&lt;a href="http://jira.jboss.com/jira/browse/XNIO-26"&gt;XNIO-26&lt;/a&gt;] - Options should be changed to typesafe constants&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-811491562689292023?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/811491562689292023/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=811491562689292023' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/811491562689292023'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/811491562689292023'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/06/xnio-100cr2-released.html' title='XNIO 1.0.0.CR2 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-7063620376416256581</id><published>2008-06-11T12:10:00.002-05:00</published><updated>2008-06-11T12:15:34.668-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>XNIO 1.0.0.CR1 Released</title><content type='html'>I've released XNIO 1.0.0.CR1.  XNIO is a replacement for NIO that vastly simplifies the handling of non-blocking I/O.  XNIO gives you the full power of NIO channels while eliminating the headache of thread and Selector management.  Also, it is dramatically simpler to implement an XNIO provider than it is to implement an NIO provider - opening the door to APR or other native implementations as well as non-network transport types such as serial ports, and platform-specific types like UNIX domain sockets.&lt;br /&gt;&lt;br /&gt;The release is available from the &lt;a href="http://www.jboss.org/xnio/"&gt;XNIO project page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-7063620376416256581?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/7063620376416256581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=7063620376416256581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7063620376416256581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/7063620376416256581'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/06/xnio-100cr1-released.html' title='XNIO 1.0.0.CR1 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-3393525160056268895</id><published>2008-05-22T20:58:00.005-05:00</published><updated>2008-05-22T21:13:00.166-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>A Closer Look at JSR-308</title><content type='html'>If you haven't heard of JSR-308, take a few minutes to &lt;a href="http://groups.csail.mit.edu/pag/jsr308/java-annotation-design.html"&gt;read the specification&lt;/a&gt; and familiarize yourself with it.  This JSR is designed "permit annotations to appear in more places than Java 6 permits".&lt;br /&gt;&lt;br /&gt;A number of blogs have popped up with negative reactions to this JSR, like &lt;a href="http://www.michaelnygard.com/blog/2008/05/when_should_you_jump_jsr_308_t.html"&gt;this one&lt;/a&gt; and &lt;a href="http://bc-squared.blogspot.com/2008/05/what-hath-java-wrought.html"&gt;this one&lt;/a&gt;, recently &lt;a href="http://www.theserverside.com/blogs/thread.tss?thread_id=49416"&gt;featured on TSS&lt;/a&gt;.  While I agree with the given opinions in many ways, it is unfortunate that there is not a great deal of technical depth or logical reasoning given in these posts (mostly it's statements to the effect of "makes Java too complex"), so I'd like to take this opportunity to explain in detail exactly why this JSR, as it stands right now, is bad for Java and its community, by citing specific examples.&lt;br /&gt;&lt;br /&gt;I think the best place to start is to look at &lt;a href="http://groups.csail.mit.edu/pag/jsr308/java-annotation-design.html#htoc16"&gt;section B.2 of the working draft&lt;/a&gt; of JSR-308, which is the section that outlines the proposed uses for annotations on types.  The justification for any change to Java (or to any language really) should be rooted in a valid use case, and many use cases are given in this section.  Here's why few, if any, of the given use cases are valid justification for the changes outlined in this JSR.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Generics and arrays&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;There are multiple use cases given for applying type annotations to arrays and generic collections.  Here's the very first one given:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The Titanium ... dialect of Java requires the ability to place the local annotation (indicating that a memory reference in a parallel system refers to data on the same processor) on various levels of an array, not just at the top level.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Fine, fine.  Titanium sounds lovely.  But, we're talking about Java here.  You are implying that there is a need for such an annotation within Java itself.  But how would Java ever be able to effectively make use of such an annotation, without substantial changes to the compiler and/or VM?  Java solves concurrent problems quite well as it stands right now, especially since the introduction of the "java.util.concurrent" package in JDK5, and there is a very active sub-community, populated with some very smart people, focused around further improving concurrency in Java by expanding upon the proven model that exists now.&lt;br /&gt;&lt;br /&gt;It's fine to explore other concurrency models, but in my opinion it would be a disservice to the Java community to do this in Java itself.  How about providing a special-purpose language on top of the JVM for this?  I've heard good things about Scala, for example.&lt;br /&gt;&lt;br /&gt;There is &lt;b&gt;no&lt;/b&gt; need or justification to re-solve a problem that has already been solved in a way that has been proven to be very effective.  Therefore I believe this use case to be wholly invalid.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;In a dependent type system [...], one wishes to specify the dimensions of an array type, such as Object[@Length(3)][@Length(10)] for a 3×10 array.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Java does not have a dependent type system as described here.  So... how is this a valid use case?  Are you proposing that Java's type system be changed?  Are you sure you want to open that can of worms?  What problem are you trying to solve here?  The traditional way to enforce strict bounds on an array as proposed here is to wrap the array manipulation operations in a class.  Compared to using annotations, using a wrapper class is potentially much easier to read, and I for one would certainly rather explain arrays as they exist today, rather than explain arrays plus all the annotations you can stick to them, and what they mean, to a clueless newbie.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;An immutability type system [...] needs to be able to specify which levels of an array may be modified. Consider specifying a procedure that inverts a matrix in place.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;See my previous point, because it applies equally well here.  An array is not a matrix.  I know lots of traditional computer scientists would love it if they were, but they simply are not - if you want a matrix, make a Matrix class and enforce your policy there.  This is a solution that has served us well until now; there is no reason to reinvent this, especially at this late stage.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;An ownership domain system [...] uses array annotations to indicate properties of array parameters, similarly to type parameters.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I took a few minutes and read through the paper referenced by this point, and I found that they demonstrate an implementation that is compatible with Java 5 annotations as they stand.  The section (6.2) in which they expound upon the limitations of Java 5 annotations that they ran into, does not seem to mention any deficiencies that are solved by this JSR.  So this one is a bit of a question mark for me.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;The ability to specify the nullness of the array and its elements separately is so important that JML [...] includes special syntax \nonnullelements(a) for an array a with non-null elements.&lt;br /&gt;&lt;br /&gt;In a type system for preventing null pointer errors, using a default of non-null, and explicitly annotating references that may be null, results in the fewest annotations and least user burden [...]. Array elements can often be null (both due to initialization, and for other reasons), necessitating annotations on them.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This is referring to &lt;a href="http://www.cs.ucf.edu/~leavens/JML/"&gt;JML&lt;/a&gt; and the principle of design by contract.  And many will agree (myself included) that it is an interesting idea - you statically define your contract in great detail along side your method declarations or definitions, and users of that interface can perform extensive validation to verify that they conform to that contract at compile time.&lt;br /&gt;&lt;br /&gt;But: does DBC belong in Java itself?  In my opinion, no: it represents a fundamental change to the way that APIs are specified in Java.  If JML-style constraints were introduced in to Java itself, you'd be taking away the language we know as Java, and replacing it with a new language.  While I'm not against design by contract by any stretch of the imagination, I think that a DBC-based language is best implemented as a new language altogether.&lt;br /&gt;&lt;br /&gt;That said, the specific use case given by these two points - a null and/or non-null annotation - is something that can be quite useful, and in fact can be comprehensively implemented using the annotation system that has existed since JDK5.  In fact I'd love to see it - but the (major) caveat is that in order to be truly useful, pretty much the entire JDK would have to be retroactively annotated.  There is a bit more to be said about this type of annotation in a moment.&lt;br /&gt;&lt;br /&gt;I do NOT believe that it is worthwhile to extend this type of annotation to arrays.  Arrays have always been and will always be a special case in Java.  In my opinion, the rules for arrays are weird/different enough from a "regular" object that they're best left as is - they solve a relatively narrow problem domain quite well enough.  Expanding the scope of arrays introduces more risk and/or complexity than benefit (again, my opinion).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Receivers&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;This is a weird one.  The basic premise is that on a (non-static) method, in addition to your regular method parameters, you should be able to put an annotation on "this", because it's kinda-sorta a formal parameter.  Sorta.&lt;br /&gt;&lt;br /&gt;The problem is that no, it's not a formal parameter at all.  You can't, for example, modify the actual "this" reference in your method.  In fact the one single example that is given is a "@Readonly" annotation that applies to the method receiver, which means that the given method doesn't modify its receiver.  This is of course ludicrous, because you can't modify "this".  You can certainly dereference it, which is I guess (?) what they're getting at.  However there is no reason why this is cannot a method-level annotation which basically means "this method does not mutate the object state".&lt;br /&gt;&lt;br /&gt;By the way, on more than one occasion, the JSR implies that annotations on a method are associated with the method's return value.  While true in some cases, this is absolutely untrue in general.  Many, many annotation-based tools and frameworks use method-level annotations to indicate the method itself.  And very seldom (in fact, never in my experience) is there confusion about whether an annotation applies to the method or the method's return value.&lt;br /&gt;&lt;br /&gt;So I don't consider this use case valid at all.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Casts&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;This section, especially in combination with the null/not-null example, very much demonstrates a couple of key issues I have with this JSR.&lt;br /&gt;&lt;br /&gt;The thing that really gets me about the whole nullability example is that this is a concept that does not even apply to types.  Nope, not even a little.  Nullability is relevant to &lt;b&gt;variables&lt;/b&gt; (local variables, fields, parameters) and &lt;b&gt;values&lt;/b&gt; (null is obviously always null; constants and many other types of expressions, like object construction, are safe to call non-null); but not types.  It is a constraint on the value space of a variable which is completely orthogonal to the type system.&lt;br /&gt;&lt;br /&gt;Let me give you an example.  Pretend that we've got an annotation called "@NotNull", which can be applied to local variables, fields, methods (referring to the return value of the method), and method parameters.  This is a horribly contrived snippet of a method that uses the hypothetical "@NotNull" annotation in various ways:&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;  ...&lt;br /&gt;  Object bar = somePlainOldMethod();&lt;br /&gt;  // Permissible because the JVM can prove that foo is not null&lt;br /&gt;  @NotNull Object foo = new Object();&lt;br /&gt;  // At this point, foo (the variable) may NOT contain null&lt;br /&gt;  // So, this would be a compile-time error&lt;br /&gt;  foo = null;&lt;br /&gt;  // As would this (bar might be null)&lt;br /&gt;  foo = bar;&lt;br /&gt;  // Now it gets interesting:&lt;br /&gt;  if (bar != null) {&lt;br /&gt;      // Hmm, the compiler can easily prove that bar cannot be null here!&lt;br /&gt;      // That makes this line a-ok - and without a big dumb (@NonNull Object) cast!&lt;br /&gt;      foo = bar;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice the inference in the "if" statement.  Wouldn't it be nice if Java were always that smart?  Do you see now how the nullness of a variable has no relation to its type?  The variable "bar" was nullable, then provably non-null, then nullable again.  The JSR adds this kind of inference as merely an optional footnote, preferring that you use the cast syntax instead.&lt;br /&gt;&lt;br /&gt;Oh, and note that all this can be done with annotations as they exist today.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Type tests&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;OK, this one is even stranger.  The idea is that an "instanceof" test becomes dual purpose.  On the one hand, it's a runtime check of variable type.  But it also becomes a compile-time annoyance generation mechanism.  How so?  It basically adds a useless constraint - you must specify all your local variable annotations in your "instanceof", or get a compile error.  If you do so, you're rewarded with - wait for it - &lt;b&gt;zero&lt;/b&gt; additional functionality; you're right where you started.&lt;br /&gt;&lt;br /&gt;Plus, this opens the door to newbie programming errors like this (quoted directly from the actual working draft):&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;if (x instanceof @A1 T) { ... }&lt;br /&gt;else if (x instanceof @A2 T) { ... }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Think about what that means.  The second "if" is never true, because the annotation is evaluated at compile-time, while the "instanceof" is evaluated at runtime!&lt;br /&gt;&lt;br /&gt;This change is not only useless and annoying, but it seems to bear little or no relationship to the other proposed use cases.  It's a solution looking for a problem.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;br /&gt;&lt;br /&gt;There are a few other smaller sections but there are really no other concrete examples worth commenting additionally on, so I'll leave the rest as an exercise for the reader.&lt;br /&gt;&lt;br /&gt;This is how I see it.  This JSR will add a much higher level of complexity to a language that has already greatly increased in complexity in the past few years.  You are changing a language that many people use to a language that, in my opinion, many fewer people will use, because of the increased learning curve and large increase in complexity for what I see as very minimal gain.  Many (including myself) feel that this JSR is crossing a threshold, beyond the so-called point of diminishing returns.&lt;br /&gt;&lt;br /&gt;Many of the problems which this JSR intends to solve are important and relevant to those who have identified them.  But you can't (and shouldn't) solve every problem in Java, and it is my belief that you will find that most of the problems which this JSR was introduced to solve are not important to most Java users.&lt;br /&gt;&lt;br /&gt;One of Java's strengths is that it is a language that compiles to a portable bytecode.  How about taking some of these ideas and applying them to new languages that target the JVM?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-3393525160056268895?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/3393525160056268895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=3393525160056268895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/3393525160056268895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/3393525160056268895'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/05/closer-look-at-jsr-308.html' title='A Closer Look at JSR-308'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-5828476773524142600</id><published>2008-05-22T15:38:00.004-05:00</published><updated>2008-06-04T10:58:41.191-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='i/o'/><title type='text'>AIO versus network servers</title><content type='html'>For those who aren't aware, the AIO read idiom works something like this pseudocode:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;buffer = allocate_buffer();&lt;br /&gt;future = aio_channel.read(buffer); // read takes place in the background; this call does not block&lt;br /&gt;future.set_completion_handler(handler);&lt;br /&gt;return;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And later on in handler:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;void handler(Buffer buffer) {&lt;br /&gt; ... decode the received buffer ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Why is this not right for high-connection-count network servers?  Imagine your buffer size is 1K.  Imagine you've got 10k concurrent connections.  You need a buffer to be allocated before you can kick off an async read.  That's an initial 10 megabytes in idle buffers, not to mention a *minimum* of 10k buffer allocations - even if the connection is never used or the channel never becomes readable.&lt;br /&gt;&lt;br /&gt;This problem is similar to &lt;a href="http://weblogs.java.net/blog/jfarcand/archive/2006/06/tricks_and_tips.html"&gt;the problem that Jean-Francois Arcand is referring to&lt;/a&gt; in his NIO Tips &amp;amp; Tricks blog.&lt;br /&gt;&lt;br /&gt;For this reason, I still believe that multiplexing/testing for readiness is still the best approach in terms of scalability.  And multiplexing for socket channels obviates the need for AIO: if a channel is readable, then a read() will by definition not block (the data is already in the receive buffer).  Therefore AIO is not useful for waiting for a socket to become ready for reading.&lt;br /&gt;&lt;br /&gt;Writing is a different story.  When you want to write to a socket channel, to minimize latency generally your write data is assembled in a buffer, and then write is invoked.  In the worst case, with regular non-blocking IO, the write returns a 0 (in POSIX-ish C it would be an EAGAIN result) indicating that the write would have blocked (that is, the kernel write buffer has no space available, so no data can be sent right now).  With non-blocking I/O, what you do at this point is register for writable events, and your handler gets notified when the channel is writable.  At this stage you retry your write.&lt;br /&gt;&lt;br /&gt;Note that even now, your entire buffer might not be written, especially if you're using a stream socket type such as TCP.  The reason is that your buffer might still be larger than the kernel's send buffer.  So in this case, you reregister your handler to be notified on writes again, repeating until your entire buffer was sent.&lt;br /&gt;&lt;br /&gt;This is a lot of boilerplate for something that's fairly common.  In this case, it's far easier to assemble your buffer, kick off an async write, and call it a day.  You'll get a notification when your write is complete, without monkeying around with registering and re-registering your handler.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-5828476773524142600?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/5828476773524142600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=5828476773524142600' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5828476773524142600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/5828476773524142600'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/05/aio-versus-network-servers.html' title='AIO versus network servers'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-2988993806636489115</id><published>2008-04-21T11:44:00.000-05:00</published><updated>2008-04-21T12:01:48.046-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jsr-310'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Date and Time in Java 5 &amp; 6</title><content type='html'>For those of you who aren't aware, &lt;a href="https://jsr-310.dev.java.net/"&gt;JSR-310&lt;/a&gt; is devoted to developing a (much-needed) new and improved replacement date and time API for Java.  Since the spec lead, Stephen Colebourne (who is the author of the excellent &lt;a href="http://joda-time.sourceforge.net/index.html"&gt;JODA date and time library&lt;/a&gt;), has made the wise decision to make the process public for the JSR, you can read (and join) the discussions taking place around this effort.&lt;br /&gt;&lt;br /&gt;One &lt;a href="https://jsr-310.dev.java.net/servlets/BrowseList?listName=dev&amp;amp;by=thread&amp;amp;from=1117076&amp;amp;to=1117076&amp;amp;first=1&amp;amp;count=6"&gt;discussion I'd like to highlight&lt;/a&gt; is a bit of talk over the last few days regarding the final package in which the date and time API will finally reside.  Currently the API is set to end up in the "javax.date" package.  This should allow us (from a legal perspective) to be able to provide the date and time implementation as a standalone library.  Great news for folks who, for whatever reason, are not going to be able to upgrade to Java 7 (which is the target for this JSR) the day it comes out.  This would allow that (sizeable) population to use the new API in their existing systems.&lt;br /&gt;&lt;br /&gt;Also, have a look at the &lt;a href="https://jsr-310.dev.java.net/nonav/doc-2008-04-20/index.html"&gt;latest API javadoc&lt;/a&gt; for a taste of what the API looks like currently.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-2988993806636489115?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/2988993806636489115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=2988993806636489115' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2988993806636489115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/2988993806636489115'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/04/date-and-time-in-java-5-6.html' title='Date and Time in Java 5 &amp; 6'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1214048633682585732.post-6083406883175468631</id><published>2008-04-21T10:04:00.000-05:00</published><updated>2008-04-21T10:15:58.951-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='remoting'/><category scheme='http://www.blogger.com/atom/ns#' term='jboss'/><title type='text'>Remoting 3.0.0-M2 Released</title><content type='html'>&lt;span class="postbody"&gt;Remoting 3.0.0-M2 is released. I've got the jars uploaded in a ZIP file, but you'll want to check out the project and look in the "samples/" for samples of using the standalone API. The Microcontainer integration is scheduled for M3, so standalone is pretty much all that you can really play with at the moment. Report bugs in JIRA as "found in: 3.0.0-M2" and "fix for: 3.0.0-M3" to make sure I see them.&lt;br /&gt;&lt;br /&gt;The version "M2" means "Milestone 2".  The API is more or less stable, but until the first Beta release it is possible that the API (and the basic protocols) will change in an incompatible way.  I do, however, encourage you to download and play around with it.&lt;br /&gt;&lt;br /&gt;You can &lt;a href="http://www.jboss.org/jbossremoting/downloads/"&gt;download the JARs here&lt;/a&gt;, and as always the sources are available via &lt;a href="http://anonsvn.jboss.org/repos/jbossremoting/remoting3/trunk/"&gt;anonymous SVN&lt;/a&gt; (and &lt;a href="https://svn.jboss.org/repos/jbossremoting/remoting3/trunk/"&gt;committer SVN&lt;/a&gt;).&lt;br /&gt; &lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1214048633682585732-6083406883175468631?l=dmlloyd.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dmlloyd.blogspot.com/feeds/6083406883175468631/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1214048633682585732&amp;postID=6083406883175468631' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6083406883175468631'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1214048633682585732/posts/default/6083406883175468631'/><link rel='alternate' type='text/html' href='http://dmlloyd.blogspot.com/2008/04/remoting-300-m2-released.html' title='Remoting 3.0.0-M2 Released'/><author><name>David M. Lloyd</name><uri>http://www.blogger.com/profile/09324451206499581019</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
