Archive for category divertissements

Oracle, Android and the copy claims: SCO all over again?

Second important update: After quite some digging, I have finally found out that the file had the following history:

  • An initial import, from a private branch to the public git repo, with this commitdiff, at Sat, 10 Jan 2009 01:50:54
  • A deletion of the file and of most of the imported branch at Wed, 4 Mar 2009 02:28:14, with this commitdiff
  • The branch got re-imported, with all new files, at Wed, 4 Mar 2009 03:28:47, with this commitdiff, without PolicyNodeImpl.java

So the file was present in the git repo from Jan, 10 to March, 4; after checking the test execution code, it is clear that the code itself was not included in the final build (delivered to handsets) but was part of a test harness, that (funnily) was mostly silenced during the development period due to the majority of tests failing :-) It is however clear that the code itself was distributed, as it was freely accessible online and through the git tree (and – funnily – it is still available under the same means). It was, however, not part of the Android SDK release, as Android 1.6 rel2 was released in December 2009, while rel3 was released in May, with the commit diff already applied.

Important update: I have verified that the code included in Android is actually a decompilation of an old Java 1.5 class file, and my own comparison is invalid, as it was done with a recent Java edition (that does have more changes – thus suggesting a reimplementation). Also, it seems that Harmony actually has not that code in its repo – despite the fact that in Android is part of the initial import under the “Harmony” subproject. My apologies.

Sigh. I had higher hopes for Oracle – while the initial complaint was dull and unsubstantial, the claims of actual copying of source code was an interesting twist (apart from the patents, of course – but that is a totally different world). Now, as ZDnet promptly writes, Oracle amended the complaint, and published the scribd link with the entire text (by the way: the HTML5 version of Scribd really, really rocks. End of parenthesis.) The relevant parts are:

40. Android includes infringing class libraries and documentation. Approximately one third of Android’s Application Programmer Interface (API) packages (available at http://developer.android.com/reference/packages.html) are derivative of Oracle America’s copyrighted Java API packages (available at http://download-llnw.oracle.com/javase/1.5.0/-docs/api/ and http://download-llnw.oracle.com/javase/1.4.2/docs/api/) and corresponding documents. The infringed elements of Oracle America’s copyrighted work include Java method and class names, definitions, organization, and parameters; the structure, organization and content of Java class libraries; and the content and organization of Java’s documentation. Examples of this copying are illustrated in Exhibit I to this complaint. In at least several instances, Android computer program code also was directly copied from copyrighted Oracle America code. For example, as may be readily seen in Exhibit J, the source code in Android’s “PolicyNodeImpl.java” class is nearly identical to “PolicyNodeImpl.java” in Oracle America’s Java, not just in name, but in the source code on a line-for-line basis.”

Hm. First of all, the definition of line-for-line equality is not correct here, as the lines are different (but quite similar). I have not developed for quite some time, but I would say that it is not strange to see similarities within the API constraints. Second, while technically part of Android, the code is Apache Harmony, a reimplementation of J2SE that tried (for many, many years) to get the compliance toolkit from Sun, but never did (and now will never do).

But the relevant point is different: the PolicyNodeImpl.java that is presented comes from the OpenJDK distribution, and was as such released under the GPL+ClassPath exception (something that is not mentioned anywhere within the complaint, by the way). Here, the claims are two and different: the first is that Android (actually, Harmony) copied its API that Oracle claims is copyrighted. The second claim is that the actual source code of the PolicyNodeImpl.java file has been copied verbatim.

Let’s start with the first one: the claim that Oracle Java APIs are protected and copyrighted. On this, it seem to me that the interface definition themselves (not the actual source code) as a mere interface does not fall within the copyright provisions, unless the actual names are trademarked, and thus its implementation requires the actual copying of a protected name in a way that is deemed incompatible by its licensee (something similar was done by Autodesk, embedding a copyrighted phrase that if not included in the file prevented the application from opening it directly). I believe that this is not the case, as the names within the source code seem to lack any “TM” or the direct use of “Java” in a way that may suggest its direct protection as a trademark.I(t should be noted that both “Java” and “OpenJDK” are trademarked, and its use is explicitly forbidden unless the code is a

And now, for the claim that the code is actually copied, here is in its glory the full diff (note: if you download the OpenJDK source you don’t get the file; I had to grab it from here in the Mercurial publication site, the raw file is this one). It seem to me that this is actually a reimplementation and not a straight copy as Oracle claims – but I would like to ask my readers for their opinion.

A disclaimer: I am not a Oracle hater, a Google or Apache fanboy, and I have no relationship with them all.

/*
 *  Licensed to the Apache Software Foundation (ASF) under one or moreCopyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License atDO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 *     http://www.apache.org/licenses/LICENSE-2.0This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the LicenseThis code is distributed on an "AS IS" BASIS,in the hope that it will be useful, but WITHOUT
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressWARRANTY; without even the implied warranty of MERCHANTABILITY or implied.
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the specific language governing permissionsLICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package sun.security.provider.certpath;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.security.cert.*;
/**
 * Implements the <code>PolicyNode</code> interface.
 * <p>
 * This class provides an implementation of the <code>PolicyNode</code>
 * interface, and is used internally to build and search Policy Trees.
 *  limitations underWhile the License.implementation is mutable during construction, it is immutable
 * before returning to a client and no mutable public or protected methods
 * are exposed by this implementation, as per the contract of PolicyNode.
 *
 * @since       1.4
 * @author      Seth Proctor
 * @author      Sean Mullan
 */
package org.apache.harmony.security.tests.support.cert;
import java.security.cert.PolicyNode;
import java.util.*;
publicfinal class PolicyNodeImpl implements PolicyNode {
    /**
     * Use to specify the special policy "Any Policy"
     */
    private static final String ANY_POLICY = "2.5.29.32.0";
    // every node has one parent, and zero or more children
    private PolicyNodeImpl mParent;
    private HashSetHashSet<PolicyNodeImpl> mChildren;
    // the 4 fields specified by RFC 3280
    private String mValidPolicy;
    private HashSetHashSet<PolicyQualifierInfo> mQualifierSet;
    private boolean mCriticalityIndicator;
    private HashSetHashSet<String> mExpectedPolicySet;
    private boolean mOriginalExpectedPolicySet;
    // the tree depth
    private int mDepth;
    private// immutability flag
    private boolean isImmutable;
    public PolicyNodeImpl(PolicyNodeImpl policynodeimpl,isImmutable = false;
    /**
     * Constructor which takes a <code>PolicyNodeImpl</code> representing the
     * parent in the Policy Tree to this node. If null, this is the
     * root of the tree. The constructor also takes the associated data
     * for this node, as found in the certificate. It also takes a boolean
     * argument specifying whether this node is being created as a result
     * of policy mapping.
     *
     * @param parent the PolicyNode above this in the tree, or null if this
     *               node is the tree's root node
     * @param validPolicy a String s,representing this node's valid policy OID
     * @param qualifierSet the Set set,
                   boolean flag,of qualifiers for this policy
     * @param criticalityIndicator a boolean representing whether or not the
     *                             extension is critical
     * @param expectedPolicySet a Set set1,of expected policies
     * @param generatedByPolicyMapping a boolean flag1)indicating whether this
     * node was generated by a policy mapping
     */
    PolicyNodeImpl(PolicyNodeImpl parent, String validPolicy,
                Set<PolicyQualifierInfo> qualifierSet,
                boolean criticalityIndicator, Set<String> expectedPolicySet,
                boolean generatedByPolicyMapping) {
        isImmutable = false;
        mParent = policynodeimpl;parent;
        mChildren = new HashSet();
        if(sHashSet<PolicyNodeImpl>();
        if (validPolicy != null) {
            mValidPolicy = s;
        } else {validPolicy;
        else
            mValidPolicy = "";
        }
        if(setif (qualifierSet != null) {
            mQualifierSet = new HashSet(set);
        } else {HashSet<PolicyQualifierInfo>(qualifierSet);
        else
            mQualifierSet = new HashSet();
        }HashSet<PolicyQualifierInfo>();
        mCriticalityIndicator = flag;
        if(set1criticalityIndicator;
        if (expectedPolicySet != null) {
            mExpectedPolicySet = new HashSet(set1);
        } else {HashSet<String>(expectedPolicySet);
        else
            mExpectedPolicySet = new HashSet();
        }HashSet<String>();
        mOriginalExpectedPolicySet = !flag1;
        if(mParent!generatedByPolicyMapping;
        // see if we're the root, and act appropriately
        if (mParent != null) {
            mDepth = mParent.getDepth() + 1;
            mParent.addChild(this);
        } else {
            mDepth = 0;
        }
    }
    PolicyNodeImpl(PolicyNodeImpl policynodeimpl,
                   PolicyNodeImpl policynodeimpl1)/**
     * Alternate constructor which makes a new node with the policy data
     * in an existing <code>PolicyNodeImpl</code>.
     *
     * @param parent a PolicyNode that's the new parent of the node, or
     *               null if this is the root node
     * @param node a PolicyNode containing the policy data to copy
     */
    PolicyNodeImpl(PolicyNodeImpl parent, PolicyNodeImpl node) {
        this(policynodeimpl, policynodeimpl1.mValidPolicy, ((Set) (policynodeimpl1.mQualifierSet)), policynodeimpl1.mCriticalityIndicator, ((Set) (policynodeimpl1.mExpectedPolicySet)),
        this(parent, node.mValidPolicy, node.mQualifierSet,
             node.mCriticalityIndicator, node.mExpectedPolicySet, false);
    }
    public PolicyNode getParent() {
        return mParent;
    }
    public IteratorIterator<PolicyNodeImpl> getChildren() {
        return Collections.unmodifiableSet(mChildren).iterator();
    }
    public int getDepth() {
        return mDepth;
    }
    public String getValidPolicy() {
        return mValidPolicy;
    }
    public SetSet<PolicyQualifierInfo> getPolicyQualifiers() {
        return Collections.unmodifiableSet(mQualifierSet);
    }
    public SetSet<String> getExpectedPolicies() {
        return Collections.unmodifiableSet(mExpectedPolicySet);
    }
    public boolean isCritical() {
        return mCriticalityIndicator;
    }
    /**
     * Return a printable representation of the PolicyNode.
     * Starting at the node on which this method is called,
     * it recurses through the tree and prints out each node.
     *
     * @return a String describing the contents of the Policy Node
     */
    public String toString() {
        StringBuffer stringbufferbuffer = new StringBuffer(asString());
        for(Iterator iteratorStringBuffer(this.asString());
        Iterator<PolicyNodeImpl> it = getChildren(); iterator.hasNext(); stringbuffer.append((PolicyNodeImpl)iterator.next()));
        while (it.hasNext()) {
            buffer.append(it.next());
        }
        return stringbuffer.toString();buffer.toString();
    }
    // private methods and package private operations
    boolean isImmutable() {
        return isImmutable;
    }
    /**
     * Sets the immutability flag of this node and all of its children
     * to true.
     */
    void setImmutable() {
        if(isImmutable)  return;
        PolicyNodeImpl policynodeimpl;
        for(Iterator iterator = mChildren.iterator(); iterator.hasNext(); policynodeimpl.setImmutable())
            policynodeimpl = (PolicyNodeImpl)iterator.next();if (isImmutable)
            return;
        for (PolicyNodeImpl node : mChildren) {
            node.setImmutable();
        }
        isImmutable = true;
    }
    private/**
     * Private method sets a child node. This is called from the child's
     * constructor.
     *
     * @param child new <code>PolicyNodeImpl</code> child node
     */
    private void addChild(PolicyNodeImpl policynodeimpl)child) {
        if(isImmutable)
        if (isImmutable) {
            throw new IllegalStateException("PolicyNode is immutable");
        } else {
            mChildren.add(policynodeimpl);
            return;
        }
        mChildren.add(child);
    }
    void/**
     * Adds an expectedPolicy to the expected policy set.
     * If this is the original expected policy set initialized
     * by the constructor, then the expected policy set is cleared
     * before the expected policy is added.
     *
     * @param expectedPolicy a String representing an expected policy.
     */
    void addExpectedPolicy(String s)expectedPolicy) {
        if (isImmutable) {
        if(isImmutable)
            throw new IllegalStateException("PolicyNode is immutable");
        if(mOriginalExpectedPolicySet)}
        if (mOriginalExpectedPolicySet) {
            mExpectedPolicySet.clear();
            mOriginalExpectedPolicySet = false;
        }
        mExpectedPolicySet.add(s);mExpectedPolicySet.add(expectedPolicy);
    }
    void/**
     * Removes all paths which don't reach the specified depth.
     *
     * @param depth an int representing the desired minimum depth of all paths
     */
    void prune(int i)depth) {
        if(isImmutable)
        if (isImmutable)
            throw new IllegalStateException("PolicyNode is immutable");
        if(mChildren.size()// if we have no children, we can't prune below us...
        if (mChildren.size() == 0)
            return;
        Iterator iteratorIterator<PolicyNodeImpl> it = mChildren.iterator();
        do
        while (it.hasNext()) {
            if(!iterator.hasNext())  break;
            PolicyNodeImpl policynodeimplnode = (PolicyNodeImpl)iterator.next();
            policynodeimpl.prune(i);
            if(policynodeimpl.mChildren.size()it.next();
            node.prune(depth);
            // now that we've called prune on the child, see if we should
            // remove it from the tree
            if ((node.mChildren.size() == 00) && i(depth > mDepth + 1)
                iterator.remove();1))
                it.remove();
        } while(true);
    }
    void/**
     * Deletes the specified child node of this node, if it exists.
     *
     * @param childNode the child node to be deleted
     */
    void deleteChild(PolicyNode policynode)childNode) {
        if(isImmutable)
        if (isImmutable) {
            throw new IllegalStateException("PolicyNode is immutable");
        } else {
            mChildren.remove(policynode);
            return;
        }
        mChildren.remove(childNode);
    }
    /**
     * Returns a copy of the tree, without copying the policy-related data,
     * rooted at the node on which this was called.
     *
     * @return a copy of the tree
     */
    PolicyNodeImpl copyTree() {
        return copyTree(null);
    }
    private PolicyNodeImpl copyTree(PolicyNodeImpl policynodeimpl)parent) {
        PolicyNodeImpl policynodeimpl1newNode = new PolicyNodeImpl(policynodeimpl,PolicyNodeImpl(parent, this);
        PolicyNodeImpl policynodeimpl2;
        for(Iterator iterator = mChildren.iterator(); iterator.hasNext(); policynodeimpl2.copyTree(policynodeimpl1))
            policynodeimpl2 = (PolicyNodeImpl)iterator.next();
        for (PolicyNodeImpl node : mChildren) {
            node.copyTree(newNode);
        }
        return policynodeimpl1;newNode;
    }
    Set/**
     * Returns all nodes at the specified depth in the tree.
     *
     * @param depth an int representing the depth of the desired nodes
     * @return a <code>Set</code> of all nodes at the specified depth
     */
    Set<PolicyNodeImpl> getPolicyNodes(int i)depth) {
        HashSet hashset
        Set<PolicyNodeImpl> set = new HashSet();
        getPolicyNodes(i, ((Set) (hashset)));HashSet<PolicyNodeImpl>();
        getPolicyNodes(depth, set);
        return hashset;set;
    }
    private/**
     * Add all nodes at depth depth to set and return the Set.
     * Internal recursion helper.
     */
    private void getPolicyNodes(int i, Setdepth, Set<PolicyNodeImpl> set) {
        if(mDepth
        // if we've reached the desired depth, then return ourself
        if (mDepth == i)depth) {
            set.add(this);
        } else {
            PolicyNodeImpl policynodeimpl;
            for(Iterator iterator = mChildren.iterator(); iterator.hasNext(); policynodeimpl.getPolicyNodes(i, set))
                policynodeimpl = (PolicyNodeImpl)iterator.next();for (PolicyNodeImpl node : mChildren) {
                node.getPolicyNodes(depth, set);
            }
        }
    }
    Set getPolicyNodesExpected(int i,/**
     * Finds all nodes at the specified depth whose expected_policy_set
     * contains the specified expected OID (if matchAny is false)
     * or the special OID "any value" (if matchAny is true).
     *
     * @param depth an int representing the desired depth
     * @param expectedOID a String s,encoding the valid OID to match
     * @param matchAny a boolean flag)indicating whether an expected_policy_set
     * containing ANY_POLICY should be considered a match
     * @return a Set of matched <code>PolicyNode</code>s
     */
    Set<PolicyNodeImpl> getPolicyNodesExpected(int depth,
        String expectedOID, boolean matchAny) {
        if (expectedOID.equals(ANY_POLICY)) {
        if(s.equals("2.5.29.32.0"))
            return getPolicyNodes(i);
        elsegetPolicyNodes(depth);
        } else {
            return getPolicyNodesExpectedHelper(i, s, flag);getPolicyNodesExpectedHelper(depth, expectedOID, matchAny);
        }
    }
    private SetSet<PolicyNodeImpl> getPolicyNodesExpectedHelper(int i, String s,depth,
        String expectedOID, boolean flag)matchAny) {
        HashSet hashset
        HashSet<PolicyNodeImpl> set = new HashSet();
        if(mDepthHashSet<PolicyNodeImpl>();
        if (mDepth < i)depth) {
            PolicyNodeImpl policynodeimpl;
            for(Iterator iterator = mChildren.iterator(); iterator.hasNext(); hashset.addAll(policynodeimpl.getPolicyNodesExpectedHelper(i, s, flag)))
                policynodeimpl = (PolicyNodeImpl)iterator.next();
            for (PolicyNodeImpl node : mChildren) {
                set.addAll(node.getPolicyNodesExpectedHelper(depth,
                                                             expectedOID,
                                                             matchAny));
            }
        } else if(flag) {
            if(mExpectedPolicySet.contains("2.5.29.32.0"))
                hashset.add(this);
        }
            if (matchAny) {
                if (mExpectedPolicySet.contains(ANY_POLICY))
                    set.add(this);
            } else if(mExpectedPolicySet.contains(s)) {
            hashset.add(this);
                if (mExpectedPolicySet.contains(expectedOID))
                    set.add(this);
            }
        }
        return hashset;set;
    }
    Set/**
     * Finds all nodes at the specified depth that contains the
     * specified valid OID
     *
     * @param depth an int representing the desired depth
     * @param validOID a String encoding the valid OID to match
     * @return a Set of matched <code>PolicyNode</code>s
     */
    Set<PolicyNodeImpl> getPolicyNodesValid(int i,depth, String s)validOID) {
        HashSet hashset
        HashSet<PolicyNodeImpl> set = new HashSet();
        if(mDepthHashSet<PolicyNodeImpl>();
        if (mDepth < i)depth) {
            PolicyNodeImpl policynodeimpl;
            for(Iterator iterator = mChildren.iterator(); iterator.hasNext(); hashset.addAll(policynodeimpl.getPolicyNodesValid(i, s)))
                policynodeimpl = (PolicyNodeImpl)iterator.next();
            for (PolicyNodeImpl node : mChildren) {
                set.addAll(node.getPolicyNodesValid(depth, validOID));
            }
        } else if(mValidPolicy.equals(s)) {
            hashset.add(this);
            if (mValidPolicy.equals(validOID))
                set.add(this);
        }
        return hashset;set;
    }
    private static String policyToString(String s)oid) {
        if(s.equals("2.5.29.32.0"))
        if (oid.equals(ANY_POLICY)) {
            return "anyPolicy";
        } else {
            return s;oid;
        }
    }
    /**
     * Prints out some data on this node.
     */
    String asString() {
        if(mParentif (mParent == null) {
            return "anyPolicy  ROOT\n";
        StringBuffer stringbuffer} else {
            StringBuffer sb = new StringBuffer();
        int
            for (int i = 0;
        for(int j0, n = getDepth(); i < j;n; i++)
            stringbuffer.append(" {
                sb.append("  ");
        stringbuffer.append(policyToString(getValidPolicy()));
        stringbuffer.append("
            }
            sb.append(policyToString(getValidPolicy()));
            sb.append("  CRIT: ");
        stringbuffer.append(isCritical());
        stringbuffer.append("
            sb.append(isCritical());
            sb.append("  EP: ");
        for(Iterator iterator = getExpectedPolicies().iterator(); iterator.hasNext(); stringbuffer.append(" "))
            for (String policy : getExpectedPolicies()) {
            String s = (String)iterator.next();
            stringbuffer.append(policyToString(s));
                sb.append(policyToString(policy));
                sb.append(" ");
            }
            sb.append(" (");
            sb.append(getDepth());
            sb.append(")\n");
            return sb.toString();
        }
        stringbuffer.append(" (");
        stringbuffer.append(getDepth());
        stringbuffer.append(")\n");
        return stringbuffer.toString();
    }
}

,

19 Comments

Everydesk online: a full desktop as a Facebook application

I am quite proud of the work that we did on EveryDesk – a full desktop as a bootable USB key, fully modifiable and adaptable. We are using it in schools, public administrations and companies, where the increased efficiency of Linux makes a difference in making old computers usable again – or helping in the problem of managing PCs that are remote or in hostile environments.

However, this is not enough. You may be without a USB-bootable computer, or you may be using a tablet like an iPad or a Galaxy Pad (something that I see more and more everywhere). In these environments, you may need something more powerful than the apps that are available there – a full Office-like application, or a real desktop browser to access a corporate banking application; maybe you need a specific client for older systems, like the IBM iSeries (the old AS/400) or some special client in Java – on system that do not have java or flash.

For this kind of applications, we are working on a system that embeds a full HTML5 desktop in a FaceBook application, making it accessible from any recent web browser, including the iPad. This way, you can have a full desktop everywhere you go. We hope that it can be of interest; as soon as it is ready, we will release source code and blueprints.

We have prepared a small demo of how it works right now; it is a real screen capture from my own personal EveryDesk/Online instance, done on a normal ADSL line. It should give an idea on how it may work for you.

,

2 Comments

Google vs. Facebook: two separate markets

Just a few days ago it was announced that according to ComScore, people spent more time on Facebook than Google; something that prompted a wide variety of claims from “google is dead” to “facebook will become the internet” or something similar. The reality is that FB and GOOG are moving in two different markets, and the failure of previous social experiments like Orkut or Buzz is actually related to the fact that Google internal machinery, so sophisticated and tailored to help manage “the world’s information”, is not appropriate for something like social sites.

In fact, Google manages everything with the assumption that data is, in some sense, relevant and useful in a generic sense, at least for a subset of its users. The concept of “usefulness” is at the core of the famous PageRank algorithm; it uses the idea that links and connections are a substitute proxy for “interest” – and mixes in the background information on who links what to create and propose potential links that maximize the probability that someone searching will go through and find something that is, well, interesting. This way, the said user will come back to Google to search something, and this will bring back more ad revenues.

This is good and correct – unless it’s data that is ephemeral, like the massive amount of drivel that is generated by social site users. The updates on Facebook users’ walls are mostly uninteresting for anyone not part of the same social circle – knowing that “Justin just spilled its coke on all its textbooks! What fun!” is probably relevant to people that know Justin, whoever he is, and maybe some textbook vendor, that will probably get a new customer. The value of Facebook is in its inclusiveness, that is the fact that a large number of social groups of all sizes are within the same platform, and share at least partly the same social graph. But – there is no need of a PageRank on the backoffice of Facebook search, as all the search that is necessary is already structured within the (user generated) social graph itself.

That’s why Google seem unable to turn its social acquisition into something integrated within its own services: the engine behind Google is tailored for a different set of parameters – and useless for social sites. Which is a pity, because some of the technology that Google developed to address this market (like Wave) was quite interesting, but – again – simply ill suited to such a market.

1 Comment

Web versus Apps: what is missing in HTML5

If there is a concept that is clear in the analysts’ minds is the fact that mobile (in any form) is the hot market right now. Apple’s iOS devices are growing by leaps and bounds, dispelling the doom predictions of our beloved Ballmer: “There’s no chance that the iPhone is going to get any significant market share. No chance. … 2% or 3%, which is what Apple might get” or dismissing the iPad as “yet another pc”. The reality is that new mobile platform are consolidating a concept -  the idea of the App store, that is an integrated approach to managing and buying applications – and the idea of “apps for everything”, even for data that comes off straight from a web site, like the recently launched Twitter app for the iPad, that is – in my own, clearly subjective opinion – beautiful.

After all the talks about platform independence, portability, universality of HTML5, and so on  – why Apps? why closed (or half-open) app stores, when theoretically the same thing can be obtained through a web page? I have a set of personal opinion on that, and I believe that we still need some additional features and infrastructures from browsers (and probably operating systems) to really match the feature set and quality of apps. If – or when – those missing pieces are delivered to the browser, the whole development experience will in my opinion return back to the web as a medium, substantially enlarging the potential user base and reducing the importance of a single OS to develop for.

User Interfaces: this is, actually, one of the easiest things. HTML5, CSS3, Canvas, and a whole bunch of additions (like WebGL) are already closing in on the most refined native UI toolkits. There is still a margin – of course – but that gap is closing fast. Modern toolkits like Cappuccino (one of my favorites, used to create the stunning 280slides tool) are quite comparable to native UIs, and the few remaining features are being added at a frantic pace (thanks in part to the healthy competition between Mozilla and WebKit).

Video: actually, WebM is in my tests a very good alternative to H264, in terms of quality and in decoding efficiency (in my tests, WebM playback uses 20 to 30% less CPU than the ffmpeg H264 decoder, which is quite a good result). As for quality, the results of MSU graphics and media lab codec comparison found out that WebM is approximately equivalent to the baseline x264 encoding; that is, good enough for most applications. The substantial drawback of WebM is at the moment the dreadful encoding time – 5 to 20 times slower than comparable, more mature encoders. Substantial effort is needed before WebM can become encoding-wise competitive.

2D and casual gaming: ah, the hard point of gaming on the web. Up to now, gaming has been mainly relegated to the Flash engine, and is one of the parts still not replicated well by HTML5, Javascript et al; in fact, Flash is quite important for the casual gaming experience, and some quite stunning games are based on flash, and comparable to native games (if you want to waste some time, look at RoboKill2 as an example).However, given the fact that no fully compatible open source flash player exist, there are still issues with the real portability and platform independence of flash gaming in general (despite the excellent improvements in Gnash and LightSpark; also, it may even be possible to see in the future a native translator to Javascript like the SmokeScreen project. Actually, there is a great deal of overlap of Flash with recent evolutions of Canvas/HTML5/Javascript – it is clear that the overall evolution of the open web platform is going in the direction of integrating most of flash functionalities directly within HTML.

3D gaming: There is at the moment no way to create something like the Epic Citadel demo, or Carmack’s RAGE engine on iOS. The only potential alternative is WebGL, that is (like the previous links) based on OpenGL 2.0 ES, and paints on the HTML5 canvas (that, in the presence of proper support for hardware compositing, should allow for complex interfaces and effects). The problem is that browser support is still immature – most browsers are still experimenting in an accelerated compositing pipeline right now, and there are still lots of problems that need to be solved before the platform can be considered stable. However, after the basic infrastructure is done, there is no reason for not seeing things like the current state of the art demos on the web; modern  in-browser Javascript JIT are good enough for action and scripting, web workers and web sockets are stable enough to create complex, asynchronous event models. It will take an additional year, probably, until the 3D support is good enough to see something like WoW inside a browser.

Local binary execution: for those things that actually cannot be done by a browser, local execution is the only alternative. For example, having a complex VPN client embedded in a web page is something that would simplify the task of connecting to a web (or non-web) in an easy way without downloading any additional package. This model was demonstrated by Google in its ChromeOS presentation, showing off a game based on the Unity web player, ported to the Native Client (NaCl) environment. The problem of the initial implementation of NaCl was that the binary was actually not portable across cpu architectures; the new pNaCl (portable NaCl) uses the incredibly good LLVM infrastructure to generate portable bytecodes.

Payment: there is one thing that is sorely missing or incomplete, and that is billing and payment management from the web application. Within iOS, and thanks to iTunes and carrier interactions, paying even in-game or in-app is easy and immediate. There is no similar ease of use and instant monetization within web applications, at the moment. One of the missing things is actually the overall management of digital identities, that is inextricably linked to the payment possibilities and channels.

DRM: yes, DRM. Or content protection, or whatever. Despite the clear indication that DRM schemes do not work, there is no shortage of studios or content producer that want to ensure that there is at least a minimum form of “protection” against unwanted use. I don’t believe that this form of protection is useful at all, but I am not confident in people accepting this in the next 5 years – and this means that DRM should be possible in the context of the browser. Possible alternatives are the use of a ported content execution engine (imagine a video player based on pNaCl, that brings its own DRM engine inside). Or integrating an open source DRM engine like DReaM (if it survives the Oracle changeover, that is). This kind of tool can also help to prevent cheating in online games (imagine a WoW like game, based on Javascript: what prevents the user to change the code on the fly with something like GreaseMonkey?) and other multiplayer environments.

App stores: what is an app store?  A tool to reduce searching costs, and in Apple iTunes model a framework for app management and backup. In a sense, something like this is possible right now with some browser/OS integration (the excellent Jolicloud has something like that right now, and with some additional support for web packaging formats and remote synchronization like Mozilla Sync this can become ubiquitous).

What do you think? Is there something else missing? Comments are, as usual, welcome…

, , ,

5 Comments

Windows phone 7, Android, and market relevance

Updated: despite the Business Insider claims, the list of motives is actually a perfect copy of those mentioned by Steve Ballmer in a CNN interview, and I also found that the list of motives for the claimed inferiority of Android is actually from 2008, as can be found here. I found quite funny that basically the same motivations apply two years later for a different OS (in 2008 it was Windows Mobile 6.5, a totally different operating system), and are quite similar to the list of motivations from MS to avoid open source – namely, inferior user experience, hidden costs and IPR risks. Maybe Microsoft has not changed so much as it would like to claim.

A recent Business Insider post provided, other than a nice retouched photo of Google’s Schmidt with menacing red eyes, a snippet of conversation with an anonymous MS employee that claimed that Android “free” OS is not free at all, and its costs are much higher than the $15 asked by Microsoft as licensing fees. Having had my stint on mobile economics, I would like to contribute some of my thoughts on what is actually implied by the MS employee, and why I believe that some parts of it are not accurate. Before flaming me as a Google fanboy, I would like to point out that I am not affiliated with Google, MS, anyone else (apart my own company, of course), and my cellphone is a Nokia. Enough said.

OEMs are not using the stock Android build. All Android OEMs are bearing costs beyond “free.” That goes with the definition of OEM – it is hardly a surprising idea. My gripe with the phrase is that the author had, conveniently, conflated the concept of “free” as “freely available operating system” with “free as in I have nothing to do, everything is done for me for free”. The second concept is actually quite uncommon, and I had never met an OEM product manager that believed in something like that. It reminds me a lot of the old taglines used in the infamous MS “comparisons”, that were – with blessings from all – sacked from Microsoft web site. So, in conclusion: yes, you will bear costs other than downloading Android from GIT. And – surprise – I am sure MS will ask for engineering costs for adapting WinPhone7 for any adaptation outside the stock image.

Lawsuits over disputed Android IP have been costly for Android OEMs. (See Apple/HTC, as just one example.) Microsoft indemnifies OEMs who license Windows Phone 7 against IP issues with the product. That is, legal disputes over the IP in Windows Phone 7 directed at OEMs will be handled by Microsoft. This goes a long way toward controlling legal costs at the OEM level. Ah, please, Microsoft – you are so friend of OSS, and you still drum the “IPR violation” song? Anyway, I am quite sure that indemnification can be quite easily acquired, probably from Google or from a third party. It depends on the kind of IPR that the OEM itself does have; in some cases such a patent safety scheme is uneconomical. It is, in any case, a business decision – Symbian did not had indemnification either (or only as an additional product) but that did not stopped Symbian from becoming the most widely used mobile OS.

Android’s laissez faire hardware landscape is a fragmented mess for device drivers. (For background, just like PCs, mobile devices need drivers for their various components—screen, GPS, WiFi, Bluetooth, 3G radio, accelerometer, etc.) Android OEMs have to put engineering resources into developing these drivers to get their devices working. The Windows Phone 7 “chassis strategy” allows devices to be created faster, saving significant engineering cost. It’s essentially plug and play, with device drivers authored by Microsoft. This (apart from the use of the clearly pejorative mention of “fragmented mess” is naturally true. It is also – another surprise – the reason of Windows success, namely the external ecosystem of hardware devices, mostly unpredictable, that were basically developed and managed outside of Microsoft control. After much bashing of Apple’s “walled garden”, now Microsoft seem to imply that the same model that brought them success is now useless, and that to win in mobile you have to adopt Apple centrally managed hardware experience. It may be true, or not – but I suspect that hardware manufacturers will be more happy to create many permutation and device models, designed for different price points and different users, in a way that would be incompatible with MS central control and central device driver development. What happens if I need to push on the market a device that deviates from the MS chassis? Will MS write the driver for me, for free? What if it doesn’t want to write it? The chassis model is nice if you are Apple, and are selling basically a single (or a few) models; if you are going to market with many hardware vendors, you are forcing the same, undifferentiated hardware on all OEM – and this is a great no-no. How are you going to go against competitors that do employ exactly the same model, bill of material, same procurement channel?

Also, this phrase is a clear indication that someone inside of MS still don’t understand what (real) open source is about. The amount of engineering necessary for creating a complex product out of OSS is substantially lower than proprietary alternatives, as I demonstrated here and here; the driver development effort can easily be shared among many different projects that use the same component, lowering the development costs substantially.

Windows Phone 7 has a software update architecture designed to make it easy for OEMs to plug-in their custom code, independent of the OS code. We’ve seen the delays due to Android OEMs having to sink engineering resources into each and every Android update. Some Android OEMs skip updates or stop updating their less popular devices. Because of the unique update architecture, Windows Phone 7 OEMs don’t need to roll their own updates based on the stock build. Costs are reduced significantly. This is another part that is, until Phone 7 is out, difficult to judge. It is a part that I believe stems from an underlying error: OEMs add code to differentiate and to push branded apps and services, not because they have to compensate for an OS missing functionality (especially now, with Android 2.2; Android 1.5 and 1.6 needed some addition from third parties because of lack of features). Carriers, once sold a device, are not that interested in providing updates – after all, you are already locked in a contract. I had seen no official documentation on why Phone7 can be so modular that no engineering is needed even for custom layers on top of the user interface – we will see.

Android OEMs need to pay for licenses for many must-have features that are standard in Windows Phone 7. For example, software to edit Office documents, audio/video codecs (see some costs here), or improved location services (for this, Moto licenses from Skyhook, just as Apple once did). Of course, all of these license fees add up. I like the concept of “must have” – it is widely different for every user and company. For example, I am sure that using Google Docs or Zoho (or Microsoft Web office, that is quite good on its own) would go against the “edit Office documents” part; as for the audio/video codecs, of course you have to license them… unless you use WebM or similar. Or, like many OEM, you are already a licensee for H264 and other covered standards-  in this case, you pay around 1$ per device. As for other services: I found no mention of location services from MS, at least not in the public presentations. If anyone has more details on them, I would welcome any addition.

Windows Phone 7 supports automated testing. Android doesn’t. When OEMs hit the QA phase of the development lifecycle, it’s faster and less expensive to QA a Windows Phone 7 device than an Android device. Again: if you have a single chassis, or a few of them, testing is certainly easier. However, there are quite a few testing suites that allow (through the emulator) to provide a very good automated testing facility.

Finally, Windows Phone 7 comes with great user experiences in the Metro UI, Zune, Xbox LIVE, Exchange, and Visual Studio for app development. Creating these experiences for Android is costly. They’re not baked into the stock build of Android. Well, there are quite a few tools for app development on Android as well. How, exactly, Exchange should be counted as a great user experience is something I am not understanding well, but that is probably a limit of mine.

In synthesis, the new MS concept is “we do it like Apple”. I am not sure that this can work for anyone that is not Apple, though; first of all, because up to now product engineering excellence was not among MS most touted virtues, and because this will in turn go against the differentiation trend that OEM and telcos are pushing to make sure that their brand lines remain unique and appealing enough. How many Phone7 devices can a telco carry? 1? 2? It is possible to imagine a custom Android device for every price point instead – some carriers like Motorola and HTC are already pushing 5,6 devices and more, and low cost handsets are adding even more to the segmentation mix.

, , ,

4 Comments

Oracle, Sun, Java: lawsuits mark the exit road

I already wrote a few words on the Oracle/Google lawsuits here and here, and I would like to thank all those that found them interesting enough to read and comment on. I found recently a very interesting post by Java author extraordinaire, James Gosling, where he answers on some of his readers’ comments. In the post there are many interesting ideas, and a few points that I believe are not totally accurate – or better, may be explained in a different way. In particular, I believe that the role of Java in the enterprise will remain and will become “legacy”, that is stable, plain and boring, while the real evolution will move from Java to… something else.

James clearly points out the fact that JavaME fragmentation was a substantial hurdle for developers, and believes that in a lesser way this may be true for Android as well. While it is true that fragmentation was a problem for Java on mobile, this was a common aspect of mobile development at the time (go ask a Windows Mobile developer about fragmentation. And see a grown man cry, as the song says). The problem of JavaME was not fragmentation, but lack of movement – the basic toolkits, the UI components, most of the libraries for one reason or the other remained largely unchanged apart a few bug fixes. JavaFX should have been promoted much, much earlier, and would have had a great impact on software development, like (I believe) the more recent Qt releases from Nokia and their idea of declarative user interfaces.

If we compare with the rest of Java, we see a much stronger push towards adding libraries, components, functionalities: all things that made Java one of the best choices for software developers in the enterprise space, because the developers can trust Sun to update and extend their platform, making their job easier and faster. It was the same approach that made Microsoft the king of software: create lots of tools and libraries for developers, sometimes even trying to push more than one approach at a time to see what sticks (like Fahrenheit) , or trying very experimental and skunkworks approach, that later are turned into more mature projects (like WinG). JavaEE and JavaSE followed the same model, with a consistent stream of additions and updates that created a confidence in developers – and, despite all the naysayers, for enterprise software Java was portable with very little effort, even for very large applications.

JavaME was not so lucky, and partly to guarantee uniform licensing Sun was forced to do everything on their own (a striking difference with Android, that – if you check the source code – included tons of external open source projects inside) limiting the rate of growth attainable. Some features that now we take for granted (like web browsing) were not included as default, or implemented by vendors in inconsistent way because Sun never gave guidance on the roadmap and product evolution; multimedia has been mostly an afterthought, usually forcing developers to create (or buy) external libraries to implement anything more complex than a video or audio player. As I wrote before: JavaFX should have been announced much, much earlier, and not as a reactive answer to the competition, but as part of a long-term roadmap that JavaEE had, while the rest of Java missed.

This is, in my opinion, one of the real reasons for the lawsuit: Sun (now Oracle) was unable to create and maintain a real roadmap outside of JavaEE (and partly JavaSE), and especially for JavaME they constantly followed – never led. This, as any developer will tell you, is never a good position; it’s full of dust and you miss all the scenery. So, since Oracle is really more interested in their own markets (the DB and the applications) and not really caring about software developers, ecosystems or openness, they probably believe that lawsuits do have a better return on investment.

,

7 Comments

Oracle/Google: the strategy behind Sun, Oracle and the OSS implications

In my previous post, I tried to provide some details on what in my opinion were the most relevant legal and licensing aspects of the recently launched Oracle lawsuit against Google. I would like now to provide some perspective on what may have been the motives behind this lawsuit, and what are the possible implications for the Java and Open Source communities.

First of all, it is clear that, as I mentioned before, Google turned the lawsuit into a positive event for their (slightly battered) public image. By turning the lawsuit against Android into an attack to the open source community, Google effectively created a positive image, as David unjustly accused by the Oracle giant. It is also clear that the lawsuit itself is actually quite weak, focusing on a copyright claim that is very vague (given the fact that Google never claimed to use Java), and a set of patent claims for techniques that are probably not relevant anymore (especially in the post-Bilski era). One of the possible reasons for this is to be sure that even the widely different Dalvik machine would be at least partially covered; the other is the fact that all of Classpath was included in the OIN “System Components” covered technologies. Since both Oracle and Google are part of OIN, I suspect that Oracle wanted to avoid any potential complication coming from this “broken marriage”.

But – this is not the only relevant aspect. Actually, an angle that is probably more important is the impact of the lawsuit on Java, Java for mobile, Android and the OSS communities that were part of the Sun technology landscape.

Enterprise Java: no change at all. Java is a very strong brand among corporate developers, and I doubt that the lawsuit will change anything at all; in fact, all the various licensee of the Java full specification are on perfectly legal grounds, and face no problem at all. Despite the opportunistic claims by Miguel De Icaza (that suggests that Mono/C# would have been a better choice), there is nothing in the lawsuit that would imply that other Java or Java-related technologies may be impacted (actually, Mono and the CLR are in the same situation as Dalvik, actually).

Mobile Java: as I mentioned before, the lawsuit put the last stone on the JavaME grave. The only potentially relevant route away from the land of the dead could have been JavaFX; that was too little, too late – incomplete, missing several pieces, missing a roadmap, and uselessly released as a binary-only project. Android  used the Java language, extended it with mobile-specific classes that were more modern and more useful for recent smartphones and even non-phone applications (like entertainment devices, automotive and navigation devices). It is not a surprise, that coupled with the Google brand name, Android surged in popularity so much as to become a threat.

Oracle OSS projects: Oracle has always been an opportunistic user of open source. With the term “opportunistic” I am not implying any negative connotation: simply the observation that Oracle dabbled in open source whenever there was an opportunity to reduce its own research and development costs. If you look at oracle projects, it is clear that all projects are related to infrastructural functionality for the Oracle run-time and for developers tools (using Eclipse as a basis). I was not able to find any “intrinsic” open source project started or adopted by Oracle that was not focused on this approach. So, for those projects, I believe that there will be no difference; for example, I believe that the activity on the Oracle-sponsored BTRFS project will not change significantly. Oracle, actually does not care at all if they are seen as “enemies”, or if their projects are not used anymore by others. What they care for is for their patches to be included in Linux. Remember that Oracle is an “old style” company; it does have two basic product lines: its database and its set of enterprise applications. Everything else is not quite necessary, and probably will be abandoned.

Sun OSS projects: as for Sun, there is a long preamble first. Sun has always been, first and foremost, an engineering company – something like Silicon Graphics in the past, or more recently Google. Sun had open sourced something of value whenever it was necessary to establish a common platform or protocol, like NFS or NIS+; but it was the advent of Jonathan Schwartz that actually turned things towards open source. The ponytailed CEO tried to turn the Sun behemoth towards a fully open strategy, but was unable to manage the conversion before being ousted out. It is a pity, actually – Sun could have leveraged its size, large number of technical partners and amount of technologies to become a platform provider like RedHat – but 10 times larger. The problem of this strategy is that it implies a large amount of cooperative development, and thus a substantial downsizing of the company itself. The alternative could have been the use of an open-core like strategy, for example creating a scalable JVM designed to auto-partition code execution on network of computers. The basic JVM could have been dual licensed, with the enhanced one released on a proprietary basis; this could have leveraged the exceptional Sun expertise in grid and parallel computing, filesystems and introspection systems.

But Sun never managed to complete the path – it dwindled left and right, with lots of subprojects that were started and abandoned. The embracing of PostgreSQL, its later abandonment, the latter embrace of MySQL, that was then not integrated anywhere; the creation of substantial OSS projects from their proprietary offering, but then losing interest as soon as a project started to become a threat for the proprietary edition. There is no surprise that despite the incredible potential, Sun never recouped much of their OSS investment (despite the great growth in their latest quarters, the OSS services remained a small portion of their revenues). Now that Oracle has taken control, I believe that Sun “openness” will quickly fade towards small, utilitarian projects – so, even if now everyone looks at Oracle with anger, noone at Oracle could care less.

Why oracle sued? The blogosphere is exploding with possible answers; my own two hypothesis are:

  • Oracle found a substantial technology it acquired (Java) losing value in what is the hottest tech market today, namely mobile systems. Sun had no credible plan to update JavaME, no credible alternative, and thus Android (that is loosely java based) is at the same time a threat to an acquired asset and (from their point of view) a stolen technology. Since anyone can follow the same path, Oracle wants to make sure that noone else would try to leverage Java to create an unlicensed (and uncontrolled) copy.
  • Oracle wants a piece of the mobile enterprise market, and the alternatives are unavailable (Apple does not want anything to do with Java, Blackberry is a JavaME licensee, Windows Mobile is backed by arch-rival Microsoft). Android is working well, grows incredibly fast, and Oracle wants a piece of it; Google probably rebuffed initial contacts, and now Oracle is showing the guns to make Google obey. I am skeptical, however, that Google would back down on what is becoming its most important growth path. The lawsuit itself is quite weak, and Google would risk too much by licensing the TCK from Oracle; they would basically destroy their opportunity for independent development. It is never a good idea to corner someone – if you leave no alternative, fight is the only answer.

I believe that the first one is the most probable one; Larry Ellison should know that cornering Google would not be sufficient to make them capitulate – they have too much to lose. But this will not be sufficient to create an opportunity for Oracle; I believe that the lawsuit will actually bring nothing to Oracle, and lots of advantages to Google. But only time will tell; the only thing that I can predict for sure right now is that Solaris will quickly fade from sight (as it will be unable to grow at the same rate of Linux) exactly like AIX and HP-UX: a mature and backroom tech, but nothing that you can base a growth strategy upon.

,

14 Comments

Oracle/Google: the patents and the implications

Just as LinuxCon ended, Oracle announced that it has filed suit for patent and copyright infringement against Google for its implementation of Android; as an Oracle spokesperson said, “In developing Android, Google knowingly, directly and repeatedly infringed Oracle’s Java-related intellectual property. This lawsuit seeks appropriate remedies for their infringement … Android (including without limitation the Dalvik VM and the Android software development kit) and devices that operate Android infringe one or more claims of each of United States Patents Nos. 6,125,447; 6,192,476; 5,966,702; 7,426,720; RE38,104; 6,910,205; and 6,061,520.” (some more details in the copy of Oracle complaint). Apart from the slight cowardice of waiting after LinuxCon for announcing it, the use of the Boies Schiller legal team (the same of SCO) would be ironic on its own (someone already is calling the company SCOracle).

The patent claims are:

Let’s skip the patent analysis for a moment, and let’s focus on the reasons behind this. Clearly, it is a move typical of mature industries: when a competitor is running past you, you try to put a wrench in its engine. That is a typical move, and one of the examples of why doing things by the book in this modern, collaborative world is wrong. Not only that, but I believe that previous actions by Sun made this threat clearly useless – even dangerous.

Let’s clear the table from the actual patent claims: the patent themselves are quite broad, and quite generic; a good example of what should not be patented (the security domain one is a good example; look at the sheet 5 and you will find the illuminating flowchart with the representation of: do you have the rights to do it? if yes, do it, if no, do nothing. How brilliant). Also, Dalvik implementation is quite different from the old JRE one, and I have strong suspicions that the actual Dalvik method is substantially different. But, that is not important. I believe that there are two main points that Oracle should have checked before filing the complaint (but, given the use of Schiller&Boies, I believe that they have still to learn from the SCO debacle): first of all, Dalvik is not Java and Google never claimed any form of Java compatibility. Second, there is a protection for patents as well, just hidden in recent history.

On the first point: in the complaint, Oracle claims that “The Android operating system software “stack” consists of Java applications running on a Java-based object-oriented application framework, and core libraries running on a “Dalvik” virtual machine (VM) that features just-in-time (JIT) compilation”. On copyrights, Oracle claims that “Without consent, authorization, approval, or license, Google knowingly, willingly, and unlawfully copied, prepared, published, and distributed Oracle America’s copyrighted work, portions thereof, or derivative works and continues to do so. Google’s Android infringes Oracle America’s copyrights in Java and Google is not licensed to do so … users of Android, including device manufacturers, must obtain and use copyrightable portions of the Java platform or works derived therefrom to manufacture and use functioning Android devices. Such use is not licensed. Google has thus induced, caused, and materially contributed to the infringing acts of others by encouraging, inducing, allowing and assisting others to use, copy, and distribute Oracle America’s copyrightable works, and works derived therefrom.”

Well, it is wrong. Wrong because Google did not copied Java – and actually never mention Java anywhere. In fact, the Android SDK produced Dalvik (not Java) bytecodes, and the decoding and execution pattern is quite different (and one of the reasons why older implementations of Dalvik were so slow – they were made to conserve memory bandwidth, that is quite limited in cell phone chipsets). The thing that Google did was to “copy” (or – for a better word – inspire) the Java language; but as the recent SAS-vs-WPS lawsuit found, “copyright in computer programs does not protect programming languages from being copied”. So, unless Oracle can find pieces of documentation that were verbatim lifted from the Sun one, I believe that the copyright part is quite weak.

As for patents, a little reminder: while copyright covers specific representations (a page of source code, an Harry Potter book, a music composition), software patents cover implementations of ideas, and if the patent is broad enough, all possible implementation of an algorithm (let’s skip for the moment the folly of giving monopoly protection on ideas. You already know how I think about it); so, if in any way Oracle had, now or in the past, given full access to those patents through a licensing that is transferable, Google is somehow protected there as well. And – guess what? That really happened! Sun released the entire Java JDK under the GPLv2+classpath exception; granting with that release full rights of use and redistribution of the IPR assigned on what was released. This is different from the TCK specification, that Google wisely never licensed; because the TCK license requires for the patents to be transferred to limit the development to enhancements or modifications to the basic JDK as released by Sun.

But, you would say, Dalvik is independent from OpenJDK, so patents are not transferred there. So, include the code that is touched by the patents from the OpenJDK within Dalvik – compile it, and make a connecting shim, include it in a way that is GPLv2 compatible. The idea (just an idea! and IANAL of course..) is that through the release of the GPL code Sun gave an implicit license to embedded patents that is connected with the code itself. So, if it is possible to create an aggregate entity of the Dalvik and OpenJDK code, the Dalvik one would become a derivative of the GPL license, and would obtain the same patent protection as well. That would be a good use of the GPL, don’t you think?

What will be the result of the lawsuit? First of all, the open source credibility of Oracle, already damaged by the OpenSolaris affair, is now destroyed. It is a pity – they have lots of good people there, both internal and through the Sun acquisition; after all, they are among the 10 largest contributors to the Linux kernel. That is something that will be very difficult to recover.

Second, Google now has a free, quite important gift: the attention has been moved from their recent net neutrality blunder, and they are again the David of the situation. I could not imagine a better gift.

Third, with this lawsuit Oracle basically announced the world that Java in mobile is dead. This was actually something that most people already knew – but seeing it in writing is always reassuring.

Update: Miguel de Icaza claims that “The Java specification patent grant patent grant seems to be only valid as long as you have a fully conformant implementation”, but that applies only to the Standard Implementation of Java, not OpenJDK. Sorry Miguel – nice try. More luck next time.

Update 2: cleaned the language on the phrase on patents, ideas and implementation that was badly worded.ù

Update 3: clarified the Dalvik+OpenJDK idea.

, ,

34 Comments

About contributions, Canonical and adopters

It is always strange to see the savage infighting that sometimes happens in the free and open source world – sometimes, like red in front of a bull, the net suddenly lights their flame-throwers and decides to roast someone. Today’s target is Canonical, makers of the Ubuntu distribution, accused of being leeches and “stealing” from the open source communities, giving little or nothing back, and profiting from that. The issue emerged from the publication of the Gnome census, where it emerged that Canonical As Sam Varghese writes, “Canonical derives the base for Ubuntu from the Debian project. It takes liberally from many free and open source software projects to produce a distribution.  While this distribution is available for free download, Canonical is also basing a business on it, and developing ways and means of making money off Ubuntu.” (which is, probably, a crime). He wrote something similar before, and  Greg DeKoenigsberg has an even more vitriolic argument in his post “Red Hat, 16%. Canonical, 1%”, that happily buries under the ground Canonical, Ubuntu and most Ubuntu fanboys.

Well, you’re all wrong.

Not because the percentages are wrong (but nearly useless, as Canonical is relatively recent and RedHat is not, because Gnome is only one of the projects and there are many others, etc.) but because they measure too little. I already wrote in the past about the enormous effort that goes to non-code contributions, and that no-one measures (as for OpenOffice, there are more contributors in non-code parts than in code); there is also a substantial effort in creating a product out of contributions. And Ubuntu certainly invested in product engineering, marketing, even engineering (less than Red Hat? So what? Large IT consulting companies are getting paid millions for open source-based systems, and I never saw a contribution at all). When Matt Asay claims that bringing Ubuntu to million of people is a contribution, he is claiming an absolute truth; every time Canonical manages to bring a press release out it is making a huge contribution. Maybe less code than others, but this is not a beauty contest – this is a cooperative effort for building a better future, not a race to see who is the nicest or worked harder. It is true that Canonical (I hope) profits from OSS: well, it is one of the most important thing for OSS, as it demonstrates that OSS is sustainable, that people can live off OSS services and products, all the while improving our world. I repeat: maybe someone at Red Hat is not happy of the visibility of Canonical, given all the contributions they do? I am sorry – and I am quite happy to show at all my talks that Red Hat is an incredibly good and well-managed company, that has open sourced all the proprietary products it acquired – and invests an incredible amount of effort in engineering in the open. I like them a lot (no, I don’t work for them, and never did use one of their services), but I like Canonical as well, because they are investing heavily in the desktop market, a market that is not the focus of Red Hat any more and that I believe is quite important.

This is not a contest. We should be happy for every, small, large, strange or different contributions that we receive. Should it be more? Maybe. But don’t overlook all those things that are being done, some of them outside of pure code. Because, as I wrote in the past, there is much more than code in an OSS project.

2 Comments

On WebM, H264, and FFmpeg implementation

 I was recently reminded by Gregory Maxwell of Xiph about the new, non-Google implementation of VP8 done within the context of FFmpeg, and many commenters on Slashdot observed that the fact that the implementation shares lots of code with the H264 part is further demonstration that VP8 is infriging on MPEG-LA held patents.

Actually, there is nothing in the implementation that suggests this, only the fact that some underlying alogrithms are similar (but not identical). For example, the entropy coder is quite similar, and it certainly helps to reuse some of the highly optimized librarties that are within FFMPEG, this is however no indication of patent infringement. What is certain, is the fact that I suspect that libVPX (Google implementation) will remain the “official” one, because there is no guarantee that in the alternative implementation the current IPR safeguards and efforts to avoid existing patents will be done properly. In fact, some of the obvious “missing optimizations” both in the decoder and encoder are clearly done to avoid patents, and this means that Google can be reasonably sure of being safe from IPR claims for the current code drop. If a FFMPEG developer implements some optimization (especially in the encoder) that actually implements a claimed part of a current patent you can end up with a freely implemented source code that implements an IPR-covered claim, like most of FFMPEG actually.

So, to end up this brief post: the existence of a parallel implementation of libvpx is a good thing; the fact that it shares lots of code with FFMPEG is no proof of IPR infringement, but on the other hand it is probably safer to use the libvpx one from Google, as it seems that it was developed explicitly to avoid existing IPR issues.

, ,

4 Comments