The Source for Java Technology Collaboration
User: Password:



Kirill Grouchnikov's Blog

July 2005 Archives


Eclipse - the milk cow for the board members

Posted by kirillcool on July 27, 2005 at 07:03 AM | Permalink | Comments (19)

My previous entry on IBM's hold over Eclipse has provoked an interesting response from the Executive Director of the Eclipse Foundation. The description of the Eclipse Foundation verbatim is an independent, not-for-profit foundation supporting the Eclipse open source community. Mike provides a few examples of Eclipse projects that have 0 IBM contributors, one of them being BIRT, and another being ECF.

The second example is completely irrelevant, having only 5 bugs, but the first one is much more intriguing. Out of 529 bugs, about 95% are allocated to Actuate employees. A quick search on the Internet finds the reason why - for only 95$ a year you can purchase features not available in the free version. Of course, both versions are developed exclusively by Actuate, it's just that the free version that apparently lacks a lot of features is presented as a part of the Eclipse IDE. It appears that Borland will be making a similar move with JBuilder Foundations, providing the additional features as Eclipse plugins for paying customers.

Obviously, IBM is not going to lose the money paid to its employees that maintain the bulk of Eclipse. It's much the same way for Sun. As aptly put elsewhere, both companies are planning to increase their revenue by "locking" customers that are looking for free solutions.

More and more companies are joining the show: BEA has announced that it will be leading the Web Tools Project (although it has only 42 bugs out of 3348 total, they are much more frequent recently), Oracle, SAP and HP are already on board. Some may argue that these companies are aiming to reduce the cost of in-house development, but they most certainly are continuing to build commercially available-only tools on top of Eclipse platform.

Going back to the independent, not-for-profit foundation supporting the Eclipse open source community motto now. It seems that an assembly of highly influential commercial vendors is steering the wheel (independent from what?), hoping to make a lot of money for themselves (not-for-profit for basic functionality?), lulling us into the false sense of the open source community (which finds them bugs instead of paid testers).

Visualize your schema dependencies

Posted by kirillcool on July 24, 2005 at 02:42 PM | Permalink | Comments (1)

One of the questions i have been asked at our BoF at the last JavaOne was whether i was aware of some application that can show dependencies between schema files as a graph. At that moment, and still now, I am unaware of any such open-source application. However, i promised that it wouldn't take long for such a feature to make its way into JAXB Workshop next release, and 29 days later, it's officially available.

First, a couple of nice screenshots from the application itself (all window controls have been removed for the sake of clarity). Here is a graph for JXDM (Department of Justice) schema set:

The next schema set comes from FpML (Financial Products):

The third schema set comes from VoiceXML:

And the last ungodly creature comes from one of the schemas in HR-XML (Human Resources). This graph has 30 vertices (schemas) and 104 edges (includes / imports / redefines), making each vertex connected to an average of almost 7 other vertices:

In order to run the application by yourself, you can either WebStart it (it needs permissions to access local schema files to read them), or download the bundle from the project download section and run drop/explorer.bat on your favourite flavour of Windows (for other OSes you will have to run the batch yourself). In any case, you'll need JDK 5.0+. In order to view a graph for your favourite set of schemas, wait for the application to come up, press Ctrl+L (or go to Actions menu), choose your schema, let it be processed and go to the Schema graph tab.

The magic of drawing, layout and mouse activity (zoom, pan, tooltip) is provided completely by the JUNG library.

Be prepared to wait for a while until the application loads up, it uses a few heavy third-party jars to make it work. And the last thing - don't even think of loading schemas from IRS, unless you want to stare at a graph with 400+ vertices.

How to create scalable icons with Java2D

Posted by kirillcool on July 23, 2005 at 12:54 AM | Permalink | Comments (11)

In one of my previous entries i've shown how to use Java2D to create layered icons for your application. Unfortunately, most of the time we think about icons in pixel-precision format, instead of thinking of them as vector graphics. Let's see an example first:
icons.png

The icons are shown starting from 10*10 to 36*36 size. As you can see, the icon components are nicely scaled (including inner graphics width, highlight in the top-left corner and so on). What's more important, each row is created by the same function that gets an icon size as a single parameter. Let's see the code of the function that created the first two rows:

First, let's define a function that will return us an Icon:
     
   public static Icon getSuccessMarkerIcon(int dimension) {
      return new ImageIcon(getSuccessMarker(dimension));
   }
Now, we define a function that creates a BufferedImage:
     
   public static BufferedImage getSuccessMarker(int dimension) {
First, we create a new image and set it to anti-aliased mode:
     
      // new RGB image with transparency channel
      BufferedImage image = new BufferedImage(dimension, dimension,
            BufferedImage.TYPE_INT_ARGB);

      // create new graphics and set anti-aliasing hint
      Graphics2D graphics = (Graphics2D) image.getGraphics().create();
      graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

Fill the background:
     
      // green background fill
      graphics.setColor(new Color(0, 196, 0));
      graphics.fillOval(0, 0, dimension - 1, dimension - 1);
Create a white spot in the top-left corner (to simulate 3D shining effect) - note that we set clipping area to the icon circle (so that all the rest will remain transparent when our icon will be shown on non-white background):
     
      // create spot in the upper-left corner using temporary graphics
      // with clip set to the icon outline
      GradientPaint spot = new GradientPaint(0, 0, new Color(255, 255, 255,
            200), dimension, dimension, new Color(255, 255, 255, 0));
      Graphics2D tempGraphics = (Graphics2D) graphics.create();
      tempGraphics.setPaint(spot);
      tempGraphics.setClip(new Ellipse2D.Double(0, 0, dimension - 1,
            dimension - 1));
      tempGraphics.fillRect(0, 0, dimension, dimension);
      tempGraphics.dispose();
Draw the outline (must be done after the white gradient so the outline is not affected by it):
     
      // draw outline of the icon
      graphics.setColor(new Color(0, 0, 0, 128));
      graphics.drawOval(0, 0, dimension - 1, dimension - 1);
Compute the stroke width for the V sign. This sign is created using the same path with different strokes, one for the outer rim (wider), and one for the inner filling (narrower).
     
      // draw the V sign
      float dimOuter = (float) (0.5f * Math.pow(dimension, 0.75));
      float dimInner = (float) (0.28f * Math.pow(dimension, 0.75));
Create a GeneralPath for the V sign
     
      // create the path itself
      GeneralPath gp = new GeneralPath();
      gp.moveTo(0.25f * dimension, 0.45f * dimension);
      gp.lineTo(0.45f * dimension, 0.65f * dimension);
      gp.lineTo(0.85f * dimension, 0.12f * dimension);
Draw the path twice
     
      // draw blackish outline
      graphics.setStroke(new BasicStroke(dimOuter, BasicStroke.CAP_ROUND,
            BasicStroke.JOIN_ROUND));
      graphics.setColor(new Color(0, 0, 0, 196));
      graphics.draw(gp);
      // draw white inside
      graphics.setStroke(new BasicStroke(dimInner, BasicStroke.CAP_ROUND,
            BasicStroke.JOIN_ROUND));
      graphics.setColor(Color.white);
      graphics.draw(gp);
Dispose of the temp graphics and return the image
     
      // dispose
      graphics.dispose();
      return image;
   }
For slightly curved mark (the second row), use the following path:
     
      GeneralPath gp = new GeneralPath();
      gp.moveTo(0.25f * dimension, 0.45f * dimension);
      gp.quadTo(0.35f * dimension, 0.52f * dimension, 0.45f * dimension,
            0.65f * dimension);
      gp.quadTo(0.65f * dimension, 0.3f * dimension, 0.85f * dimension,
            0.12f * dimension);
The code for the other rows is very similar. One trick for triangles is to create the perimeter path that specifies rounded corners (using quadTo as above).

Using this technique, you no longer have to bundle icons of different sizes in your application. In the example below, there are three versions of the same error icon, one 9*9 (overlayed on top of another icon in the tree cell renderer), another 11*11 (in the left gutter panel) and the last 13*13 (in the message table panel). All of them were created on the fly without the need to worry if you have the corresponding icon bundled with your application.
milano.png

Native XML support in Dolphin

Posted by kirillcool on July 16, 2005 at 01:10 AM | Permalink | Comments (18)

In "Evolving the Java language" technical session during the last JavaOne, Mark Reinhold shed some light on the future of Java XML support. The slides for the technical sessions have been finally uploaded to conference webpage, so download the PDF for session TS-7955. The executive summary of the relavant slides is:
  • DOM is excellent feature-wise, but requires too much code to be written, and reads poorly.
  • JDOM is more concise, and if you tilt your head and squint, it looks almost like XML.
  • JAXB 2.0 is schema-driven and can not handle "free" XMLs (w/o schema definition) or "intermediate" XMLs (in the middle of the processing).
  • It would be great to directly write XML, but that will drive compiler guys insane.
  • One of possibilities - using hash mark # to refer to XML attributes or subelements.
  • This can be either to get or to set a new value.
  • Enhanced for loop should allow looping over all instances of some attribute.
  • A lot of generified suggestions for new classes (XML and such).

And now, hoping the above list did not offend too many lawyers, let's proceed. As outlined in the first three items, the current state of affairs in working with XML is far from satisfactory. If you take a web designer, it usually means exceptional HTML and CSS skills, and good Javascript. Javascript is very far from Java, but it's fairly easy to use. How about throwing in an XML parser? We can be all excited with StAX, but the "ease of use" column is somewhat misleading. It's easy to use when you talk with your dog in JVM bytecodes, but it's certainly not easier for non-technical guys.

IBM continues to develop XJ - XML enhancements for Java. XJ program treats XSD schemas as "first-class" citizens, allowing to import them as regular Java classes, read and write attributes and elements, unmarshal strings, streams and files to "virtual" objects and marshal these objects back ("virtual" object is object of class that directly corresponds to some schema artifact, without the need for explicitly generating this class). As Mark pointed out during his talk, this approach is too restrictive - you work only on XML that are valid according to a predefined set of schemas.

The same can be said about JAXB 2.0. It doesn't matter if you start with a schema and create classes, or if you start with your classes. As long as the input can not be completely mapped to your classes, the unmarshaller will fail. In addition, you can not add arbitrary elements during the marshalling.

The approach that Mark outlined in his talk is the complete opposite - no schema, no class for the data, only working with XML tags (that in the proposed syntax can not even be externalized). Complete freedom that comes at cost of optional validation, typechecking and syntax that is far from readable (except for your JVM-compliant dog).

So, what am I looking for? Suppose I have two simple classes, Customer and Order, that look like this:
class Order {
  // has get-set pair
  private int id;
}

class Customer {
  // has get-set pair
  private int id;
  // has get-set pair
  private String name;
  // has get-set pair
  private List orders;
}
Simple annotation with JAXB 2.0 can be putting the following on each class:
@XmlAccessorType(AccessType.FIELD)
And maybe the following on Customer:
@XmlRootElement(name = "customer")
Taking a simple XML
<customer>
  <id>1</id>
  <name>Dan</name>
  <order>
    <id>1</id>
  </order>
  <order>
    <id>1</id>
  </order>
</customer>
I'd like to be able to simply write
String xml = ...;  // contains the above XML
Customer cust = xml;
With the auto-unboxing calling JAXB 2.0 unmarshaller (which is already a part of Mustang). The same auto-unboxing should be provided for File, Reader and InputStream as well. If I want to change my customer, i simply change the field:
cust.setName("Arnold");
The marshalling should be as simple as unmarshalling
String newXml = cust;
Here, the auto-boxing should be called. In this case, toString() default behaviour can be the marshalling using JAXB 2.0 (in case Customer class does not override the default implementation of toString()). Auto-boxing should be also provided for Writer, OutputStream and File.

Looping over elements in Customer should be kept as simple as possible:
for (Order order : cust.getOrders[id>3]) {
  System.out.println(order.getId());
}
Here, the compiler knows the exact type of id field and can invoke the getter function. The amount of extra syntax elements (hash mark, slashes, apostrophes) should be 0. The code should be easy to read.

Now, the more interesting problem. What if we don't have schema? What if we are working on XML that has extra elements or attributes that our functions should simply ignore? What if we need to add extra elements or attributes that our functions wish to add for subsequent modules? The answer is simple, and was introduced long ago in Java, and reinforced in 5.0 with generics - extends keyword. Combined with "implicit" properties and functions introduced on enums in 5.0, clean solutions can be provided to the problems stated above.

Suppose that I get the following XML
<customer>
  <id>1</id>
  <name>Dan</name>
  <age>32</age>
  <order>
    <id>1</id>
    <extId>1000</extId>
  </order>
  <order>
    <id>1</id>
    <extId>2000</extId>
  </order>
</customer>
Marked in red - elements that can not be mapped to Customer and Order classes. However, our code doesn't use these elements at all. How can we make our code work and the compiler happy? Make the compiler perform implicit narrowing conversion:
String xml = ...;  // contains the above XML
Customer cust = xml;
The code is exactly as it was. The marshaller should simply discard all the "irrelevant" information, just as done with regular upcast. Of course, the regular upcast doesn't really change the class, so that you can always downcast back (at your own risk). This will be clarified in the following examples.

Suppose now that you wish to handle the new fields, but you can't change the Customer and Order classes (for example, they are part of external jar). Now the code can look like this:
String xml = ...;  // contains the above XML
extends Customer cust = xml;
The extends keyword instructs the compiler (and the unmarshaller) to keep extra information (exactly as done with enums and name() function). This keyword applies to all internal elements (Order in our case). How can we access the new (undeclared) fields - the same way as regular fields:
System.out.println(cust.age);
Here, the unmarshaller stored the value of age in some internal map, and the compiler retrieves that value for us. Here, there are three possible cases:
  • Single instance with simple value
  • Single instance with complex value (inner elements)
  • Multiple instances
In the first case, the value class will be String, in the second - extends Object and in the third - List<extends Object>. The compiler should allow looping over elements even if they are single entries:

// must extend Object as we don't know it's type
for (extends Object age : cust.age) {
  // implicit function provided by the compiler
  if (age.isSimple()) {
    // the cast will succeed
    System.out.println((String)age);
  }
}
What about adding new elements? Simply call
cust.weight = 180;
This can only compile on extends Customer. If the type of "cust" is Customer, the compiler should issue an error message.

Continuing this line of thought, the regular rules for casting, narrowing and passing objects as parameters apply:
private Customer cust1;
private extends Customer cust2;

void test() {
  // narrowing implicit cast - all undeclared
  // attributes and elements are discarded
  cust1 = cust2;
  // widening implicit cast
  cust2 = cust1;
}
Here we have special case - although both cust1 and cust2 point to the same "base" object, changes to cust1 are seen in cust2, but changes in cust2 are seen in cust1 only on declared fields. If we have another extends Customer cust3 that points to cust2, it's the same object. In this case, all three are poiting to the same object in memory, but calling marshaller on cust1 will emit only declared fields, while calling marshaller on cust2 or cust3 will emit all fields. This way, the referencing model is preserved, and the compiler does not allow adding or retrieving undeclared fields from cust1.

Another example -
Set customers = new HashSet();
Customer cust1 = ...;
extends Customer cust2 = ...;
// implicit widening cast
customers.add(cust1);
// regular insert
customers.add(cust2);
for (Customer cust : customers) {
  System.out.println(cust.age);
}
In this case, this function will print null on the cust1.age - it was implicitly widened based on the type of the Set, but doesn't contain information on age.

Another example:
void foo(Customer cust) {
  // widening cast - undeclared fields
  // can appear after the call.
  bar(cust);
}
void bar(extends Customer cust) {
  // implicit narrowing cast - only declared fields
  // can be changed.
  foo(cust);
}
The extended type may provide access to its elements, as enum does (with implicit functions):
Map getAllElements();
where each entry can be either String or List for collections.

The last example is a recursive function that traverses the input XML and dumps its contents to the console. Arguably, this function is not much simpler than its counterpart for DOM. However, most of its logic is both straightforward and simple. In bold red font - the functions that are generated implicitly by the compiler:
void dumpXml(extends Object xmlObj) {
  // see if it is a simple (and implicitly single) element
  if (xmlObj.isSimple()) {
    System.out.println((String)xmlObj);
    return;
  }
  // see if it is a single (and complex because of the previous
  // check) element
  if (xmlObj.isSingle()) {
    // iterate over inner elements. The getElements()
    // function is generated implicitly in the same way as 
    // name() is for enums
    for (Map.Entry element : xmlObj.getElements()) {
      System.out.println(element.getKey()); // element tag name
      dumpXml(element.getValue());          // recurse on value
    }
    return;
  }
  
  // here - we have multiple instances of element with the same
  // tag (collection). Can call .isMultiple() function on 
  // xmlObj
  for (extends Object child : xmlObj.getElements().valueSet()) {
    dumpXml(child);             // recurse on the current child
  }
}


Answers to selected comments

The marshalling and unmarshalling exceptions (including I/O and XML format) should be declared as unchecked. Few new exception classes (may be even one) should "envelop" the existing exceptions (too many of them already). If your code wishes to provide corresponding support - you will have to catch the new exceptions and deal with them correspondingly.

The examples are based on attributes rather than accessors, but using JAXB 2.0 this remains purely a choice. You can go either way (and don't forget that XML attributes and elements do imply straightforward field implementation). For undeclared elements (such as age in the examples above), there can be only a public attribute-style access - after all, they are not declared on the corresponding data class.

XJ's support of undeclared attributes requires the same approach as working with DOM and XPath. The only option to parse XML that is not valid according to some schema is to use XMLElement class, which brings back the "ease-of-use" of DOM. The only example I could find of getting information out of XMLElement was using XPath query (in SequenceInstanceOf.xj). All other examples (which are very scarce) use this class to wrap something inside some tag and either output it as XML or put it inside another tag. There are two problems with this approach:
  • Partial processing of XML can not use schema-derived types. If i know that the input XML contains fields that i wish to ignore, i just don't define them in my data model and work on extends object. In XJ, I'll have to work on XMLElement even if I wish to ignore some fields (unless i have schema definition for every intermediate XML state in my business process chain).
  • XMLElement is not a run-time class as far as I can see from the bundle distribution (the documentation is very scarce). The only way to get elements from it is using XPath, even for simple attributes.
Regarding Xen type-system (thanks for the link). It appears that the authors are trying to mold existing language into schema-based classes. The proposed approach modifies the class declarations completely, making the language syntax follow XSD artifacts. Clearly, this is ill-suited not only for DTD and Relax NG, but also to the existing code base. Suppose you have back-end library that provides a lot of functions. All you need to do (in the approach proposed in this entry) to make this library work with XML - annotate the classes correspondingly. With Xen, you'll have to rewrite your library from scratch or create a data-mapping layer to map from new classes to old data classes. Looking into the future - the code as shown above, does not even know that it's working with XML. Tomorrow (a few years from now) this code can be converted to work with another data format (binary XML, OODBS) without touching the business logic, effectively separating the data layer from the business layer.

Porting small library from Java 5.0 to Java 1.4 - could it be any harder?

Posted by kirillcool on July 15, 2005 at 11:45 AM | Permalink | Comments (4)

And so, last evening I set out to provide 1.4-compatible version of my Substance look-and-feel library. What promised to be an easy task (a couple of changes per file, given not too excessive use of generics), turned out to be a frustrating and valuable experience not only with Swing classes, but with Java 5.0 features in general.

First off, I should say that at work we write for JDK 1.4.2. For me, last year that amounted to roughly 2600 hours spent on writing 1.4.2-compliant code. At home (for a few projects here on java.net) it's been 5.0 from the beginning. Last year that amounted to roughly 700 hours spent on using 5.0 features. Not claiming to know my way through all new features in 5.0 (there were way too many hands raised on Joshua Bloch's "Collections Connection" when he asked to see who knows everything in 5.0), I feel comfortable with all new language features. Contrary to what some claim (he looks suspiciously familiar), generics in the "light" version (no wildcards, no "super" or "extends" etc.) make the code look better and more robust. As a collection guru, you may think that nobody can forget that exact value type stored in some map, but what about your average programmer who left last week and whose bugs you need to fix? Your best hope would be that he documented the correct types of keys and values in javadoc, otherwise you would either hunt all the puts, or debug until your fingers are blue and ready to fall off.

And so, i thought. 77 files, 440KB of code. How hard can it be? It shouldn't even matter how many files or how many lines of code. Just take Retroweaver, add ant task and lean back. The "lean back" part ended abruptly, seeing that i have used quite a handful of methods that were new in 5.0 (which i used). Here lies the main deception of Retroweaver - its abilities are very limited. It can handle generics, enhanced for loops, enums, iterables, but that's about it. A class that's new in 5.0, or a new method on existing class - you're on your own. And that certainly discourages the use of Retroweaver - I moved to 5.0 not only because of the language features. I want to use new stuff like Formatter, Scanner, concurrency, ExecutorService and even String.replace that gets two CharSequences as parameters. And so, the first big disappointment was - if you want to port your library back to 1.4, you can't use any 5.0 new stuff. That sounds obvious, but not so if you start writing a new library straight in 5.0.

The next step was to see the functions that were not present in 1.4 and replace them with the corresponding counterparts from 1.4. That sounds easy, but when you extend functionality of the existing Java classes, it's not. For look-and-feel, you extend the existing UI delegates and plug-in your stuff. The stuff you plug should involve only drawing, so that couldn't change much between different JDK versions, right? Right and wrong. It doesn't change much, but a lot of stuff gets exposed in later JDK versions that was private in the previous ones. One of the best examples here would be createScrollButton in TabbedPaneUI. When you set your tabbed pane to work in SCROLL_TAB_LAYOUT mode, the tabs that overflow the available space are not visible, and can be "scrolled to" using two small arrow buttons. The default implementation draws the button on its own, ignoring the installed ButtonUI, so you would want to override this behaviour to provide consistent look and feel to all the buttons. In 5.0 it's very easy - you are override createScrollButton() function, it's called and then Swing plugs in all the listeners on those buttons. In 1.4 - big surprise. Pretty much everything in BaseTabbedPaneUI is private, the buttons, the listener, the layout. And everything is not only wired, but also hardcoded for the class names. And you can't make your button inherit from the inner button - its class is private. What you can do - the good old "copy paste". That's what is done in JGoodies - its TabbedPaneUI is a complete rip-off (with a few tweaks to plug its own buttons), spanning 3092 lines. My original 5.0 version of TabbedPaneUI is 235 lines. And that brought the second disappointment - there are very good reasons to use new functions. That sounds obvious too, but yet again if you start out with new functionality and then force yourself to go back, you'll have to implement it yourself.

At this point, the next step was obvious - the code must be rewritten. But should it still be in 5.0? That's a tough question. You can integrate Retroweaver in your ant script and run it everytime you change something. You can pay close attention to javadoc comments of every single function that you intend to use. You can set your compiler to 1.4 settings, but it will not catch use of new 5.0 functions. Or, you can just take your code and backport it to 1.4 yourself. After all, you are not using any new stuff (apart from generics and enums), and you are not burdened with all the bookkeeping.

A few clicks in Eclipse, and the project was configured to 1.4. Thirty seconds later, the build is over, and on 77 files I had 856 errors. About 30% were on generics (both parametrized collections and missing casts on retrieving objects), 30% were on @Override (you use that a lot writing look-and-feel under 5.0), and 35% were on enums. The most unexpected part was for enums - you just get used to having name(), values() and using them in switch statements. The harsh 1.4 reality sets in, and even when you use Bloch's enum pattern, you still need to provide name(), values() and rewrite your switch statements. Couple of hours later - all the errors were gone (except the functions that were not available in 1.4), and the code was uglier than before, especially when you need to store Longs in a Map (autoboxing is nice), or iterating over entries in Set or array. The third disappointment set in during the two hours frantic coding - removing 5.0 language features takes more that it seems. Less obvious (maybe because it's sold as "syntactic change" only), but time-consuming nonetheless.

When the last errors were fixed, I run the test application that tests all component UIs. Instantly i was greated with the long despised "use getRootPane().add()" message. Quick fix, the application runs, but:
  • background of menu and menu items is dark gray instead of nice light gray. The same for combobox.
  • default button behaviour is transferred to the clicked button.
  • the buttons are not "rollover-enabled"
  • dialog root pane is not opaque
  • selected items in list are not highlighted
  • sliders have background for ticks
  • progress bar is off by 1 pixel in both width and height
  • root pane header is off by 1 pixel in width
All these were either fixed or corrected for 5.0. Now i have to introduce "bug fixes" myself. That's when the last disappointment sets in - each new JDK version fixes existing bugs in older versions. Obvious as well, but quite unexpected when all you want is to run your library in older JDK and just want it to show the same behaviour.

With all of the above, twenty four hours later, the library has not been ported back, but a few lessons have been learned.

Tiger for 5, Mustang for 6, Dolphin for 7. What for 8?

Posted by kirillcool on July 03, 2005 at 10:13 AM | Permalink | Comments (55)

We know that Tampa will host 2009 SuperBowl, Vancouver will host Olympic Games 2010 and London will host Wimbledon 2108 (unless the Antarctic ice melt sweeps British isles clean). But what about our own beloved Java Platform, Standard Edition?

So, I got to ask Sun people (Mark and Graham among them) if they already have the name for Java 8. After a short giggle, they said that they had one name in mind (without divulging it) and then asked me if i had one. They caught me off guard, but having done the homework (and looking on the list of the previous names), here is my short list of candidates.
  • Flamingo
  • Eagle
  • Falcon
  • Albatross
  • Kingfisher
  • Condor
  • Magnolia (well, not actually a bird, but can start a nice trend)
My personal favourite would be Eagle. And here is a short list of names Sun should stay away from:
  • Brazil - that will make me seriously consider going to MS
  • Elephant - for the memory footprint
  • Snail - for the performance
Also see this lively discussion on TSS thread.

JavaOne - what a cool, next-generation, Brazilian experience

Posted by kirillcool on July 02, 2005 at 11:35 AM | Permalink | Comments (14)

Oh, well. What did we have?
  • A lot of supposedly cool stuff (even had an entire track for that), that wasn't anywhere near being usable, useful, or cool for that matter.
  • A lot of next-generation stuff, that will take at least 3-4 years to make its way into real-world enterprise applications (yes, it will take uncounted hundreds of millions of dollars for real systems to move from J2EE 1.3.1).
  • A lot of cheap applause from Brazilian programmers (felt like a horde of puppets sometimes, but as long as people are happy...).
  • An amazingly annoying Finch puppet (note the nice interoperability with the previous item). I guess its creator likes it, but who else in the JUGs? Even John Gage was forced to play along and listen to it. Next in line - the guy in the Duke costume (i was told that they worked in shifts). My picture was way out of focus. I'll be on my way to buy that HP camera real soon.
  • A wonderfully disappointing track on desktop (i have attended at least 10 sessions and BoFs on this one), only to be matched by the shallowness of "Swing hacks" with stunning amount of typos, discrepancies between the code and the comments, and code style. But then again, i only got to #45. Nice to know, though, that a sizeable portion of Java 2D team has been working for three weeks on turning a non-existing application into an extreme looking one.
  • An educating insight into Dolphin's future by Mark Reinhold. Unfortunately, he has asked me to refrain from putting the screenshots of his slides on the web, so i'll patiently wait (hopefully not too long) for his entry on the subject to put my 2c in.
  • A stunning amount of James Gosling look-a-likes. Guys, seriously, the long gray hair may look fine on James, but not on you. Just shell out a few bucks and cut it. Really. Even set up a PayPal account, and i'll gladly chip in.
  • A fair amount of nightmares when John Gage repeatedly tells me that I have only 58 hours left to make new friends. Only to be matched by the obnoxious behaviour of xfy's marketing guys. And may be by the amazing number of people who were actually willing to sit down and listen to that **** to get a t-shirt in the end.
  • Speaking of xfy - the technical people couldn't even tell me why it's better than OpenOffice or MS Office. Well, why should i buy it exactly?
  • And speaking of the pavillion floor - nice experience with one of the Sun's WebStart guys that couldn't answer my question (not an easy one) and then was apparently relieved when his shift ended. Didn't even finish the conversation properly, just looked the other way and started to talk with the next shift guy. Way to go!
  • The naming convention for next Java products is OK, but can the marketing guys please stop? Pretty please? I know you have to show that you bring value to the organization, but how about enough? Not only did you make the slides look ridiculous, you even got your own people confused (Graham and Mark had contradicting points of view on the time of the next naming change). Pretty please, can you choose something and then let it live? Maybe you (the lawyers / marketing people) didn't attend the sessions, but even your own technical guys were making fun of you (indirectly) on each slide with "Java TM Platform Standard Edition" that replaced "Java".
  • Had my own BoF attended by almost 18 people (but then again, it started at 19:30 on Wednesday, in the middle of the "Bash the next geek you see" party).
  • And please! We know you are Brazilian. Heard it quite a few times. Brazil everybody (wait a few seconds for applause). Blah blah blah (notice that the audience is dozing off) Brazil (wait for applause). Rinse and repeat.
And now - the promised cartoon. I could call it "cool" or even "next-generation". However, it's a simple still shot of my wall map with an assorted sprinkle of spray primitive in Microsoft (should i shoot myself for not using a true Open-Source product?) Paint:
map.png
And yes, Hani, it was a long flight, i went to sessions (some good, some bad, no explanations why), i met people (it was cool, remind myself to cut right arm for using this word again), JSF could kick ass if i bothered enough to use it, NetBeans is great (i don't work for Sun, honest), and here's a picture (he does look perplexed, doesn't he?)



Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds