Wednesday, September 22, 2010

JavaOne 2010: JavaFX Graphics

In late July, I publicly wondered how much time I should spend on JavaFX at JavaOne 2010. JavaFX was the big announcement at 2007 JavaOne and dominated 2008 JavaOne and had numerous sessions in 2009 JavaOne, but it wasn't clear to me that JavaFX's future was worth missing other subjects to attend sessions on JavaFX. I knew the other subjects would be viable in the future, but wasn't so sure about JavaFX. The JavaOne 2010 Opening Keynote changed all that. Not only did they talk big game about JavaFX's future (which has been the refrain from the past three JavaOne conferences), but as (or more) importantly, they described their vision for it in a way that, for the first time in a long time, I think gives it a reasonable opportunity for long-term success and widespread adoption. With that in mind, it is not surprising that Jim Graham's and Kevin Rushforth's presentation "JavaFX Graphics" was fairly well attended.

JavaFX uses the Scene Graph Model for its graphics support. The scene graph consists of a hierarchy of group and leaf nodes. It makes media directly accessible and easy to add to applications with minimal effort.

The speakers stated that some JavaFX capabilities that would get less attention from them in this presentation are SVG paths, Media (sound and video), UI controls, Input, 3D cameras, and charts.

Prism is a new graphics stack, but is at implementation level (implements SceneGraph at rendering level), but is invisible to the developer. Its main reason for use is performance, but it does provide 3D. Prism will be default renderer in the next release, Although it is expected that most machines will have graphic cards to support Prism by the time it is released, software support and Swing Toolkit will be retained for those machines that don't have graphics cards supporting Prism. This release is expected sometime in 2011. The JavaFX developer sees JavaFX UI Controls and JavaFX Scene Graph API, but does not need to deal with Swing Toolkit, Java 2D, or other implementaton-specific APIs.

The presenters showed numerous effects examples with source code. Not surprisingly, most of their slides were written using JavaFX Script because they were created before the official announcement of JavaFX Script's deprecation. Also, the presenters stated that JavaFX Script uses fewer lines of code, so it was better suited for fitting onto slides. Finally, there are some features JavaFX Script provides that still need to be incorporated into Java as convenience methods.

Some of the main topics covered in this presentation were applying effects and animation. The speakers covered adding 3D perspective transforms. We won't see all 3D transforms in the next release of JavaFX, but the rest should come in the next version after that.

The audience seemed genuinely interested in JavaFX. Questions were repeatedly asked and answered regarding whether these examples demonstrated will be doable in standard Java. Repeatedly the answer was that JavaFX Script is deprecated and these functions will be available via standard Java. I believe this gives JavaFX the best chance for long-term success and widespread adoption, especially if other improvements to the Java language make it less verbose. If all Java developers can easily access JavaFX APIs and the books, articles, and blogs all indicate how to use these APIs without specific JavaFX Script, its widespread adoption should be much greater. I think the vision is there. The question, as in the past three JavaOne conferences, is how quickly it can be delivered.

Sun Didn't Like Google's Handling of Android Either

Darryl K. Taft's article Java Creator James Gosling: Why I Quit Oracle provides some additional insight into why the so-called "father of Java" (James Gosling) quit Oracle shortly after the Oracle acquisition of Sun. That's interesting enough in itself and the title of the article implies that content. However, I found the reported Gosling comments on Sun, Google, and Android just as interesting. I look at that briefly in this post.

I have heard and read from more than one Java developer who sees Oracle's lawsuit against Google over Android as completely evil and indefensible. Many of these folks say things along the lines of, "Sun would never have done anything like that." If Gosling is quoted correctly, it seems clear that Sun wasn't too happy about Google's tactics with Android either. According to the article, Gosling stated, "We were pretty ticked off with what they were doing and the way they were doing it."

If Sun wasn't happy with Google, why didn't they purse the issue legally like Oracle has? Gosling's explanation is two-fold: lawsuits are expensive in terms of money and senior personnel time and because "Google has the PR aura about it as being the universe’s love child." Obviously, it's not good public relations to sue the "universe's love child." Software developers as a group seem particularly prone to "us versus them" attitudes: PC vs Mac, Windows vs Linux, vi vs emacs, NetBeans vs Eclipse, aligned curly braces vs opening brace continuing same line, and on and on. This seems to have spilled over to love/hate relationships with vendors as well.

The article references Gosling's own blog post with more details on how Sun tried to handle the Android situation. In his blog, Gosling makes it clear that he is in no way defending Oracle or contributing to Oracle's lawsuit. Instead, though, this article and his blog posts are intended as reminders that "There are no guiltless parties with white hats in this little drama." One question I wonder about: Had Sun done anything legally against Google regarding Android, would Sun (an obvious and enthusiastic open source supporter in recent years) have been considered 'attacking open source' as some allege Oracle has?

JavaOne 2010: Polyglot Programming in the JVM

I was impressed with how Andres Almiray's performed as a substitute speaker for Hamlet D'Arcy's JavaOne 2010 presentation "Code Generation on the JVM" and looked forward to his presentation of his own talk: "Polyglot Programming in the JVM: Or How I Learned to Stop Worrying and Love the JVM". This session was my third session of the day in the same hotel (Parc 55)!

Almiray began by outlining his credentials and providing "some facts about Java" (see Java History 101: Once Upon an Oak). Almiray stated that while generics can be good, he doesn't love them. Almiray explained that Java's language syntax was designed to be attractive to developers in C/C++, which were the dominant languages of the day. This led to Java having more verbosity than it needs today.

After outlining some of Java's history that have made it more challenging to use, Almiray transitioned into talking about using JVM languages other than Java to enjoy the benefits of JVM "without the pain of Java."

The non-Java JVM languages tend to be more concise (less verbose) than Java. Almiray showed the common JavaBean example written in Java and said we have come to rely on IDEs because of the pain involved with writing these in Java. Almiray showed code for Groovy, Clojure, and Scala versions of the same JavaBean that had been written in Java originally.

Almiray moved from standard JavaBeans classes to coverage of closures. He pointed out that Java does not have closures and that Java developers commonly use anonymous inner classes to do the same thing. Java is supposed to get Lambda in a future version (JDK 8). Almiray the same proposed Java Lambda code with Groovy closures, Clojure closures, and Scala closures. In demonstrating these examples, Almiray reminded the audience that Groovy supports operator overloading and that Scala uses the val keyword to indicate a variable's value cannot be changed.

Almiray's next topic was "enhanced switch" which we might get in Java 7. He showed Groovy code switching on a range. In these examples, Almiray asked who likes to use regular expressions in Java.  There were no raised hands. One of Almiray's examples showed use of Groovy's ~ operator for regular expressions for a case to evaluate. Almiray went on to demonstrate the code for doing this with Scala and Clojure.

Almiray talked about one of my favorite features of Groovy: integration with Java without JSR 223. He stated that the same seamless two-way integration with Java is true of Clojure and Scala as well. Other things that these three alternative JVM languages have in common are operator overloading support, regular expressions "as first class citizens", closures, everything as an object, and native syntax for collection classes.

On operator overloading, Almiray thinks that Scala has "gone over the top" because it allows developers to write any method they want to override any operator they want (he used ==== as an example). He contrasted this with Groovy which has a much smaller set.

Almiray went on to discuss each of the three alternative JVM languages advertised in his abstract on an individual basis. He stated that Groovy's metaprogramming capability at buildtime and runtime attracted him to Groovy. He also likes the healthy Groovy ecosystem: Grails, Griffon, Gant (Groovy version of Ant), Gradle, Spock, Gaelyk (Google App Engine), Gpars (Groovy Parallel Systems), CodeNarc (code inspection), etc. Groovy was "born in 2003" and is about to celebrate its seventh birthday next month.

Scala's syntax is different than Java's/Groovy's, but Scalar has a richer type system. Scala will not allow you to "put a square peg in a round hole." Scala uses type inference and can use implicits to provide hints as to the type. Scala's actor model deals with concurrency and threads. Almiray said that the Actor Model is not a silver bullet for concurrency, but is much better. Almiray also talked about Scala's Traits, which support mixing in different behaviors.

Clojure, like all LISP variants, treats "data as code and vice versa." Clojure provides immutable structures and Software Transactional Memory (STM). STM is also making its way into Scala. If STM is added to Java, it would be readily available in Groovy.

Almiray demonstrated a small example of all three of these alternative JVM languages working together. The name of the demonstrated software was appropriately named Babel. Almiray mixed this demonstration with views of the source code in the IDE. One thing I would not have realized is that the Scala Double is NOT the Java Double.

Almiray identified "other places you might find polyglot development."  Web development features many languages/formats: XML, SQL, JavaScript, JSON, CSS, Flash/Flex/ActionScript. We're starting to see "Next-Gen Datastores (NoSQL)" (polyglot persistence): FleetDB in Clojure, FlockDB in Scala, CouchDB and Riak in Erlang. Almiray stated that some people are starting to say that NoSQL is no longer "No SQL," but is instead becoming "Not Just SQL." Polyglot build systems include Gradle/Gant for Groovy, Rake for Ruby/JRuby, and Maven 3 for XML/Groovy/Ruby.

Almiray believes that Java may have reached its maturity in terms of features. Clojure is "making a lot of noise" after being only three years old and Scala and Groovy were started in the 2000s. Although polyglot programming has received more (and more favorable) press recently, it's been around for quite some time. Almiray also referenced Stuart Halloway's Java.next blog.

JavaOne 2010: JUnit Kung Fu: Getting More Out of Your Unit Tests

My Wednesday at JavaOne 2010 began with John Ferguson Smart's standing-room-only presentation "JUnit Kung Fu: Getting More Out of Your Unit Tests." Most of the overcapacity audience responded in the affirmative when Smart asked who uses JUnit. While the majority of the audience uses JUnit 4, some do use JUnit 3. Only a small number of individuals raised their hands when asked who uses Test-Driven Development (TDD).

Smart stated that appropriate naming of tests is a significant tool in getting the most out of JUnit-based unit tests. He mentioned that JUnit 4 enables this by allowing for annotations to specify the types of tests rather than having to use the same method name conventions that earlier versions of JUnit requires. In the slide, "What's in a name," Smart pointed out that naming tests appropriately helps express the behavior of the application being tested. Smart likes to say he doesn't write tests for his classes. Instead, classes get tested "as a side effect" for his testing of desired behaviors. Smart recommended that you don't test "how it happens," but test "what it does." If your implementation changes, your test doesn't necessarily need to change because you're only worried about outcomes and not how the outcomes are achieved. Smart talked about how appropriately named tests are more readable for people new to the tests and also provide the benefit of helping test the appropriate things (behaviors).

Smart outlined many naming tips in his slide "What's in a name" (only a subset it listed here):
  1. Don't use the word "test" in your tests (use "should" instead)
  2. Write your tests consistently
  3. Consider tests as production code
For Unit Test Naming Tip #1, Smart stated that "should" is very common in Behavior-Driven Development (BDD) circles. Test methods should be named to provide a context. They should provide the behavior being tested and the expected outcome. I liked this tip because I find myself naming my test methods similarly, but I have always started with the word "test," followed by the method name being tested, followed by the expected behavior and outcome. Smart's recommendations reaffirm some of the things I have found through experience, but I think provide a better articulation of how to do this in a more efficient way than I've been doing.

Smart stated that tests should be written consistently. He showed two choices: "Given-When-Then" or "Arrange-Act-Assert." Smart said that he uses the classic TDD approach of writing to the inputs and outputs first and then writing the implementation.

Smart's bullet "Tests are deliverables too - respect them as such" summarized his discussion of the importance of refactoring tests just as production code is refactored. Similarly, he stated that they should be as clean and readable as the production code. One of the common difficulties associated with unit tests is keeping them maintained and consistent with production code. Smart pointed out that if we treat the unit tests like production code, this won't be seen as a negative. Further, if tests are maintained as part of production maintenance, they don't get to a sad state of disrepair. In the questions and answers portion, Smart further recommended that unit tests be reviewed in code reviews alongside the code being reviewed.

Smart spent over 20 minutes of the 60 minute presentation on test naming conventions. He pointed out at the end of that section that if there was only one thing he wanted us to get out of this presentation, it was the important of unit testing naming conventions. I appreciated the fact that his actions (devoting 1/3 of the presentation to naming conventions for unit tests) reaffirmed his words (the one thing that we should take away).

Smart transitioned from unit test naming conventions to covering the expressiveness and readability that Hamcrest brings to JUnit-based unit testing. Smart pointed out a common weakness of JUnit related to exceptions and understanding what went wrong. Hamcrest expresses why it broke much more clearly. Smart covered "home-made Hamcrest matchers" (custom Hamcrest matchers) and described creating these in "three easy steps." Neal Ford also mentioned Hamcrest in his JavaOne 2010 presentation Unit Testing That's Not So Bad: Small Things that Make a Big Difference.

Only a few people in the audience indicated that they use parameterized tests. Smart talked about how parameterized tests are useful for data-driven tests. JUnit 4.8.1 support for parameterized tests was demonstrated. JUnit creates as many instances of the class as there are rows in the associated database table. A set of results is generated that can be analyzed. Smart also talked about using Apache POI to read in data from Excel spreadsheet to use with parameterized testing. Smart referred the audience members to his blog post Data-driven Tests with JUnit and Excel (JavaLobby version) for further details.

Smart demonstrated using parameterized tests in web application testing using Selenium 2. The purpose of this demonstration was to show that parameterized tests are not limited solely to numeric calculations.

Smart next covered JUnit Rules. He specifically discussed TemporaryFolder Rule, ErrorCollector Rule, Timeout Rule, Verifier Rule, and Watchman Rule. The post JUnit 4.7 Per-Test Rules also provides useful coverage of these rules.

Smart believes that recently added JUnit Categories will be production-ready once adequate tooling is available. You currently have to run JUnit Categories using JUnit test suites (the other work-around involves "mucking around with the classpath"). Smart's Grouping Tests Using JUnit Categories talks about JUnit Categories in significantly more detail.

Parallel tests can lead to faster running of tests, especially when multiple CPUs are available (common today). Smart showed a slide that indicated how to set up parallel tests in JUnit with Maven. This requires JUnit 4.8.1 and Surefire 2.5 (Maven).

Smart recommended that those not using a mocking framework should start using a mocking framework to make unit testing easier. He suggested that those using a mocking framework other than Mockito might look at Mockito for making their testing even easier. He stated that Mockito's mocking functionality is achieved with very little code or formality. The JUnit page on Mockito has this to say about Mockito:
Java mocking is dominated by expect-run-verify libraries like EasyMock or jMock. Mockito offers simpler and more intuitive approach: you ask questions about interactions after execution. Using mockito, you can verify what you want. Using expect-run-verify libraries you often look after irrelevant interactions.
Mockito has similar syntax to EasyMock, therefore you can refactor safely. Mockito doesn't understand the notion of 'expectation'. There is only stubbing or verifications.
Like Neal Ford, Smart mentioned Infinitest. He said it used to be open source, but is now a combination of commercial/open source. The beauty of this product is that "whenever you save your file changes [your production source code], [the applicable] unit tests will be rerun."

Smart stated something I've often believed is a common weakness in unit testing. He referred to this as a "unit test trap": our tests often do test and pass what we coded (but not necessarily the behavior we wanted). Because the coder knows what he or she coded, it is not surprising that his or her tests validate that what he or she wrote as they intended.

Regarding code coverage tools, Smart stated that these are useful but should not be solely relied upon. He pointed out that these tools show what is covered, but what we really care about is what is not test covered. My interpretation of his position here is that code coverage tools are useful to make sure that a high level of test coverage is being performed, but then further analysis needs to start from there. Developers cannot simply get overconfident because they have a high level of test coverage.

Smart stated in his presentation and then reaffirmed in the questions and answers portion that private methods should not be unit tested. His position is that if a developer is uncomfortable with them enough to unit test them individually, that developer should consider refactoring them into their own testable class. For me, this fits with his overall philosophy of testing behaviors rather than testing "how." See the StackOverflow thread What's the best way of unit testing private methods? for interesting discussion that basically summarizes common arguments for and against testing private methods directly.

Smart had significant substance to cover and ran out of time (Smart quipped that we had "approximately minus 20 seconds for questions"). This is my kind of presentation! In many ways, it was like trying to drink from a fire hose, but I loved it! There are numerous ideas and frameworks he mentioned that I plan to go spend quality time investigating further. I'm especially interested in the things that both he and Neal Ford talked about.

DISCLAIMER: As with all my reviews of JavaOne 2010 sessions, this post is clearly my interpretation of what I thought was said (or what I thought I heard). Any errors or misstatements are likely mine and not the speaker's and I recommend assuming that until proven otherwise. If anyone is aware of a misquote or misstatement in this or any of my JavaOne 2010 sessions reviews, please let me know so that I can fix it.

JavaOne 2010: Visualizing the Java Concurrent API

One of my goals at JavaOne 2010 was to attend some sessions on Java concurrency. I had not been aware of the Java Concurrent Animated project until reading the abstract for this presentation:
This presentation will consists of a series of animations that visualize the functionality of each Java concurrent component. Each animation features buttons that correspond to the methods in that component. Each click of a button creates a thread to calling a method, showing how the threads interact in real time. Each animation is controlled by the actual Java concurrent component it is illustrating, so the animation is not only a visual demonstration, it's also a code example. If you?re still using constructs like Thread.start or wait/notify, you'll want to attend this meeting. The presentation is packaged as a self-executable Java Archive (JAR) file and is available for download. It is a valuable reference.
The abstract looked outstanding, but in the back of my mind I wondered if it was worth going to a presentation on this if I could simply run the advertised self-executable JAR file. It turns out that I was glad that I did attend because there was significant discussion regarding what was graphically being displayed.This was another standing-room-only presentation.

The speakers began the presentation with a brief history of concurrency support in Java. They have worked on this application to serve as an graphical illustrative reference for how the various concurrent structures work.

The specific concurrency structures first discussed were Executors (java.util.concurrent.Executor), which provide the access to thread pools. The "bouncer class of Java" is the Semaphore (java.util.Semaphore). Whereas a lock is reentrant, a Semaphore is not reentrant. It is possible for a Semaphore to be released by a Thread other than the Thread that started the Semaphor.

ReetrantLock (java.util.concurrent.locks.ReentrantLock) is a replacement for synchronized that allows same Thread to reenter. This makes it possible to avoid potential deadlock problem associated with synchronized. The cost is the need to manually unlock it from the same Thread that locked it.

Condition (java.util.concurrent.locks.Condition) is directly related to the Lock (same package!). The Javadoc notation for Condition summarizes its purpose nicely:
Condition factors out the Object monitor methods (wait, notify and notifyAll) into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitraryLock implementations. Where a Lock replaces the use of synchronized methods and statements, a Condition replaces the use of the Object monitor methods.
Even this Condition still has the possibility of "spurious wakeups."

The ReentrantReadWriteLock (java.util.concurrency.locks.ReentrantReadWriteLock) policy has changed from J2SE 5 to Java SE 6.

CyclicBarrier (java.util.concurrent.CyclicBarrier) and CountDownLatch (java.util.concurrent.CountDownLatch) are familiar concepts for those familiar with working with hardware. The Javadoc describes the CyclicBarrier: "A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point." It also describes an effect described in the presentation: "The CyclicBarrier uses an all-or-none breakage model for failed synchronization attempts: If a thread leaves a barrier point prematurely because of interruption, failure, or timeout, all other threads waiting at that barrier point will also leave abnormally via BrokenBarrierException (or InterruptedException if they too were interrupted at about the same time)."  The Javadoc also provides a nice summary of CountdownLock:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
A CountDownLatch is initialized with a given count. The await methods block until the current count reaches zero due to invocations of the countDown() method, after which all waiting threads are released and any subsequent invocations of await return immediately. This is a one-shot phenomenon -- the count cannot be reset. If you need a version that resets the count, consider using aCyclicBarrier.
AtomicInteger (java.util.concurrent.atomic.AtomicInteger) is representative of thread-safe access on single variables.  See java.util.concurrent.atomic package description for further details.

The BlockingQueue (java.util.concurrent.BlockingQueue) and Future (java.util.concurrent.Future) [often returned by Executors] were also discussed and demonstrated. Callable is similar to Runnable but returns generic object instead of void.

The java.util.concurrent approach also introduced the ability to set time units explicitly rather than specifying everything in number of milliseconds. This is available via the TimeUnit enum.

Download Java Concurrent Animated at http://sourceforge.net/projects/javaconcurrenta/. Because this executable uses the very concurrent structures it is illustrating, there is no "artificial" rendering of what's happening. This means that even strange or unexpected behaviors can be seen.

On a pretty much unimportant and unrelated note, I was in the same room for two consecutive sessions for the first (and likely only) time during this conference. Both this presentation and the presentation I attended before it (JUnit Kung Fu: Getting More Out of Your Unit Tests) were held in Parc 55's Embarcadero.

Tuesday, September 21, 2010

JavaOne 2010: Speedy Scripting: Productivity and Performance

Per Bothner presented "Speedy Scripting: Productivity and Performance" today at JavaOne 2010.  He started into this topic by presenting things we like about scripting languages and things we like about compiled languages.  For example, he talked about how we generally like the no or hidden compiling of scripting languages as well as scripting languages' less boilerplate and runtime advancements. Desirable features of compiled languages include execution speed, compile time error checking, greater ability for tooling to help, and greater ability for humans to read and understand what's happening specifically.

Of course, Bothner observed, everybody wants to combine best of both. Bothner mentioned JSR 292 ("Supporting Dynamically Typed Languages on the JavaTM Platform"). In fact, one of the "themes" of JavaOne 2010 has seemed to me to be along the lines of retaining Java's power but bringing more advantages commonly associated with scripting languages to Java.

One observation that Bothner made that I have also observed is that performance is often not as important in many scripting situations with today's faster hardware and small scripts.  However, he pointed out, these scripts often become much larger and then performance begins to matter.  An example he cited here was the emphasis from each major browser vendor on coming up with a faster JavaScript now that much larger JavaScript libraries are available and JavaScript-based applications are getting much larger.

One "semi-solution" to deal with the trade-off between scripting languages and compiled languages is to use the "appropriate language for each job."
Bothner went through several slides on different languages trying to bridge the gap between scripting languages and compiled languages or exhibiting language features he wanted to call out.  I am guessing I'm missing some here, but I'll summarize some of them.  He referenced Scala as a strongly type language similar to Java with interesting concepts that some people refer to as "The Better Java." Clojure is LISP-like JVM language suited for concurrency.
Bothner referenced a language I had never heard of: Thorn. He referenced an OOPSLA paper on it. The abstract for that presentation states about Thorn: "Thorn is an object-oriented scripting language with support for concurrent and distributed computing and robust program evolution." The Thorn page describes Thorn this way:
Thorn is a dynamically-typed concurrent language in which lightweight isolated processes communicate by message passing.
. . .
Thorn is a joint effort between Purdue University and IBM Research T.J. Watson Research Center.
Currently there are two different implementations of Thorn. We have a compiler that targets the JVM and an interpreter written in Java. The interpreter implements the full language, while the compiler currently implements a subset.
Bothner briefly introduced his own language, Kawa, which is a dialect of Scheme. Among other advantages, it features a true compiler and is fast. He also stated that Scheme is where first class closures got their start.

Until this presentation, I was not aware of The Computer Languages Benchmark Game. The main page for this game describes it briefly as: "Compare the performance of ~30 programming languages using ~12 flawed benchmarks for 4 different combinations of OS/machine. Contribute faster more elegant programs." Bothner warned that the normal performance benchmarking caveats apply here: a particular language's performance depends on the cleverness of the developer's solution and on the fit of that language for each of the potential problems being solved. In short, one cannot necessarily say one language is faster than another just because of overall better marks in this game.

Bothner provided his "Performance Factors in Language Design." I'm not listing them all here and recommend seeing his slide for all of them. However, there were a couple points that stood out to me that I thought delivered mention here. He stated that the language should make type specification available but optional. He referred to "optimistic static typing" in which the language only rejects an attempted assignment if it can prove that the assigned value cannot match. He prefers this to more strict static typing in which it must be proven that the assignment can be made.

Bothner believes that a language should be required to declare variables to avoid typos and because doing so is basis for most optimization and error checking. I cannot agree more with another of Bothner's assertions: Avoid String-based APIs. He pointed out that String APIs present security risks and easy opportunities for breakage. He emphasized functionally generating output Strings rather than passing around Strings directly.
Another good point that Bothner made is that there are cases where static typing can make your programming more productive and easier. When implemented correctly and in the right situations, static code can actually be even less verbose than dynamically typed code.

Bothner talked about Expression-Oriented Programming.  He stated that expressions are less verbose and more composable than the alternatives. He used SQL's use of expressions as an example and stated that although "SQL may be a mess," its use of expression-oriented programming is an advantage.
Bothner then rounded out his talk with a conclusion and summary.  I found this presentation to be interesting in several ways, but particularly enjoyed the opportunity to think a little "bigger picture." I tend to prefer presentations with technical details that I can apply immediately, but I want presentations like Bothner's sprinkled in their because they are challenging in a different way.  They force me to think about bigger picture ideas and what I like and don't like in the languages I commonly use. I doubt that I'll begin writing a language of my own anytime soon, but Bothner's presentation helps me to better understand why I like certain languages better than others, how to better judge which languages are worth further effort, and how to decide which language is best for the job.

JavaOne 2010: OSGi Migration Headaches

Krasimir Semerdzhiev and Peter Peshev presented "OSGi Migration Headaches" at JavaOne 2010. The speakers took turns presenting and started with an introduction regarding OSGi, what it is, and why it is useful. This is one of those presentations that was useful to hear, but will be even more useful as a reference when working with OSGi. The slides contained several common problems encountered when introducing OSGi into a Java application.  For each problem, common issues or causes of that problematic symptom are listed.  It's a great format for a reference. Many of the issues and problem causes the speakers identified are
not specific to OSGi and so their discussion of those issues is generally useful to Java developers.

The speakers recommended Eclipse Plugin Development Environment (PDE) for creating bundle manifests.  This is easier and less error prone than hand-writing these bundle manifests.

Upon first bundle activation, one is likely to see java.lang.ClassNotFoundException. They listed possible causes of this (missing import-package, missing export-package, import version mismatch, forgotten/missing component, wrong boot class delegation property, file permissions problems). There is a potential problem of specifying versions incorrectly because of subtle differences in version specification syntax.

The java.lang.NoClassDefFoundError means class is not found but cannot get instance of. Possible causes include exception in static block, missing imported class, class version mismatch, HotSpot reflection JIT optimizations (BugID 6265952 related to 15 method calls).

The java.lang.ClassCastException can be caused by additional copies of the OSGi framework classes, undesirable additional JARs on the classpath, and conflict/clash between RT.jar and application libs.

The speakers discussed possible issues underyling the situation when it works in Eclipse but not in Equinox. See also the article OSGi with Eclipse Equinox - Tutorial.

The speakers talked about dependencies on startup order. They also discussed classloader resource assumptions and possible issues: JAR files, folders with class files/packages, URLs to JARs or classes, or new File call after loader resources iteration. Boot delegation specifics got its own slide: com.foo.* includes all sub-packages but not com.foo package itself.

Speakers recommended using Eclipse Memory Analyzer when trying to determine cause of conflicts, errors, and exceptions when using OSGi.

This presentation is one of those which would definitely be helpful to have on hand (hard copy of soft copy) as a reference when using OSGi. It would nice to be able to look up the common causes of these various identified issues by symptom.