Joe Wang's weblog -- JAXP & SJSXP, and thoughts of ... little impact
A Drop of Water
Archives
« November 2009
SunMonTueWedThuFriSat
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
     
       
Today
Click me to subscribe
Search

Links
 

Today's Page Hits: 11

Friday Apr 10, 2009
Cool companies, cool customers

As a Sun employee, I can't help but notice all sorts of colorful stories on the tech news, "people familiar with the matter" type of stories, ciculating in the last couple of weeks. What's more interesting is how millions of dollars worth of shares could change hands based upon "unconfirmed" news.

Sure, powerful analysts have said so. Sure, where could it go when a company's share has been down to the earth? Anyone can recite a good history of such things.

But there always are exceptions, right? If you were reporters/analysts several years ago, you sure didn't miss the party who pre-announced Apple's death, many many times. Apple, from what I read, had been declared dead more than 50 times.

Only a few years before the introduction of iPod, even a board member of Apple was heard saying the company was going bankrupt. Surely, as cool as Mac, it only had 5% of the PC market. It seemed only the cool artists were buying it. Apple has had no short of cool ideas and technologies, but had little success in the market dominated by Windows. What's wrong? Can't cool stuff have a right place? Does cool mean niche?

Apple's huge success proved that a cool product can actually dominate a market. The key though, is to find the cool customers, which Apple did, thanks to the cool youths!

Sun has had no short of cool ideas and technologies. Sun happened to have been a cool company and had cool customers too. So how do you know it won't be hot again?

Well, as a Sun engineer, I'm obviously biased. Go ahead continue your forecast of cloudy days over Sun, be prepared to get a sunglass though, who knows, after 50 forecasts, you might need it :)

Posted at 03:07PM Apr 10, 2009 by joehw in OfLittleImpact  |  Comments[0]

Thursday Mar 12, 2009
JAXP 1.4 no longer supports JDK 1.4, also Performance improvement

We just announced that we no longer support JDK 1.4 in JAXP standalone builds. The main motivation was that we found such requirement made it hard to maintain a synchronized source with JDK6. Recently, we have made some performance improvements which will be in the jdk6 update 14 release. Due to the requirement for supporting JDK 1.4 however, we couldn't put back the same changes we made in jdk6 since features such as generics, StringBuilder were not available in JDK 1.4.

Another consideration was that J2SE 1.4.2 has reached its End of Service Life (EOSL) on October 30th, 2008. It is no longer necessary for JAXP standalone to support JDK 1.4.

So download JAXP 1.4 Weekly or Nightly and give it a test. Our performance team's tests using SPECjvm2007/SPECjvm2008 have shown tremedous performance improvement in certain areas. Besides, there have also been critical fixes such as 6536111 SAX parser throws OutOfMemoryError and 6506304 java.net.MalformedURLException: unknown protoco: c which have "earned" many votes and comments demanding a fix on SDN. These fixes will also be included in JDK6 update 14.

Posted at 10:48AM Mar 12, 2009 by joehw in JAXP  |  Comments[0]

Monday Mar 09, 2009
Developing client application in Sun GlassFish Mobility Platform 1.1

It's always fun to try something new. In the midst of a relatively quiet period in the JAXP project, I had the opportunity to try out the Sun GlassFish Mobility Platform (SGMP) and create my very first mobile application! To me, it has been nothing but fun!

To me, both the SGMP technology and the UI library LWUIT were new. I expected some learning curve. Surprisingly though, the SGMP client API has made it very easy to develop a client application. In all, I found I spent more time trying to twike the look and feels, including customizations over LWUIT implementation. In this and the next blog, I'll share the experiences in implementing the SGMP client API, and using LWUIT to build mobile applications on generic devices as well as Blackberry.

The application I created is a client for the Sun GlassFish Mobility Platform 1.1. It uses the Salesforce connector Rebecca designed to access account on salesforce developer site and demonstrate the ability to manipulate data from a public services such as SalesForce.com developer site via SGMP. The application is included in the SGMP download. See Rebecca's blog on how to install and set up for a test run.

The first design decision is the data model, or in SGMP term, BusinessObject (BO). A business object has a pair (name, blob). Here the name is defined as the unique identifier of the data object. If you have read Rebecca's blog, you know that the Salesforce connector handles a small set of data from the Salesforce developer site, e.g. Account, and Contacts and Tasks for each account, which is basically the first tab in the Salesforce page. It is easy to see that we can use the unique Account ID as the name of the Account object so that the pair looks like (Account ID, Account record). It's slightly tricky for Contacts and Tasks because the API does not currently support relationship. To guarantee the uniqueness, we needed to combine the Account ID and Contact ID or Task ID. See Rebecca's blog on how the BOs were designed.

Once this is decided, the implementation is easy. The BO interface only requires that get/setName are preserved since they meant to get and set the name of the object, and implement the serialize and deserialize methods. This part of work was originally done in the connector, so here we just need to copy the portion of the code from corresponding object classes. The benefit of the copy-n-paste is that it guarantees the contract between the client and connector. The rest of the BO class is up to the needs by the client application itself that includes the getter and setter methods for each field, and methods, in the case of Account, to handle relationships such as adding and removing tasks. Below is a snapshot of the Account class:

public class Account extends BusinessObject2 {
    ...


    public Account(String name, String acctName) {
        super(name, acctName);
    }


    public String getAcctName() {
        return _acctName;
    }

    public void setAcctName(String name) {
        setDisplayName(name);
        this._acctName = name;
    }


     /**
     * add a task and set it as current
     * @param task
     */
    public void addTask(Task task) {
        if (_tasks == null) {
            _tasks = new Vector();
        }
        _tasks.addElement(task);
        setCurrentTaskIndex(_tasks.size() - 1);
    }

    /**
     * Mark task (index) as removed
     * @param index 
     */
    public void removeTask(int index) {
        Task task = (Task)_tasks.elementAt(index);
        _tasks.removeElementAt(index);
        _currentTaskIndex = TASK_NONE;
        if (_tasks.size() == 0) {
            _tasks = null;
        }
        _storage.deleteObject(task);
    }


    public byte[] serialize() throws IOException {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        DataOutputStream dOut = new DataOutputStream(out);

        dOut.writeUTF(Util.serializeChkNullString(_id));
        dOut.writeUTF(Util.serializeChkNullString(_acctNo));
        dOut.writeUTF(Util.serializeChkNullString(_acctName));

        ...

        dOut.flush();
        return out.toByteArray();
    }

    public void deserialize(byte[] array) throws IOException {
        ByteArrayInputStream in = new ByteArrayInputStream(array);
        DataInputStream dIn = new DataInputStream(in);

        _id = Util.deserializeChkNullString(dIn.readUTF());
        _acctNo = Util.deserializeChkNullString(dIn.readUTF());
        _acctName = Util.deserializeChkNullString(dIn.readUTF());
         
        ...

        _tasks = null;
        _contacts = null;
    }
    
}

Once you have your data classes ready, the next thing needs to be done is to configure the synchronization engine to perform sync. The SGMP Sync engine supports six different type of synchronizations. The most commonly used one is the so-called FAST_SYNC which can also be named incremental sync. Fast sync checks both client and server and exchanges only modified data to bring the client and server in sync. In an application therefore, it should be selected as default normally.

In the Salesforce sample application, we provided the ability to clean up local storage so that users may remove the application without worrying about leaving trash data behind. The deletion would obviously break the synchronized status since it was not meant to delete the data on the backend. In case the application may be installed and run again, the synchronization must be done to restore the previous status. The sample application detects an initial sync and does a RESTORE_SYNC to bring over data from server, thus restore previous status. Here's the code:

                _syncMgr.setCredentials(_config.getUsername(),_config.getPassword() + _config.getKey(), _config.getServerURL());
                if (_config.isFirstSync()) {
                    _syncMgr.sync(SyncType.RESTORE_SYNC);
                    _config.setFirstSync(false);
                } else {
                    _syncMgr.sync(getSelectedSyncType(_config.getSyncType()));
                }

Another factor worth noting is that a fast sync only exchanges modification once. In the case of creating new record, an additional sync may be necessary. In the sample application for example, when there is a new task on the client, a fast sync would cause the server to create a new record. However, the client would have no way to know that the backend has added the record with a different key, therefore, the client and server are not completely in sync. The simplest way to handle the issue is to do another sync as we did. However, you have a smarter way to solve the problem without the need for the additional (immediate) sync. I'll leave that to you :)

The next task after synchronization is reading the data. The sync engine provides a mechanism called BusinessObjectStorage which returns a storage engine for use to read and write data. As stated above, the current implementation uses the file system and stores BOs as files. To avoid reading all of the files, the sample application makes use of naming convention to avoid reading files unnecessarily.

The sample application first returns names of all of the BOs and then parses through the list to find Account object to read, and put the Contact and Task objects in a cache. The code looks like this (actual code are in different classes):

        boStorage = syncMgr.getBusinessObjectStorage();  //return storage engine
        Vector files = boStorage.getNames();             //return a complete list of BOs

        for (int i = 0; i < files.size(); i++) {
            String tmpN = (String) files.elementAt(i);
            //- strip file extentions
            String fName = tmpN.substring(0, tmpN.length() - 4);
            String accountId = fName.substring(0, Account.ID_LENGTH);  //by the naming convention, name of Account Object starts with Account ID
            Account account = (Account) _accounts.get(accountId);
            if (account == null) {
                //- found an account by either a task or contact, parent object does not exist yet.  Create it.  The parent will be found later.
                account = new Account(accountId, _storage);
                _accounts.put(accountId, account);
            }

            if (fName.length() > 20) { //either contact or task
                int loc = fName.indexOf(Task.FILE_PREFIX);
                if (loc > -1) { //task
                    account.addTaskFilename(fName); //- Just put in list; process array contents on 1st user selection of account
                } else { //contact
                    account.addContactFilename(fName);
                }
            } else {
                // an account, read it now
                _storage.readObject(account);
                _accountNames.addElement(account.getAcctName());
                _accountIds.addElement(accountId);
            }
        }

This is all that's related to the SGMP client API. The rest is to develop a proper interface to present the data. As you see, the SGMP client API is very easy to use. I actually ended up spending most of the time learning and customizing LWUIT to design the user interface. I will share some of that experience in my next blog.

Posted at 10:54AM Mar 09, 2009 by joehw in Sun  |  Comments[1]

Sunday Feb 03, 2008
Quote: Microsoft-Yahoo the mother of all clusterbombs

I just can't help but laugh when I run into this article. CNet sure have some thoughtful and creative editors.

As people are coming up more key words regarding this event. For me, the Microsoft-Yahoo news can be tagged: aggressive, predatory, desperate, lame.

Remember the days when they were aggressive? They were labeled predatory. The result? They killed off Netscape just like that. Many would hate Microsoft for what they did. But strategically, that's a classic successful case of the strategy "taking away the firewood from under the cauldron". People might say they hated Microsoft, but they didn't hate their free "soup" and they didn't care to supply Netscape with the good and old firewood they badly needed, leaving their cauldron cold.

There may be no need to debate on if the Yahoo Cauldron, which is obviously losing steam, actually worth $44.5 billion. Or if the two teams, each failed to compete with Google, could end up even worse when combined as manifested by many historical combinations. Not to say how users might react to this desperate move -- maybe they'll abandon both and go take a sip of the Google soup. It just made people chuckle on how even Microsoft could be so hopeless against Google.

Maybe it's not a coincidence when Mr. Gates are calling for a Kinder Capitalism, Microsoft is acting like a behaved competitor to Google. Sure Google is a colossus in comparison with Netscape. But sure it's obvious where Google gets their firewood.

It certainly seems, the more aggressive, the smarter. When you're desperate, you tend to make lame decisions.

Here is the story by the way: Microsoft-Yahoo the mother of all clusterbombs.

Posted at 11:49PM Feb 03, 2008 by joehw in OfLittleImpact  |  Comments[0]

Thursday Sep 20, 2007
Writing the XML Declaration using XMLStreamWriter/XMLEventWriter

An issue (sjsxp issue 43) Tatu posted on SJSXP sparked a lot of dicussions in the JAXP Dev mailing list. The main observations on this part of specification are that it lacks the clearness on default encoding, the order of preference among the default, that set when the writer is constructed, and that set by calling writeStartDocument on the XMLStreamWriter or createStartDocument on XMLEventFactory. Also, the specifications of the writeStartDocument methods on XMLStreamWriter do not align well with the createStartDocument methods on XMLEventFactory. I've recorded the findings and added proposal 1 for each section on the StAX.next Discussion page. Please feel free to join our discussion and suggest your proposals.

Thanks.

Posted at 03:28PM Sep 20, 2007 by joehw in JAXP  |  Comments[0]

Wednesday Aug 01, 2007
Open Source, Open Mind, and Open Opportunities

Looking at today's stock price for sunw, we're flat after only a mild rise in the mid of a big increase in Q4 profit. Blame the volatile session if you would or blind investors. Or maybe they just way too smart and had dug things up from those financial numbers and decided to wait-and-see.

It turns out, over the last five years, we had increased our revenue by about 4.5%. In the same period, HP and Dell had over 60%, even IBM had over 12%. But Apple made everyone wish to be an Apple with a stunning 230%. A stock price from $7 to $130, that's what makes it a shining apple.

Ok, we all know they've dropped "computer", shame they couldn't even hold the fame they earned when they invented PC, and now that's not even their major product anymore. Or is it "shame"? Depending on how one sees it, it is the bravest act to recognize the market reality and embrace new opportunities. Of course, one could argue that iPod and iPhone are still extensions to "computer" and ITunes are software services. But that's not the point here. Brilliant ideas could come to anyone, but the one who wins is the one who acts on it bravely with an open-mind.

The world already know we are one of most open-sourced companies;
The world are reading the most open-minded CEO's blog
Hope you (and we) would find it soon that this Sun has bravely opened its arms to new ideas, new opportunities, and opened a revenue stream to your liking :)

Oh, would you regret not buying Sun at such a discount? This fake financial analyst rates sunw a strong buy with a target price to your liking too :)

Posted at 04:11PM Aug 01, 2007 by joehw in OfLittleImpact  |  Comments[0]

Tuesday Jul 03, 2007
Gene-Altered Apple

Before iPod, the Apple was just about the size of the organically grows in my backyard. What happened afterwards surely would amaze everyone who has looked at this chart. So now it's a big huge Apple -- about 17 times bigger than when it announced iPod in Oct. 2001.

How this new-gene has inflated it into such a gigantic apple may be no secret to many. Look how powerful this gene is:
Study: Dr. iPod can double successful heart-condition diagnoses
.

Now it has been rummored that yet another new gene has reproduced into half a million over the weekend!

What's our new gene? Only 12 times needed to get us back to the 60s :)

Posted at 01:59PM Jul 03, 2007 by joehw in OfLittleImpact  |  Comments[0]

Wednesday Apr 18, 2007
Feature for Secure Processing

I recently revisited the release notes for JAXP 1.4.0 and 1.4.1 and felt it's neccessary to update the compatibility guide to give it a more complete description about the current implementation of this feature.

Many of you are already familiar with this feature. But I thought it might be beneficial to people who newly come to JAXP or want to use the default XML processing in J2SE 6.



The secure feature, with a keyword FEATURE_SECURE_PROCESSING, was added in JAXP 1.3/J2SE 5 as described in the compatibility guide. The feature was designed to mitigate security risk exposed by using entity resolution and large constructs that may result in Denial-of-service attack. When the feature is turned on, default limitations are applied to entity expansion (default 64,000) and number of element attributes (10,000). These numbers were experimental in that they were tested on a general platform as having acceptable performance. Users may perform their own tests and reset the limitations. Refer to the Feature for Secure Processing section of the compatibility guide on how to reset the limitations.


Another restriction under the security feature was about extension functions. This security feature can be turned on and off using the factories. Again, please refer to the Feature for Secure Processing section of the compatibility guide.


In JAXP 1.4/J2SE 6, the security feature is turned on by default for DOM and SAX parsers. That is, the JAXP 1.4 RI sets default limitations to entity expansion and number of element attributes. JAXP 1.4 also added a limitation to maxOccur in XML schema as described in JAXP 1.4 Release Notes. The limit to maxOccur was set by default to 5,000. Again, this is experimental number with a reasoning that it happens very rarely in practical applications.



Going forward, we're re-evaluating the current security implementation and thinking that some enhancement might be neccessary. We would love to hear your experiences in securing your application and any comments on this topic. Here's a link to the JAXP Forum. Thanks.

Posted at 10:39AM Apr 18, 2007 by joehw in JAXP  |  Comments[0]

Tuesday Mar 20, 2007
The Java API for XML Processing (JAXP) RI 1.4.1 Release
JAXP 1.4.1 is the first patch release for JAXP 1.4 FCS which was released on Oct. 31, 2006. The JAXP team has worked actively with the community and teams within Sun to have brought many changes and fixes into the code base over the last 5 months. It's a great pleasure to announce the release and availability of the 1.4.1 stable build for download.

I would like to take this opportunity to thank everyone who has helped make this release possible. Thanks to the JAXP community, The Java Technology and XML community, as well as the SJSXP community who have contributed to this project.

On another note, to better serve our community, we have just created the JAXP forum under the Java Web Services and XML category. We'd like to welcome you to participate!
Posted at 11:43PM Mar 20, 2007 by joehw in JAXP  |  Comments[1]

Monday Feb 26, 2007
SJSXP 1.0.1 Release update
Thanks to Jeffrey who brought up the backward compatibility issue of the 1.0.1 release build. We've decided to make it consistent to the JAXP builds and ensure backward compatibility with JDK 1.4. I have just updated both the 1.0.1 release and latest builds in the download area. Thanks.
Posted at 05:13PM Feb 26, 2007 by joehw in JAXP  |  Comments[0]

Friday Feb 16, 2007
SJSXP 1.0.1 Released on Java.net
Sun Java Streaming XML Parser (SJSXP) 1.0.1 has been released on Feb. 14, 2007 and is available for download on Java.net.

The 1.0.1 release is the first since the SJSXP 1.0 FCS on April 11,2006. Thanks to the SJSXP Java.net community and our web services teams, we have been able to provide many updates and fixes to the technology. For a complete change log, please refer to the 1.0.1 Changelog. Among them, there were several issues that all pointed to the Filtered StreamReader. As a result, we've re-written the implementation. I thought it's therefore worth mentioning here.

As we've discussed in the Release Notes, there were two main issues in implementing the filtered stream reader. That is:
(1) On initiating a Filtered StreamReader, should the reader move to an acceptable filtered event?
(2) should the hasNext() method advance the stream in order to test if there is a "next" event?

We've decided to implement "yes" and "yes" to the above questions. The understanding was that hasNext should return an event accepted by the filter, which meant it had to search the stream for one. It might fail a special use case where the underlining stream might be called. But it satisfies usual use cases such as the "while hasNext; get next" pattern. Most important of all, the implementation passes the new TCK completely. We're hoping that this would be addressed when the JSR 173 Maintenance Release 1.1 opens up. We'd appreciate your comments.

Posted at 02:19PM Feb 16, 2007 by joehw in JAXP  |  Comments[0]