The Source for Java Technology Collaboration
User: Password:



Fabrizio Giudici's Blog

Fabrizio Giudici Fabrizio Giudici is a Senior Java Architect with a long J2EE experience and in the latest two years he expanded his interests to Jini and NetBeans. Fabrizio has been running Tidalwave.it, his own consultancy company, since 2001 and has been a technical speaker at JavaOne, JavaPolis, Jazoon, Jini Community Meetings and some italian Java conferences. He started working with Java since the old 1.0 times and after 1.3 he has been committed in demonstrating that Java performance is not an issue, really. After bringing Java to the world of Formula One telemetry, he believes he is on the right path. Fabrizio is a member of the JUG Milano and the NetBeans Dream Team.



Shame on you, MediaMarkt Zurich

Posted by fabriziogiudici on June 29, 2009 at 03:20 AM | Permalink | Comments (0)

The past week I've spend a day in Zurich to attend OSGi DevCon Europe. It has been a good experience, even though I was (and I am) not yet in good shape.

When I left the venue, before going to the hotel to have a rest, I took the chance of visiting the near-by MediaMarkt shop in SihlCity. I recalled that I had been there in 2007 and the shop was really packed with stuff that I seldom find on the shelf in Italy, even at MediaWorld (the italian equivalent of MediaMarkt). What I needed was a 500GB 2.5" SATA to replace the one on my laptop, since it has a faulty sector.

I found the disk, as expected. But when I tried to check it out, I have been told that payment with credit card was not allowed; only cash or debit cards. What? In one of the most known IT supermarkets, in one of the most luxurious commercial centers of Zurich, in one of the most bank-related cities of the world? One of the most stupid things I've ever seen. I'm a regular customer of MediaWorld in Italy and I've always paid with my credit card with no problems at all.

For the record, I missed 10 euros for paying with cash and I was too tired to search for a teller machine, so I left the disk there.




Wine delivered at OSGi DevCon

Posted by fabriziogiudici on June 22, 2009 at 02:16 AM | Permalink | Comments (1)

Well, so I'm at OSGi DevCon Europe (the only day I'm being in Zurich). One of the missions I had to accomplish is to deliver some fine italian wine to Felipe Gaucho, for thanking him as he's hosting some CPU-intensive Hudson jobs for blueMarine).

I'm happy to be in Zurich since I'm still in bad shape and, after the JavaOne fault, even this visit wasn't sure; and today I've such a fuzziness in my head that I'm having a bit of troubles even in following the presentations.

Anyway, the OSGi stuff is really interesting for me as I'm new to this technology (as a plus for the organization, WiFi is working and I've got a power supply in the presentation room, excellent!). During the break I've had an interesting conversation with Toni Epple, who'll later deliver his presentation about NetIGSO - in my opinion one of the most clever things that are happening to the NetBeans Platform.

Also, this week I'm mixing some vacation with JavaFX mobile testing. I've got the JavaFX runtime with my HTC Diamond Touch, but the first run of blueBill Mobile was not good - the application crashed just after the first launch while I was on the Splügenpass. Indeed, it was a sort of expected thing, as so far I've only tried the application with the emulator and the past week I've performed some changes to the application working with the desktop profile, since I hadn't Windows at hand (still required for the mobile development). But I'm carrying a second laptop with Windows aboard and tomorrow I'll try to fix it.




First enhancements on BetterBeansBinding

Posted by fabriziogiudici on June 15, 2009 at 10:55 AM | Permalink | Comments (0)

After the May pause, I've resumed working on BBB. As anticipated, the focus now is on test coverage, but I've also started working on some enhancements / bugs submitted by people. For instance, BETTERBEANSBINDING-32, "JTableBinding.ColumnBinding: cell renderer/editor" is about adding the capability of specifying a cell renderer and / or editor for any column of a JTableBinding:
final List<MockBean> beans = new ArrayList<MockBean>();
beans.add(new MockBean(1, 11.1, "First row"));
beans.add(new MockBean(2, 22.2, "Second row"));
beans.add(new MockBean(3, 33.3, "Third row"));
beans.add(new MockBean(4, 44.4, "Fourth row"));

final IntegerTableCellRenderer integerTableCellRenderer = new IntegerTableCellRenderer();
final DoubleTableCellRenderer doubleTableCellRenderer = new DoubleTableCellRenderer();
final SpinnerTableCellEditor spinnerTableCellEditor = new SpinnerTableCellEditor();

final JTable table = new JTable();
final JTableBinding binding = SwingBindings.createJTableBinding(UpdateStrategy.READ, beans, table);

binding.addColumnBinding(BeanProperty.create(MockBean.PROP_PROPERTY1)).
        setColumnName("property1").
        setEditable(true).
        setEditor(spinnerTableCellEditor).
        setRenderer(integerTableCellRenderer);

binding.addColumnBinding(BeanProperty.create(MockBean.PROP_PROPERTY2)).
        setColumnName("property2").
        setRenderer(doubleTableCellRenderer);

binding.addColumnBinding(BeanProperty.create(MockBean.PROP_PROPERTY3)).
        setColumnName("property3");

binding.bind();

The priority I'll give to issues is the result of a "cost function" involving different variables:
  1. Whether you've submitted a patch (some issues have got it)
  2. Whether you've submitted a reasonable good test case
  3. How much I've got acquainted to the related part of the code
I've given up, for now, with automatically copying the issues from the old BB tracker at java.net - I've spent a considerable effort in setting up the software factory, but now I'd like to focus on the code. So, if you have urgent issues pending in BB, please open them again to BBB (maybe adding a reference to the old issue tracker).

Recall that it's possible to vote for issues, and I would take it into account together with the other criteria.







Jazoon and OSGi DevCon + maybe testing on the field blueBill Mobile

Posted by fabriziogiudici on June 15, 2009 at 04:24 AM | Permalink | Comments (0)

Just a reminder of the next round of conferences:
  • OSGi DevCon 2009 (and GlassFish Community Day) will be held in Zurich on Monday 22nd.
  • Jazoon 2009 will be held in Zurich for the rest of the week.
I'll attend OSGi DevCon; no Jazoon for me as the past weeks have been pretty complicated (first, the budget was consumed by JavaOne attendance; and even though moneys haven't been spent because of my fault, there's a much needed bunch of holidays, scheduled since a couple of months, just after OSGi DevCon).

If I manage in putting blueBill Mobile on my newly bought HTC Diamond Touch, the trip trough the Alps and Provence will be used for some real-world testing.





JavaFX binding is neat, but ... beware

Posted by fabriziogiudici on June 11, 2009 at 02:45 PM | Permalink | Comments (23)

An interesting chains of discussions has been triggered about JavaFX features and how it can be possibly used beyond the GUI scope.

Osvaldo has just published an interesting post. Actually I like binding a lot, but I was wondering about some adverse effects that can arise out of binding use.

There is a basic conceptual problem: binding is an evolution of getters/setters, that is exposure of naked properties. According to OO principles it is a breakage of information hiding, that should implemented by encapsulation, but we got used of it because of fourteen years of Java, as most of the Java frameworks use it (not only Swing, but also JPA etc...). So we can live with it - but I'd say I'm fine with it for some mundane uses such as populating a UI or a persistence bean; it would be probably better if we learned to avoid it for core business classes.

Anyway, this is just a general premise; now let's consider a specific example. Consider the following JavaFX class:
class Breakable
  {
    public var theProperty = 0;

    public function breakIt(): Void
      {
        theProperty = 4;
      }
  }
It's fine, right? You can even unit test it without problems, so you declare it stable.  Now, you use Breakable in this context:

var breaker = 1;

def breakable = Breakable
  {
    theProperty: bind breaker;
  };

public function run(): Void
  {
    breakable.breakIt();
  }

Run it, and you get a

com.sun.javafx.runtime.AssignToBoundException: Cannot assign to bound variable

You can't execute theProperty = 4, since theProperty is bound and, by definition, at every moment can only hold the same value as breaker.

Do you see my point? An external class has broken Breakable, that was fine by itself. We have injected a problem. This is a worse breakage than breaking information hiding in Java by getters/setters, as not only we can change the internal status of Breakable (forgivable as explained in the premise), but we changed also the behaviour of theProperty, that now can't be assigned any longer; it is now incompatible with the original behaviour of Breakable.

I'd be worried about using this in a core business class. OO exists to make our software more robust, but binding in this perspective can make it more brittle.

I propose to address this issue by introducing an unbindable keyword such as:

class Breakable
  {
    public unbindable var theProperty = 0;

    public function breakIt(): Void
      {
        theProperty = 4;
      }
  }

This would make the compiler stop with an error when you try to bind theProperty (the problem is unidirectional binding; bidirectional binding is ok). You might think that the enhancement of the compiler could be done without a specific modifier, as the compiler could induce the unbindable status of theProperty by just finding the assignment theProperty = 4; but this is just a simple example, and theProperty could be a protected variable manipulated by a subclass.

This small example can be checked out as a NetBeans project from:

svn co -r 45 https://kenai.com/svn/javafxstuff~svn/trunk/Binding1


What if you run JUnit tests on a JavaFX project with Cobertura?

Posted by fabriziogiudici on June 07, 2009 at 07:43 AM | Permalink | Comments (0)

Well, clearly Cobertura can't handle the syntax of JavaFX, so I think many figures are wrong (e.g. Branch Coverage, Complexity; I'm unsure about Line Coverage). But some bit of useful information is here, at least for what concerns what you haven't tested at all.



You get also some file-level details, but the incapability of understanding JavaFX syntax lead to inconsistencies (note red lines with a non zero count). But it seems that searching for non zero counts is a good way to find out which lines you don't have covered).

Who knows whether anybody will care about writing a Cobertura plug-in for JavaFX? If Sun has got a few money for pushing small projects, it would be a good idea IMO.



Writing a UI controller in JavaFX

Posted by fabriziogiudici on June 06, 2009 at 04:28 PM | Permalink | Comments (2)

While JavaFX is great for the UI (binding, declarative stuff, etc...) it's also a good candidate for writing controllers (in a MVC).

Of course I'm not saying I'd write a complete application (I mean, a back-end) in JavaFX - JavaFX is a DSL and it's specific for the presentation part. You'd have problems in forcing it to a broader scope than the one it has been designed for. But the specific models and controllers of a front-end are fine - and you can take advantage of binding there too.

For this post, I'm focusing on a couple of classes of blueBill Mobile, in particular to the controller that manages all the logic behind the "Search species" screen; thus this post could help you in getting more confident with the language features of JavaFX, beyond the UI stuff. I'm also using a few real-case points to illustrate some tips and pitfalls of some typical JavaFX constructs.

I'm embedding an updated screencast of the application (in the meantime I've updated it to be resolution independent as I hope to be able to run it on a HTC Diamond Touch, just ordered). The video requires QuickTime.








The concept is that, while you type in the search box, the list gets filtered in function of the english or scientific name. Furthermore (this is a new feature just implemented), blueBill Mobile is able to perform some autocompletion when it makes sense. For instance, if you carefully look at the video when I type in, I'm only entering "a-r-d-a-c" to select "Ardea Cinerea"; or "p-i-e-<space>-a" for "Pied Avocet". blueBill Mobile autocompletes the rest becase in some cases there are no multiple options. It's an important feature for improving the user's experience with a mobile gear: you get the same stuff by typing less.

As per the MVC pattern, it's important to encapsulate this logic in a separate controller, that could be reused by different views; furthermore, it could be easily unit tested (I've posted to DZone a tip on how to run JUnit tests for JavaFX with NetBeans, waiting for it to be approved and published).



First, let's have a look to the model class representing a Taxon (in short, it models the information about a bird species):

package it.tidalwave.bluebillmfx.taxon.model;

import java.lang.Comparable;

public class Taxon extends Comparable
  {
    public-read protected var displayName : String;

    public-read protected var scientificName : String;

    public-read protected var id : String;

    override function compareTo (other : Object)
      {
        return displayName.compareTo((other as Taxon).displayName);
      }

    override function toString()
      {
        return "{displayName} ({scientificName}) ({id})"
      }
  }

public function displayNameGetter (taxon : Taxon): String
  {
    return taxon.displayName;
  }

public function scientificNameGetter (taxon : Taxon): String
  {
    return taxon.scientificName;
  }

public def namePropertyGetters = [displayNameGetter, scientificNameGetter];
Functions and variables defined out of the class braces are equivalent to Java static stuff.

I've omitted stuff from the real project that is not related to what we're discussing about. Basically, the model exposes three properties, two of which are the interesting ones: displayName and scientificName. We also define two functions to adress them, and we put those functions in the sequence namePropertyGetters (whoa, these are closures indeed!).


Now let's have a look at TaxonSearchController:

package it.tidalwave.bluebillmfx.taxon.controller;

import it.tidalwave.bluebillmfx.taxon.model.Taxon;

public class TaxonSearchController
  {
    public var selectedTaxon = bind if (selectedTaxonIndex < 0) then null else filteredTaxons[selectedTaxonIndex];

    public var selectedTaxonIndex : Integer = -1;
     
    public var taxons: Taxon[];

    public var filter = "" on replace
      {
        filteredTaxons = taxons[taxon | matches(taxon, filter)];
        update();
      }

    public-read var autoCompleted = "";

    public var filteredTaxons: Taxon[];

    protected function matches (taxon : Taxon, string: String) : Boolean
      {
        if (string == "")
          {
            return true;
          }

        for (propertyGetter in Taxon.namePropertyGetters)
          {
            if (propertyGetter(taxon).toLowerCase().startsWith(filter.toLowerCase()))
              {
                return true;
              }
          }

        return false;
      }

    protected function update(): Void
      {
        def autoCompletedTry = commonLeadingSubstring(filteredTaxons, findMatchingPropertyGetter());
        //
        // Sometimes it can't find a better auto-completion than the current filter, since it searches the displayName
        // and the scientificName at the same time. In this case, we just ignore the new value.
        //
        if (autoCompletedTry.length() > filter.length())
          {
            autoCompleted = autoCompletedTry;
          }

        selectedTaxonIndex = if (sizeof filteredTaxons == 1) then 0 else -1;
        println("selectedTaxonIndex: {selectedTaxonIndex}")
      }

    protected function findMatchingPropertyGetter(): function (:Taxon): String
      {
        for (taxon in filteredTaxons)
          {
            for (propertyGetter in Taxon.namePropertyGetters)
              {
                if (propertyGetter(taxon).toLowerCase().startsWith(filter.toLowerCase()))
                  {
                    return propertyGetter;
                  }
              }
          }

        return null;
      }

    // some stuff later
 }


This class exposes the following properties:
  • taxons: you have to populate it with the full list of available bird species;
  • filter: the string containing the text you're entering in the search box;
  • filteredTaxons: the species filtered by the filter string;
  • autoCompleted: the auto-completion string guessed by the controller ("" if no guess is available);
  • selectedTaxon: if the filter drilled down to a single species, it is assigned to this variable;
  • selectedTaxonIndex: the index of selectedTaxon, -1 if not available.
The latest four properties are intended to be bound by client code, that will receive a notification of changes.

filter has got a trigger (on replace), that is code executed when the variable changes value. The trigger performs the filtering with the | operator of JavaFX: we can read the first line of the trigger as "filteredTaxons is assigned to the sequence of taxons for which the matches() function returns true". The second line calls the update() function that I'm describing below.
For a number of reasons, this is not necessarily efficient, as filteredTaxons is always entirely scanned. There are a lot of ways to make the selection faster, but I'm not going to do a premature optimization until I see how it performs on a real phone. On a laptop, it's pretty fast with about 1.000 items.
The matches() function performs an iteration over all the property get functions and checks whether the related property starts with the value of filter (case-insensitive). I'd say it's pretty straightforward.
One of the advantages of creating a sequence of property getter functions is that we could easily add new matching criteria by just defining new functions: for instance, other localized names in different languages. The controller would use them in the search without needing any modification.
The update() function computes the auto-completion hint. It takes the sequence of filteredTaxons, the getter of the property that was used for the current selection (more about this later) and calls commonLeadingSubstring(), which has just to find the common substring out of a sequence of string properties.
It's not always possible to find a good autocompletion guess, so sometimes the suggestion is even shorter than the current filter, in which case we ignore it. Please don't under-estimate the importance of that assignment to a temporary variable (autoCompletedTry): since autoCompleted might be bound (that is, client code could automatically receive change notifications) we don't want to assign it a value that could be quickly invalidated (if the length() test fails).
Just to understand the importance of this point - it's not just a matter of avoiding useless updates, it's about not having the application broken. In the real application, a TextBox is updated when autoCompleted changes and in turn it makes a further update to filter (see the code at the end of this post). If you directly assign autoCompleted to a shorter string than filter, you get stuck in the TextBox, as further key strokes are thrown away. Consider this sequence (from a real case): you've typed "cal", you type another "i", the TextBox temporarily shows "cali", then the autocompletion guess fails and returns "cal", and the string in the TextBox goes back to "cal": you're stuck! Binding indeed is powerful, but has a dark side and must be learned with care.
As the last operation, the code checks whether we've got a single selected bird species.
Probably you're still curious about the reason why the computation of autoCompleted can fail. After all we're progressively shrinking a list of items, thus if you have typed "cali", then all the filtered species should start with "cali", right? Well, it would be true if we were filtering on a single set of names; but we're performing the search at the same time on the two sets of names (english and scientific) and thus there could be conflicts. Consider the following pairs selected by the "cali" filter (english, scientific): ("Calandra Lark", "Melanocorypha calandra"), ("Dunlin", "Calidris alpina"), ("California Quail", "Callipepla californica").
Another interesting point is findMatchingPropertyGetter(). It must guess whether the current filter is working on the english or the scientific name, and return the related property getter. Basically, the controller has already got this information, inside the matches() method (look at the repeated code), but we threw it away. One could think about having matches() returning more than a single boolean, but it's not possible because it's used by the | operator while filtering the sequence: that operator wants a boolean. Probably we could just assign a member variable for recalling the information later (this would make the class not thread-safe, but after all this is only executed in the EDT) - but at the moment I think the code is more readable as it is now.

To complete this post, here are the two last missing functions:
    protected function commonLeadingSubstring (taxons: Taxon[], propertyGetter: function (:Taxon): String): String
      {
        if (sizeof taxons == 0)
          {
            return "";
          }

        if (sizeof taxons == 1)
          {
            return propertyGetter(taxons[0]);
          }

        var common = propertyGetter(taxons[0]);

        for (other in taxons[1..])
          {
            common = commonLeadingSubstring(common, propertyGetter(other));

            if (common == "")
              {
                break; // don't waste time in further iterations, "" it's for sure the final result
              }
          }

        return root;
      }

    function commonLeadingSubstring (string1 : String, string2 : String): String
      {
        return if (string1.length() > string2.length())
          {
            commonLeadingSubstring(string2, string1);
          }
        else if (string1 == "")
          {
            "";
          }
        else if (string2.startsWith(string1))
          {
            string1;
          }
        else
          {
            commonLeadingSubstring(string1.substring(0, string1.length() - 1), string2);
          }
      }
The logic is pretty straightforward. The common leading string search is decomposed to pairs of adjacent strings; and the search on a single pair is implemented by recursion.

To conclude the post, this is how the view class binds to the controller (I'm omitting all the UI specific parts):

package it.tidalwave.bluebillmfx.taxon.view;

public class TaxonSearchScreen
{
    public var taxons : Taxon[];

    var filter = "";

    public-read def controller = TaxonSearchController
      {
        taxons: bind taxons
        filter: bind filter
      }

    def autoCompleted = bind controller.autoCompleted on replace
      {
        if (autoCompleted != "")
          {
            filter = autoCompleted;
          }
      }

    def list = ListBox
      {
        items:                 bind controller.filteredTaxons
      };

    def searchBox = TextBox
      {
        text:       bind filter with inverse
      };
}
You have to load taxons with all the available species; then the thing just works, with ListBox being automatically updated with the filtered species, and the TextBox bi-directionally bound (bind ... with inverse) with filter. The bi-directionality is needed because one direction is when you type in the search box, thus commanding to the controller a new selection, the other direction is when the auto-completion is updated.





Sven Reimers and NetBeans Platform to win a 2009 Duke Award

Posted by fabriziogiudici on June 05, 2009 at 10:00 AM | Permalink | Comments (1)

More details will come later, but in the meantime I'd like to let people know that one of the Duke Awards of this year has been granted to Sven Reimers for a really cool project made on the NetBeans Platform. Sven is member of the NetBeans Dream Team and we're all proud of him.

Congratulations to Sven and his team!



Upgraded JavaFX support in NetBeans IDE 6.5

Posted by fabriziogiudici on June 05, 2009 at 07:39 AM | Permalink | Comments (0)

Not only the JavaFX SDK got upgraded, but we have much improved support in the NetBeans IDE - but some things are probably not obvious. Is it the NetBeans 6.5.1 bundled with JavaFX 1.2 the same thing as upgrading your pre-existing copy with the update center? I've posted all the details to DZone.


JavaFX 1.2: still a nasty compiler (NetBeans?) bug for Mobile

Posted by fabriziogiudici on June 04, 2009 at 05:50 AM | Permalink | Comments (7)

A few days ago I discovered a nasty bug with the JavaFX compiler (or NetBeans? or both?) that prevents you from splitting a large project in sub-projects; see item #4 in my post at DZone. I hoped that the bug went away with JavaFX 1.2, but unfortunately it didn't. So I set up a simple test case. You can check it out from here:

svn co -r 40 https://kenai.com/svn/javafxstuff~svn/trunk/ModuleTest

There are two simple projects, Library and Project. Project declares Library as a dependency, thus includes the .jar delivered by Library in the compiler path. Library contains this simple class:
package it.tidalwave.javafxstuff.module.library;

public class LibraryClass
  {
    public var attr = "FooBar";
  }

while Project contains:

package it.tidalwave.javafxstuff.module.project;

import it.tidalwave.javafxstuff.module.library.LibraryClass;

public class ProjectClass
  {
    def xxx = LibraryClass { attr: "BarFoo" };
  }

For the record, Library also contains a Dummy class that is required by NetBeans since for the IDE every JavaFX project must have a main. No big trouble.

Now, if you compile Project setting for both projects the "Standalone" profile, everything goes fine. If you select the "Mobile" profile, the compiler fails with:

compile:
jar:
/home/fritz/Business/Tidalwave/Projects/JavaFXStuff/trunk/ModuleTest/Project/src/it/tidalwave/javafxstuff/module/project/ProjectClass.fx:17: cannot find symbol
symbol  : variable attr
location: class it.tidalwave.javafxstuff.module.library.LibraryClass
    def xxx = LibraryClass { attr: "BarFoo" };
1 error
ERROR: javafxc execution failed, exit code: 1
/home/fritz/Business/Tidalwave/Projects/JavaFXStuff/trunk/ModuleTest/Project/nbproject/build-impl.xml:145: exec returned: 255
BUILD FAILED (total time: 2 seconds)

That is, Project can see classes from Library, but can't see their (public) attributes. I discovered the bug with JavaFX 1.1 (necessarily on Windows for having the Mobile profile), but I can reproduce it on Linux and JavaFX 1.2 (with this combination you cannot run the Mobile emulator, but the compiler should work).

This, of course, completely jeopardizes the capability of partitioning a large project in smaller components, at least for the Mobile profile. For me it's really a critical bug.

Not yet JavaFX Mobile on Linux?

Posted by fabriziogiudici on June 04, 2009 at 05:25 AM | Permalink | Comments (6)

I've just installed the NetBeans 6.5.1 + JavaFX 1.2 pack on Linux Ubuntu. No problems for developing and running applications with the standard profile. But when I tried to run with the "mobile" profile, I first got an exception, NetBeans being unable to run the "preverify" tool. Easily fixed with a chmod a+x. Nevertheless, the mobile application can't run because of:
midp-run:
/home/fritz/Business/Tidalwave/Projects/blueBill-Mobile/trunk/src/FX/blueBill-mobileFX/nbproject/build-impl.xml:196: Current platform does not include mobile device emulator necessary for the execution.
BUILD FAILED (total time: 18 seconds)

Going to the project property and trying to select the device for the emulator, I get a drop down box with the "Please wait..." message staying forever. Hmm... should I guess that we can't develop with JavaFX Mobile on Linux yet?





Interview with Dennis Reedy on cloud computing with Rio and Elastic Grid (BOF-4638)

Posted by fabriziogiudici on June 04, 2009 at 01:52 AM | Permalink | Comments (3)

I met Dennis Reedy five years ago (boys, how fast time flows!) when he participated in one of the most interesting projects I've done so far, the Real Time Telemetry Service (RTTS) for Formula 1 cars, by Magneti Marelli Motorsport and Sun Microsystems Italy. Dennis' contributions were fundamental for the success of the project, both because he is the author of Rio, a platform based on Jini (now Apache River) that we used for building RTTS, and also thanks to his great experience as an architect of “critical systems”. If you look at Dennis' CV, you'll find quite a deal of “cool stuff” (yet real-world projects).

Just for putting things in context with today's trends (everybody is talking about clouds at CommunityOne and JavaOne), I learned for the first time concepts such as “grid” and “dynamic provisioning” thanks to Dennis. Actually, Dennis is going to have a BoF at JavaOne, named “Cloud Computing and NetBeans™ IDE Enable Army Research Lab’s Next-Generation Simulation System”, BOF-4638, Wednesday, June 3, 7:45PM, at Esplanade 300.

I'm going to mitigate a bit the pain of not being in San Francisco and having a drink with Dennis by interviewing him on my blog.

Q. For people that don't know you, Dennis, please introduce yourself.


A. Fabrizio, thanks for giving me the opportunity to tell you about what we are presenting out here at JavaOne. I am presenting with Ron Bowers from the Army Research Laboratory in Aberdeen, MD. Ron is the lead architect for MUVES3.

Q. Well, Dennis, I see that you're still involved in cool stuff. Tell us something about this project.

A. The MUVES3 project is a simulation environment for evaluating the survivability of US Army systems to ballistic threats (bullets, artillery rounds – things that basically go boom), and the lethality of US Army weapons against enemy vehicles.

Q. Which are the key technologies used to build the cloud infrastructure behind MUVES 3?

A. The MUVES3 project uses a dynamic distributed architecture built on top of the Rio project. Rio provides the core service's architecture, real time provisioning, management and deployment for MUVES3. We rely quite heavily on service associations and the policy approach that Rio brings.

MUVES3 also generates a tremendous amount of data. We have a persistent management approach that allows the representation of data in different states as it moves through the system; for fast access to in-flight data, JavaSpaces is used (we use the stock Outrigger service from Apache River); Long Term storage is accomplished using Derby, and for data that has not been committed to long term storage we use Apache Active MQ.

For moving to the cloud we are using Elastic Grid (EG) (LINK).  While we cannot run MUVES3 in the public cloud, we are Cloud Bursting the testing clusters to EC2 using EG. EG provides the fabric that enables the on-demand provisioning of the application in the cloud seamlessly.

Q. Glad to see that Rio still rocks. MUVES 3 is related to national security, so it clearly runs on some private US Army network; but Amazon's Elastic Compute Cloud / Elastic Grid were chosen for the test deployment. What challenges have you faced in pursuing cloud computing for this effort?

A. First was getting management approval :) Besides that, we have organized the project to have the application infrastructure from the sensitive algorithms and code. This organization has produced a project called Gomez (on java.net as a sub-project of the Rio project). This allows us to verify and validate the key infrastructure capabilities and scalability.

Although we achieved  architectural separation, we faced some hurdles of being able to run in the cloud.

We did not want to build an Amazon Machine Image (AMI) every night. This would have been a real administrative burden.
We wanted to avoid developing special code and testing framework for cloud deployment/orchestration. Ideally, transparently switch from LAN-based deployment to the cloud.

We absolutely needed preserve the dynamic distributed semantics architected in the system: Service selection strategies and Dynamic discovery semantics are a key part of the system.

Elastic Grid builds on the capabilities that Rio provides for LAN based deployments and really eased the move to the cloud. With the current approach we can cloud burst using the EG AMI, deploy and run the system across multiple concurrent testing clusters on EC2.

Q. The US Army is a very peculiar customer; should people really start studying clouds seriously, for more “mundane” customers?

A. ARL has actually been a leader in computing for decades, ever hear of the ENIAC? ;) All kidding aside, cloud computing approaches seem to be a key element of programs going forward in the public sector.

I do think that cloud computing approaches should be assessed for use. From a cost-cutting perspective it's really a no-brainer. However, you really need to assess what the real impacts of running your application in the cloud are.

Q. Well, I see that you used NetBeans RCP (a.k.a. NetBeans Platform) as the framework for the desktop clients. You know that I'm a big fan of the NetBeans Platform, so I'm happy to see it ;-) What is your experience with this product? Why did you choose it over alternatives?

A. NetBeans RCP is used as the framework for UI development and aggregation of visual components. As the standard bearer of IDEs in the Java community (java.net) NetBeans provides a standardized and accepted platform to base development on.

One of the reasons the project chose NetBeans was the fast form development and easy deployment via JNLP.  The project team really loves that NetBeans is extremely well supported by the community as well.

Q. Will you work further on MUVES 3? What are the next things you're going to do?

A. I have really enjoyed my time spent with the MUVES3 project team to date. I do hope for continued involvement and success with the project, there are a number of significant and interesting things to do.

Now that we have begun the effort to use a cloud computing approach we still need to look at ways to aggregate and visualize the system both from a real time view and also from a post-mortem aspect. Being able to view how the system is operating, what it's boundaries are and where bottlenecks are (or may occur) are key elements to the survivability of the system.


Thank you Dennis. Let's hope to meet for JavaOne/WhateverWillBe 2010.


First webcast of blueBill-Mobile (JavaFX)

Posted by fabriziogiudici on June 03, 2009 at 04:01 PM | Permalink | Comments (4)

I've almost finished the port of blueBill-Mobile to JavaFX 1.2. Basically the only issues still open are related to layout, as there are a few things that have changed and I have to understand better. In particular, one of the broken things is the navigation facility that has been designed with "sliding" screens, à la iPhone (with navigation buttons that contextually appear on the screen edges); for the webcast below, I've temporarily replaced it with a fade in / fade out approach. I'm waiting for fixing this final issue before releasing the source. The webcast below requires QuickTime.


Basically, you're seeing the following features:
  1. browsing for a bird species
  2. opening an "info" screen, where photos at full screen can be choosen
  3. viewing a map with nearby recent observations of a given species (this works by connecting to a REST service of blueBill Server, which is currently mocked by an instance serving dummy data)
  4. inserting a geo-tagged observation of a bird (that gets published to blueBill Server again via REST)
  5. viewing a map of fellow-birdwatchers in the nearby surroundings, in real-time (a similar feature to Google Latitude); even in this case, the prototype really connects to a server, but it gets dummy data.
One of the things that I realized only after putting some real photos into the demo is that it's not trivial to render the same photo in two different modes (landscape and portrait) making sure that the subject is still well framed. Basically, this requires annotating the photos with the information about the subject placement, so the application can adjust the frame adaptively. It's easy to do in JavaFX, but it will require some time for me to add the annotation to the photos. That's why you're still seeing some photos brutally cropped at the right or the bottom side.

Now I'm longing to hear from J1 the announcement of the JavaFX player for MSA (JSR-248) mobile phones or such, so I can run this ASAP on a real phone. Also because I'm working for having this thing used for real, on the field.


And this year the bug...

Posted by fabriziogiudici on June 02, 2009 at 09:41 AM | Permalink | Comments (1)

Nandini Ramani, director of JavaFX Engineering, just showed a demo, with Jonathan on the stage. It's the new designer tool for JavaFX. This year the bug was only with the projector (people couldn't see the first few seconds of the demo). All the rest was fine. A sign of JavaFX being mature? ;-)


JavaFX 1.2: lots of new good things, some price to pay

Posted by fabriziogiudici on June 02, 2009 at 03:22 AM | Permalink | Comments (1)

So, JavaFX 1.2 is out and you can download it from javafx.com (note: when you press the "Download now" button you'll still see 1.1.1, just click on the bottom link "See downloads for other platforms"). Yes, there's the Linux version too ;-) And Solaris too.

The news items are in a good number, not only at level of APIs (whole new packages, including - thanks God - various types of controls), but at the language level too. Multiple inheritance has gone away (excellent!), replaced by explicit mixin support; you have to use commas to separate elements in sequences; you can't any longer shadow variables in nested blocks, and so on. I won't repeat here the very good change list that Steve on Java already prepared: have a look at it, it has been extremely useful for me.

The mixin support sounds as one of the most interesting things at language level - but I couldn't find yet a document explaining how it is implemented (there are still broken links on JavaFX sites that point back to 1.1 docs) - I just supposed it is a classic mixin and just put the "mixin" keyword in the few cases where I needed it. Of course I'll go deeper in it when the docs are available.

The price to pay is that, most likely, your application developed with JavaFX 1.1(.1) won't ever compile. blueBill Mobile didn't. After a few hours I got it to compile (unfortunately, the thing needs longer than expected, since NetBeans support hasn't been updated yet and the editor gets even more messed up). The compiler seems much more stable, but I was however able to crash it once :o)

After fixing the source, the application still doesn't work. There are nodes that aren't immediately visible, and in one of the screens where there is a list of items I first got a StackOverflowError, later - after some change - an OutOfMemoryError. Hmm... It is to be said that the implementation I wrote of the List was very quick, as I bet that new components were coming with 1.2. So I think I'll try first replacing my old, home-made controls with the new ones. Also, I'm also aware that there have been changes in the behaviour of nodes and I'm getting some compiler and runtime warnings that I have to investigate on.

Stay tuned for the progress. Once I fix blueBill Mobile for JavaFX 1.2 I'll make it available for playing around. And of course, if you're at JavaOne, don't miss JavaFX talks.



Interview with lambdaj creator - meet Mario Fusco at the Java.Net Community Corner

Posted by fabriziogiudici on June 01, 2009 at 11:08 AM | Permalink | Comments (3)

Functional programming has been a hot topic in recent times, at the point that a number of “new” languages such as Scala, Haskell or Erlang have been brought to the attention of people (at least, those attending conferences or reading blogs). BTW, the topic is not new as one might expect: for instance, look at this DDJ article back from 2005 – but, as often happens, new topics require some time to gain the attention of masses.

Indeed, I think that functional programming has got some pretty neat stuff and, carefully used, could be a good way to improve the quality of your code. Functional programming is indeed the correct topic to think of when you hear about “closures in the Java language”. The basic difference is that “functional programming” is the concept, that you should learn and master, while “closures” are just a tool to implement it. One of the possible tools, and for this reason it isn't really important as the concept itself. In fact, a number of existing solutions for the old, good, plain Java, that of course don't use closures, have been developed (just a random reference to an existing product, Functional Java).

I've been interested in using a few of functional stuff in Java since some time, but honestly this topic has slipped below other higher priorities so far. One of the first places where to I'd use functional programming is the collections area (lists, maps, sets, whatever), as I find myself often re-writing similar code to extract stuff out of a list, or index a List into a Map, or similar stuff. One of the issues I didn't link with solutions such as Functional Java is that they are a replacement of the java.util.* classes such as List or Map. Indeed I've always gave a high value to the Java Collections library, since it is a shared implementation of common stuff: you use List, Map and whatever and there are pretty high chances that whatever third party's library you're going to integrate in your project also use them. Having to replace them, and introduce adapters, never sounded good to me.

MarioFusco.jpg But now, it looks as you have another choice. A new library, named lambdaJ, offers a neat solution to work in functional way with the existing java.util.* stuff. To learn more about LambdaJ I'm interviewing Mario Fusco, the author, from JUG Lugano (but, hey, Mario is italianissimo ;-). Before starting, I'd like to point people that are going to attend JavaOne 2009 that Mario will speak in person about LambdaJ at the Java.Net Community Corner on Tuesday at 11:30.


Q. Ciao Mario. First, please introduce yourself. Where you live, where you work and what are your primary interests?

A. I am a Java programmer and architect with a more than decennial experience. I worked in Italy, Germany and currently in Switzerland being involved in (and often leading) many projects in different fields like advertising, e-commerce and insurance.
My main interests about Java technologies are in multi-threaded programming and distributed computing, performance optimization, the most important enterprise level servers and frameworks, functional programming and the emerging Java compatible languages like Scala, Groovy or Jruby.
I am also one of the leader of the Java User Group in the town of Lugano where I live since 3 years.

Q. Please introduce lambdaJ. As you're a pretty practical person, I bet you wrote it as a solution to a problem you found in your job. Am I right?

A. Yes, you're. We were working on a project that had a very complex data model and we found our  software was full of tons of pieces of code that did almost the same: iterating over collections of our business objects in order to perform basically the same set of more or less complex tasks.

We also found some of those loops were particularly hard to read. Developers spent more time trying to figure out what a given loop did than to write the loop itself.

For this reason I started writing some utility methods and implementing a small DSL at the purpose to improve the code readability. The guys of my team liked this approach and felt comfortable with it almost immediately.

But when they start asking “How could I wrote this in your collections language?” or “Could you add that feature to your collections thing?” I realized I was writing something that could have a very large and general applicability field. So I decided to refactor it in an independent library outside the original project.

Of course the last step was to find a name for that library, since in my opinion “the Mario's collection thing” was not good enough. I choose lambdaj since to develop it I used some functional programming techniques that in turns derive from the lambda-calculus theory.

Q. Can you give us some examples of how lambdaJ will improve our code?

A. There are mainly 2 idea behind lambdaj: the first is to treat a collection as it was a single object by allowing to propagate a single method invocation to all the objects in the collection as in the following example:
forEach(personsInFamily).setLastName("Fusco");
The second is to allow to define a pointer to a java method in a statically typed way in order to call the API offered by lambdaj using that method as an argument as it follows:
List<Person> sortedPersons = sort(persons, on(Person.class).getAge());
In this last case if you compare this statement with the piece of code that you have to write to achieve the same result using the API of the Java Collection framework:
List<Person> sortedPersons = new ArrayList<Person>(person);
Collections.sort(sortedPersons, new Comparator<Person>() {
    public int compare(Person p1, Person p2) {
        return p1.getAge() - p2.getAge();
    }
});
I think the improvement is evident in both effectiveness while writing and clarity while reading it.

Q. It is definitely much better! Let me open a small, personal bitching parenthesis: IMHO this demonstrates that people can improve the way they code more looking at their skills than complaining about missing features in the language. Mario has obtained that “done-in-one-line-of-code” thing that seemed to unavoidably need closures. Closed the personal parenthesis. Can you give us some other example? For instance, a typical thing that I often do is retrieve a List of items (e.g. from a database query) and then copy them into a Map, indexed by a certain property, so I can speed up further operations (such as the lookup by a UI or such).

A. Also this task could be made very easy by using lambdaj as it follows:
Map<String, Person> personsByLastName = index(persons, on(Person.class).getLastName());
Actually lambdaj can do much more. In this example there's a big likelihood that in the list of person there could be 2 or more persons with the same last name. In this case in the indexed map you will lose all the persons having a duplicate last name. Probably what you need instead is to group the persons by their last name. Even in this case lambdaj can help you as it follows:
Group<Person> personsByLastName = group(persons, by(on(Person.class).getLastName()));
Then to find the persons in the Group with a given last name you can than write:

List<Person> personsInMyFamily =  personsByLastName.find(“Fusco”);

Note that to achieve the same result in plain java you should write something like that:

Map<String, List<Person> > personsByLastName = new HashMap<String, List<Person>>();
for (Person person : persons) {
    String lastName = person.getLastName();
    List<Person> personsWithGivenName =  personsByLastName.get(lastName);

    if (personsWithGivenName == null) {
        personsWithGivenName = new ArrayList<Person>();
        personsByLastName.put(lastName, personsWithGivenName);
    }
    personsWithGivenName.add(person);
}
List<Person> personsInMyFamily = personsByLastName.get(“Fusco”);
Once again the difference is evident. Don't you think so? In the end lamndaj groups are even more powerful since you can group your collection by more than one property. For example you could want to group you list of persons by their last name and then by their first name. In lambdaj you could do that as it follows:
Group<Person> personsByLastName = 
    group(persons, by(on(Person.class).getLastName()), by(on(Person.class).getFirstName()));
Q. Great! One more example, please. We've shown a couple of “stateless” manipulations. What about I have to compute the sum of a certain property in a list of items?

A. You could achieve this result in lambdaj in two different ways:
int totalAges = sum(persons, on(Person.class).getAge());
or
int totalAges = sumFrom(persons).getAge());
that, as you can see, reflect the two main ideas on which lambdaj is built. Actually I think that the sumFrom() method can be effectively used in another very common case. Suppose you have a list of beans with the properties a, b and c that need to be showed in a table. What you usually do is to bind each bean in the list to a given row in the table and popolate the cells corrisponding to the columns A, B and C by invoking respectively bean.getA(), bean.getB() and bean.getC(). Well, if you now need to display a row with the totals of that values you could do something like that:
Bean totalizerBean = sumFrom(beans);
and so you can populate the row of totals of your table just binding the totalizerBean as any each other bean by invoking totalizerBean.getA(), totalizerBean.getB() and totalizerBean.getC().

Q. What about performance? And easiness of debugging? You're clearly using dynamic bytecode manipulation and I know that some people, when they hear about CGLIB and other similar stuff, get worried.

A. Of course there is a trade-off in using lambdaj and in some cases performance could be an issue. I tried to analyze them by comparing the time needed by lambdaj to achieve a given task with the one spent to have the same result in an iterative mode. I empirically found that lambdaj is about 3 times slower that for each time it needs invoke a method on an object proxied by lambdaj. It means that in the former example you could expect that lambdaj is 6 times slower to sort the given collection of Person since it needs to use that mechanism twice for each Person comparison.
Actually this result has been measured in the case when Person is implemented as a Class and then by using CGLIB. If Person was an interface lambdaj automatically switches to use the native Java proxy mechanism and I expect that in this case performance could be a bit better even if I haven't already tested it. Anyway even if that couldn't sound so good, I guess that in the biggest part of the software you can write the performance penalty you have to pay by using lambdaj is really small. And I hope the improvements in your code readability and maintainability overcome it.

Q. Fair. For what I see, performance shouldn't be a big trouble here. From an architectural point of view, we're not saying we're replacing database queries with ten or hundred of thousands of records; SQL/JPQL/whateverQL is still the best option here. I'm longing to try lambdaj in blueMarine, and for what I can see in advance it won't hurt my performance in a sensible way. In any case, probably the closure guys could have still an argument if they absolutely need the maximum speed (but - hey - I'd like to know how faster is a closure-based solution). And don't forget that lambdaj is just a new thing, so Mario and the other authors could find some optimization in future. By the way: what are your future plans? Do you have a roadmap with new features for lambdaj?

A. Honestly there isn't any well defined roadmap. As I told before lambdaj is the side product of a project on which my team and I are working. So, at the moment, it contains more or less only the features that we found immediately useful for us during the development of that project. I'm sure that there a lot of outstanding features that could be implemented following the same philosophy. That's why I would like to have the help and suggestions of the java developers community in order to define which are the missing features in lambdaj.


Thank you Mario and enjoy JavaOne!

NetBeans 6.7 RC1 - and JIRA support (beta)

Posted by fabriziogiudici on June 01, 2009 at 09:05 AM | Permalink | Comments (0)

NetBeans 6.7 RC1 has been announced just a few hours ago. I've just downloaded and installed, and the first thing I searched for is the integration with JIRA. In fact, NetBeans 6.7 comes with Kenai integration, which - among other things - mean also the capability of interacting with an issue tracker from inside the IDE. This is not only to avoid opening Firefox - for instance, when you perform a commit to Subversion, you have the chance of contextually changing the status of an issue. Integration with Bugzilla was already present in 6.7 beta, and JIRA support promised for the "future". So, I immediately went to the "Service" tab and opened the dialog to create an issue tracker... but there's only the option for Bugzilla. But don't dispair. Go to the "Tools / Plugins" pane and, voilà, there is a pair of plugins for adding JIRA support. Clearly, since the guys didn't directly bundle JIRA support into the IDE, this means that the quality is not production yet... but it's worth a try. After a few minutes, I was able to configure and install my own JIRA instance (Tidalwave JIRA). Querying for issues seems to work, and the commit box has got the option to update the issue tracker. I haven't done any serious testing, but things sounds promising...

NetBeansScreenSnapz001.png

The configuration dialog for adding a JIRA issue tracker.



NetBeansScreenSnapz002.png

Querying the issue tracker.



NetBeansScreenSnapz003.png

Changing an issue while committing changes.



Submitted a candidate to the JavaFX Coding Contest...

Posted by fabriziogiudici on May 29, 2009 at 10:32 PM | Permalink | Comments (2)

... as usual, I got to the very last minute. Too bad. The idea of the thing dates several months back (but it wasn't to be made in JavaFX until the contest has been revealed). It's a mobile application - which made me ever scream more and more because of the additional bugs in the JavaFX Mobile Emulator (not to say I had to use Windows for it... indeed the thing has been developed with Mac OS X as an applet, and only today moved to a Windows machine, where I fixed the parts not compatible with MIDP).

Too sleepy now. Next post will be a more detailed impression about this job, now that for the first time I've moved to a real JavaFX application (previously I only prepared a few demos). As soon as I verify it doesn't hurt the contest rules, I'll also blog about the code. Also because there are a few reusable parts inside (such as a reasonably flexible map viewer implementation - compatible with OpenStreetMap, Microsoft Visual Earth and possibly others), of course entirely developed on the "mobile" profile (unlike Joshua's demo which is a wrapper upon SwingX JXMapViewer).








Cancelling my JavaOne :-(

Posted by fabriziogiudici on May 29, 2009 at 10:22 AM | Permalink | Comments (6)

Unfortunately, a health trouble happened a few days ago prevented me from taking the plane. No Community One, no Java One, no friends, no photo trips this year. Of course, also my Community One talk about "NetBeans™ Platform + Wicket = Reusable Components and Modular Web Apps" has been cancelled. I'm sorry for that.



Ten days to Community One and JavaOne: my talk and my plans

Posted by fabriziogiudici on May 22, 2009 at 07:06 AM | Permalink | Comments (3)

In ten days the mother of all Java events will be held in San Francisco, anticipated by the Community One. As usual, tons of interesting speeches - completely involved in some heavy work, I was forgetting that you have to pre-register for individual sessions in order to be sure of having a place inside a room. The conference planner was pretty good this year and I was able to work out an agenda in a short time (also because this year I'm probably more focused on some topics than in the past).

So you can find my agenda below. Above all, let me recall you that I'll have a speech at Community One:

(S304067) NetBeans™ Platform + Wicket = Reusable Components and Modular Web Apps

Please read carefully the title: I'm talking about NetBeans PLATFORM, not NetBeans IDE. I'm not going to show you how to build a Wicket application using the NetBeans IDE, but how to build a modular, componentized webapp using pieces of the NetBeans Platform. What does mean "modular, componentized"? Many things, including:
  • Decomposing the application in modules with their own version number and inter-dependency declarations
  • Having menus dynamically built by looking up the modules installed on the system (which is great for branding and customizing deployment)
  • Being able to update a deployed application with an update center
  • Easilly reusing stuff from existing desktop applications (for instance, I'll show you a web application that uses a good number of code modules from blueMarine).
After looking at the first point, a number of you are probably thinking "isn't this what OSGi is for?". Right. While the NetBeans Platform isn't OSGi, it is getting compatible with OSGi. At the moment I don't feel a technical reason for which my application would be better with OSGi, but I realize OSGi is an important standard that is getting more and more spread. So, in my roadmap there's the OSGification of my web application (keeping of course the NetBeans Platform and the other stuff). As I've said many times, I'm a OSGi newbie, but in these days I'm working hard to have at least a little demo including OSGi for my talk. I can't guarantee about it, but I'm trying. For sure, it's something I'll be showing after the summer break.

See you at C1/J1!



PS Sorry, links below are not functional.

Monday, Jun 01
09:00-10:30Hall B-C, Moscone
CommunityOne General Session Seats Available
11:50-12:40Hall E 135, Moscone Remove From Schedule (S304065) Test Your Product on Multiple Machines in Parallel with HudsonSeats Available
13:40-14:30Esplanade 300, Moscone Remove From Schedule (S304051) Your Code, Your Community . . . Your Cloud: Project KenaiSeats Available
14:40-15:30Gateway 104, Moscone Remove From Schedule (S311528) Practical Cloud Computing PatternsSeats Available
16:00-16:50Esplanade 300, Moscone Remove From Schedule (S304040) Social-Enable Your Web Apps with OpenSocialSeats Available
17:00-17:50Esplanade 302, Moscone Remove From Schedule (S304067) NetBeans™ Platform + Wicket = Reusable Components and Modular Web AppsSeats Available
Tuesday, Jun 02
08:30-10:30Hall B-C, Moscone
Tuesday Morning General SessionSeats Available
10:50-11:50Hall E 133, Moscone Remove From Schedule (TS-6802) Hadoop, a Highly Scalable, Distributed File/Data Processing System
Implemented in Java™ Technology
Seats Available
12:10-13:10Esplanade 307-310, Moscone Remove From Schedule (TS-4308) Architecting Robust Applications for Amazon EC2 Seats Available
13:30-15:00Hall B-C, Moscone
Tuesday Afternoon Technical General SessionSeats Available
15:20-16:20Hall E 135, Moscone Remove From Schedule (TS-3817) Google App Engine: Java™Technology in the CloudSeats Available
16:40-17:40North Hall 124, Moscone Remove From Schedule (TS-5494) Getting the Most from the Designers with the JavaFX™ Production SuiteSeats Available
Wednesday, Jun 03
08:30-09:30Hall B-C, Moscone
Mobility General Session (Part I)Seats Available
09:45-10:45Gateway 104, Moscone Remove From Schedule (TS-5301) Continuous Integration in the Cloud with HudsonSeats Available
11:05-12:05Esplanade 301, Moscone Remove From Schedule (TS-4230) Enterprise Build and Test in the CloudSeats Available
13:30-14:30Hall E 134, Moscone Remove From Schedule (TS-4966) Upgrading OSGiSeats Available
14:50-15:50Esplanade 307-310, Moscone Remove From Schedule (TS-5295) Designing and Building Security into REST ApplicationsSeats Available
16:10-17:10Esplanade 300, Moscone Remove From Schedule (TS-4861) Pro JavaFX™ Platform: RIA Enterprise Application Development with JavaFX TechnologySeats Available
17:30-18:30Hall B-C, Moscone
Mobility General Session (Part II)Seats Available
19:45-20:35Esplanade 300, Moscone Remove From Schedule (BOF-4638) Cloud Computing and NetBeans™ IDE Enable Army Research Lab\2019s Next-Generation Simulation SystemSeats Available
Thursday, Jun 04
08:30-09:15Hall B-C, Moscone
Thursday Morning General SessionSeats Available
09:30-10:30North Hall 124, Moscone Remove From Schedule (TS-5578) The New World: JavaFX™ Technology-Based UI ControlsSeats Available
10:50-11:50Esplanade 300, Moscone Remove From Schedule (TS-5082) Matchmaking in the Cloud: Hadoop and EC2 at eHarmonySeats Available
13:30-14:30Esplanade 307-310, Moscone Remove From Schedule (TS-4005) The Web on OSGi: Here’s HowSeats Available
















My demo at All4Web

Posted by fabriziogiudici on May 09, 2009 at 08:14 AM | Permalink | Comments (13)

All4Web has been a pretty promising prime and attendees gave us a very good feedback. For sure we will make another in future, even better.

I gave a quick demo of a JavaFX application, a very simple prototypical Contact List - the same simple application was developed by other speakers in Flex, Silverlight and AJAX. It was a special session that we named "RIA vs RIA", a sort of RIA shootout, that we gave for the first time 1.5 years ago (but at the time without Silverlight).

In the end everything was fine, even though the night before the demo, just before going to bed, I accidentally 'rm-rf'ed my code - of course from the command line, so no way of recovering it. Recently I found myself thinking that I should put under Subversion also my quick demos... when you have a good idea, implement it quickly! Fortunately my talk was in the afternoon, so I was able to rewrite it from scratch in the morning, with just a few minor bugs.

In any case I've just created a new project under Kenai, JavaFXStuff. Rather than a real project, it's just a source repository where I'll put some random demos about JavaFX. The All4Web demos can be checked out with

svn -r 11 co https://kenai.com/svn/javafxstuff~svn/trunk/ContactList/src/ContactList

The demo can be launched as a regular Desktop application:

https://kenai.com/svn/javafxstuff~svn/trunk/ContactList/www/ContactList.jnlp

or as an applet embedded in a HTML page:

https://kenai.com/svn/javafxstuff~svn/trunk/ContactList/www/ContactList.html

I'll work a bit on this demo in future, as at the moment the demo is very rough - basically I don't like at all the fact that, as many other demos around, the UI code is just a single file with poor separation of concerns.



Oracle to keep on Sparc and Sun hardware development

Posted by fabriziogiudici on May 08, 2009 at 02:39 PM | Permalink | Comments (4)

Oracle has started giving out some official information about its strategies with Sun. Larry Ellison just told us that Oracle is committed to keep on Sparc and Sun hardware development (cited by many, e.g. Reuters). So, we can start throwing in the basket the first half of wrong forecasts by "experts" that surely predicted the dismission of that compartment... Let's hope Oracle will give us some more news about the single software product strategies.
"We are definitely not going to exit the hardware business," Ellison said in an email interview with Reuters. "If a company designs both hardware and software, it can build much better systems than if they only design the software. That's why Apple's (AAPL.O) iPhone is so much better than Microsoft (MSFT.O) phones."




Reminder: All4Web is free and there's a Sun certification discount

Posted by fabriziogiudici on May 04, 2009 at 02:29 PM | Permalink | Comments (0)

This post relates to an event in italian language, so I'm going to post in Italian.

Vi ricordo che Venerdì 8 Maggio, presso l'Università di Milano Bicocca, si terrà l'evento gratuito All4Web: una giornata dedicata alle quattro maggiori tecnologie per RIA (Java/JavaFX, Adobe Air/Flex, Microsoft Silverlight e AJAX) - evento realizzato dalle rispettive comunità, da un'idea di Lorenzo Sicilia. La track Java è affidata alle amorevoli cure di Marcello Teodori (Spring) e mie (JavaFX).

Non solo l'evento è gratuito, ma Sun Italia e JUG Milano hanno preparato un'offerta speciale per i partecipanti: i voucher per le certificazioni a 40 €! Maggiori informazioni sul volantino che allego.

Se volete venire, possibilmente registratevi sull'apposito sito.



The Observation API (hey, it's not the Observable pattern)

Posted by fabriziogiudici on April 29, 2009 at 04:25 PM | Permalink | Comments (6)

As I said in February, I'm going to post on my blog a series about the use of Semantic Technologies and how they are being used in some of my projects.

Today let's start giving a small domain model and then design a related abstract API. In the next post I'll show you how to implement it on the top of a RDF triple store.

Models

The API is designed to manage a set of "observations" (of whatever, by anybody, etc... let's keep it generic in order to respect the "AAA slogan": Anyone can say Anything about Any topic), so I'm calling it "the Observation API". 

Let's introduce the key abstractions:
  • An Observer represents entities capable to make observations. It may be a physical person, or a device, or anything else makes sense.
  • An Observation is made at a certain time and Location, by one or more Observers and is composed of one or more ObservationItems.
  • An ObservationItem pairs an Observable with a Cardinality.
  • An Observable has no special properties and can be anything.
  • A Cardinality may be a single integer number, a close or open range of integers (e.g. "between 10 and 20", or "more than 5"), or "undefined".
  • An ObservationSet is a set of Observations.
  • A Source is where a certain datum comes from (i.e. who or what provided it, inserting into the database).
Domain Model

All of the above concepts are going to become classes, so I'm now referring to them with the code typo convention. Observer, Observable, Location and Source have a single property exposed through getDisplayName(), that is the identifier used for rendering the object in a UI. Applying some common patterns, we add a few more classes for the solution model:
  • An ObservationManager provides way to retrieve and create ObservationSets.
  • A Finder is used to perform various queries.
  • An Observation.Builder provides ways to create new Observations.
The only architectural dependency introduced in the API is related to the use of components à la NetBeans Platform, whose lookup logic is hidden behind a ObservationManager.Locator. As annotations has been recently introduced for dependency injection in the Platform, this class will be removed at some point in future, making the API mostly technology-agnostic.

UML Diagram
(Click on the above diagram for a larger version)

Scenarios and examples

While I have anticipated that this API is very generic, for the following scenarios I'm giving the context of birding (or birdwatching) - which BTW is the reason for which I've designed it.

First of all, code dealing with the Observation API shoud create an ObservationSet:
ObservationManager observationManager = ObservationManager.Locator.findObservationManager();
ObservationSet temporarySet = observationManager.createObservationSet();
// or
ObservationSet persistentSet = observationManager.createObservationSet(backingStore); // backingStore is a generic Object, architecture dependent
ObservationManager provides a convenience method findOrCreate() for creating various entities of the API, even though they can be also instantiated in other ways - let's remember that things such as Observer, Observable, Location and Source are pretty generic stuff, and their implementation could come from some other APIs. This is a very important point: in a real application I don't expect ObservationManager.findOrCreate() to be really used alone, if not for ancillary, simple entities, because in the real world I'll mostly need some concrete entities with their own properties and behaviour. But the simple use of this method is ok for tests (and examples).



Here it is how I could create a new Observation of about 100-150 flamingoes and 23 spoonbills:
Date when = dateFormat.parse("29-04-2007");
Location castiglione = observationSet.findOrCreate(Location.class, "Castiglione della Pescaia", EmptyInitializer.instance());
Observer fabrizio = observationSet.findOrCreate(Observer.class, "Fabrizio Giudici", EmptyInitializer.instance());
Observable flamingo = observationSet.findOrCreate(Observable.class, "Flamingo", EmptyInitializer.instance());
Observable spoonbill = observationSet.findOrCreate(Observable.class, "Spoonbill", EmptyInitializer.instance());

Observation observation = observationSet.createObservation().
date(when).
location(castiglione).
item(spoonbill, Cardinality.valueOf(23)).
item(flamingo, Cardinality.rangeOf(100, 150)).
observer(fabrizio).
build();
Note how a fluent interface has been used for specifying all the data items for building an Observation. If this operation is made against a persistence ObservationSet, the inserted data are made persistent too (eventually at the next transaction commit; details are opaque to the API). The only required parameter for findOrCreate(), besides the entity type, is a string which represents the display name of the entity; if an entity of the given type and display name already exists, it will be returned and not created. A third argoment is an implementation of the interface:
public interface Initializer<T> 
  {
    public void initialize (T entity);
  }
that is responsible for initializing the entity status if it is created from scratch; this will be discussed in a future post, in the meantime you just need to know that EmptyInitializer.instance() returns a "no op" initializer that does nothing.

Now, how to perform queries? The starting point is the ObservationSet of course:

List<Observable> observables = observationSet.find(Observable.class).
                                              sort(SortCriterion.DISPLAY_NAME).
                                              from(100).
                                              max(20).
                                              results();


ObservationSet.find(Class<T>) returns a Finder<T>, which encapsulates the query logic. It also provides a fluent interface to specify some generic (optional) parameters of the query; in the above example the sort criterion and the "paging" of results (from the 100th, for a max of 20 items), which is easily integrable in user interfaces supporting paging. You can specify criterion for a few generic attributes of an Observation (e.g.  DISPLAY_NAME, DATE, LOCATION, OBSERVABLE). There are no more things to specify here as we are still dealing with generic entities. 
Finder
s are used in other places of the API too: for instance, you can do:

Observable observable = ...;
Finder<ObservationItem> finder = observable.findObservationItems();

or
Location location = ...;
Finder<ObservationItem> finder = location.findObservationItems();
that is, you can query single entities for the related concepts.

Enough for today. Some resources:


BetterBeansBinding: building with Eclipse

Posted by fabriziogiudici on April 28, 2009 at 05:50 AM | Permalink | Comments (0)

Since BBB is build with Maven, it is pretty IDE agnostic. Specific instructions to build it with different tools are at the bottom of the Sofware Factory Wiki page. You can open and build the project with a single operation using NetBeans and IntelliJ IDEA. I believe it's possible to do the same with Eclipse - I'm not an expert of it, but asking for help I was pointed out to try a couple of specific plug-ins for Maven (I was a bit surprised that there was no Maven support out-of-the-box). I tried, but I faced with a problem about the incompatibility of some modules, that remembered me some nightmare experienced three years ago trying to use Eclipse with J2EE. I supposed these problems were gone away with the latest stuff (for the record I tried the latest Ganymede). I really don't have time to play with it, and probably I've got lazy as I've got acquanted with the NetBeans plugins that just install and work (not to mention the out-of-the-box support for many things), so if you're running Eclipse and Maven and would like to contribute with a few lines for the Wiki, you're welcome to take ownership of issue 29. Thanks!



BetterBeansBinding: ready, start, go (1.2.2 released)

Posted by fabriziogiudici on April 25, 2009 at 01:12 PM | Permalink | Comments (9)

After some delay, as I tried to work around a problem with Maven + Cobertura + Hudson, the BetterBeansBinding project is ready to go. I've released 1.2.2 which is no functionally different from the latest Shannon's commit of BeansBinding: it probably shouldn't be used for production, since I don't know in which state the last commit was done (and the current test coverage is 18%). BTW, I temporarily commented out two tests, which seems to be not finished, in order for Cobertura to compute the coverage. 1.2.2 will be used as the target release to file issues and RFE against.

The job performed so far has been related with the set up of the new project: changes in the license, Hudson CI and mavenization. The bug related to Hudson and Cobertura hasn't been resolved yet, but I don't want to postpone the start up of the project further. So, I've generated a Cobertura HTML report and manually committed to the repository.

I've still to find a way to copy the issues from the BeansBinding tracker, so in the meantime if you have something urgent to fix, please report it again against BBB issue tracker.

PS I've kept the same licensing, Lesser GPL v2.1. Should I upgrade to LGPL v3?



Next events and conferences - and, hey, the Server Day is coming!

Posted by fabriziogiudici on April 22, 2009 at 09:42 AM | Permalink | Comments (3)

It sounds as the two next months are packed with events:
  • May 8, Milan: I'll speak at All4Web about JavaFX, including a RIA vs RIA talk. Free event (in Italian language).
  • May 21, Genoa: I'll attend The Server Day, organized by JUG Genoa. Do you remember the IDE Shootout from JUG Cologne and JUG Genoa? Well, think of a similar event, but focused on Application Servers. And the argument is hot after the Oracle - Sun deal. Free event.
  • May 31, San Francisco: I'll be at the Hudson Unconference; a party at the Thirsty Bear will follow. It sounds as I'll be at last able to offer that beer to Kohsuke. Free event.
  • June 1, San Francisco: I'll speak at CommunityOne West about the NetBeans Platform on the server side; there will be possibly some OSGi divagation and I could *possibly* present a new Tidalwave product, if I manage in getting a demo ready (not sure at the moment). Free event. I don't know yet if I'll get a JavaOne pass, but in any case I'll be wandering a bit in the Pavillion until Thursday.
  • June 22, Zurich: I'll attend OSGi DevCon Europe. No budget and no time to attend Jazoon, unfortunately (the following days are the only slot I have for a planned tour through the Swiss, Italian and French Alps). If you have a chance for Zurich, consider Jazoon as it is an interesting conference.
It also sounds as I have to free several GBs in the disk to make room for the incoming photos... ;-)

I would like to draw your attention on the Server Day stuff, since it has been just announced. The capability of seeing a direct comparison among GlassFish, JBoss, Spring dm Server, GlassFish and Oracle WebLogic, described by people who develop them, in a single afternoon - and *free* event! - should not be missed.



On why I'm skeptical about the "permanently connected" stuff

Posted by fabriziogiudici on April 22, 2009 at 03:17 AM | Permalink | Comments (0)

I've blogged many times about my skeptical attitude about service models based on the "permanently connected" paradigm. Let me tell you this funny (more or less) anecdote that happened to me this morning. Not to be taken too seriously.

Today I'm teaching a class for Sun in the Milan hinterland. When I got off my car in the park lot, I've accidentally dropped the car keys into a street drain (a perfect hit into the only drain in 100 m^2). Of course I've got a backup of the keys, but they are at the moment in my house in Genoa.

But don't worry. I supposed I could call a courier and have my parents to send me the backup keys - organizing the thing early in the morning should be ok for getting the delivery within 5PM. So I phoned the courier, asked for information (to make sure the delivery can be actually made within 5PM, or I'd loose the backup keys too!) and organize the delivery. In spite of being in the middle of a highly populated area, the quality of the mobile signal was low. In a few words, after ten minutes of giving the details of the delivery, the line dropped. Puff. Of course, if I call again the courier I won't get in touch with the same operator (this is the problem of stateless Session Bean, I presume, so you could also interpret this story as a rant against stateless models, at least from the user's perspective), so I would have to restart from scratch. But I'm teaching a class and I can't have my students on hold for too long.

So I gave up and this evening, when the class ends, I'll try to find another solution. So, don't feel safe about that "permanently connected" stuff. Sometimes the network doesn't work. Well, at least today it's not raining.

PS If you are wandering on why I'm not using the web pages of the courier to set up the delivery, it's because I wanted to have a *direct* confimation that the delivery would be completed in time.



Google App Engine for Java sucks

Posted by fabriziogiudici on April 16, 2009 at 02:17 AM | Permalink | Comments (20)

I confess, I missed the key point while reading the announcement. But Google App Engine for Java misses a good deal of classes in the JRE: in a word, they aren't offering the full Java runtime. It shouldn't be ever called "for Java" IMO and I don't understand why Google is using the "Java" term for a thing that is not Java. While for many this is not a problem, for me it is since there is e.g. no support for java.awt.Image and such. Also, I don't see any technical reason for this choice, at least for a good deal of the missing classes.



Who knows SigTest, please raise your hand.

Posted by fabriziogiudici on April 08, 2009 at 04:49 AM | Permalink | Comments (0)

I've almost completed the inception of BetterBeansBinding: sources are in the new repo (but I have yet to replace the copyright notices), the project has been mavenized (!*), we have the issue repository and the communication plan, yesterday also a new instance of Hudson went up (it's mine, I've been able to deploy it to a different server that doesn't have load problems as the one for blueMarine) and we have the first reports (Cobertura and Findbugs).

One of the last pieces I'm working on is SigTest. Do you know it? SigTest is a pretty neat tool for testing the compability of an API with its specification and/or previous releases, used by the developers of the JDK and (with a slightly patched version) by NetBeans developers. The idea is that you publish a release of an API and declare it is a reference point (in my case it's the very first version of BBB, that hasn't been touched so it's just the BeansBinding code in a new repo); then run SigTest to create a "golden file" that contains a precise description of the public classes and methods exposed by your API. Later, you'll run again the test on the most recent build and it will compare the results with the golden file. If it's the same, no problem; if it finds you've only added new methods and classes, no problem but be aware of what you're doing; if you have changed things and broke the backward compatibility, you'll see an error. And, as Jarda Tulach described in some chapters of his book, retrocompability can be broken in very subtle ways: one thing is source compability (you are allowed to recompile everything), another is binary compatibility (you just replace jars - and BBB needs it), etc..

SigTest will help BBB in keeping the compability with the original API.

(*!) I don't have changed my mind about Maven. It's just that BBB is not "my own" project, but it has some relevance for the whole Swing community, others will participate and Maven is popular, so this choice should make collaboration easier.



IBM broke off Sun acquisition talks

Posted by fabriziogiudici on April 05, 2009 at 05:30 PM | Permalink | Comments (4)

According to Reuters, IBM withdrew its buy offer for Sun. It's not clear whether the deal broke forever or talks could resume, neither whether there are other possible buyers. We have to get patient on this issue.



Interesting rumors about the Sun/IBM deal

Posted by fabriziogiudici on April 01, 2009 at 12:00 AM | Permalink | Comments (8)

While the fact I'm a member of the NetBeans Dream Team prevents me from revealing some reserved news, I've got some hints from a private contact of mine, in Italy - so I think I can tell you some details without infringing any secrecy commitment.

Since when the WSJ anticipated the first rumors about the Sun/IBM deal, lots of analysts started speculating which would be the most important Sun assets that IBM is interested to buy. While there are no doubts that one of the primary interests is about Java IP, some put the focus on the server line, others on some innovative parts of Solaris (e.g. ZFS) or specific software in Sun's portfolio such as the Identity Server.

My private contact has access to a senior IBM manager, who comes from Italy but has been working in the USA offices for years. The manager allegedly revealed him that the primary IBM interest is indeed NetBeans. Not to shut it down, as some fear, but to make it the primary reference IDE for the Java world - in fact, as NetBeans is getting OSGi compatibility this year, IBM realized that Eclipse now can't stand the competition, as NetBeans is a much superior product.

My contact gave me some other hot detail. The primary site for NetBeans development would stay in Prague, and a specific spin-off company would be created. The (provisionary?) name of the new company would be "Sole" (*), the italian translation of the word "Sun", which would avoid some trademark issues, while preserving a sort of continuity with the current NetBeans owner.

Who knows? As usual, these rumors can't be easily confirmed, so we just wait and see...

(*) Indeed, some assert to have seen the name of the new company printed in some reserved document, and swear it is rather "Sola" - could be a transcription problem due to the bad pronounce of the italian word?



June 2009
Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30        


Search this blog:
  

Categories
Community
Community: Java User Groups
Community: JavaDesktop
Community: JDK
Community: Jini
Community: Mobile & Embedded
Community: NetBeans
Community: Sun Grid
Distributed
Grid
J2ME
J2SE
JavaOne
Jini
Linux
Open Source
Web Applications
Archives

June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
December 2006
November 2006

Recent Entries

Shame on you, MediaMarkt Zurich

Wine delivered at OSGi DevCon

First enhancements on BetterBeansBinding



Powered by
Movable Type 3.01D


 Feed java.net RSS Feeds