Skip to main content

The Mystery of the PolicyNodeImpl Class

Posted by cayhorstmann on November 15, 2010 at 2:50 AM PST

When Oracle, in its Android lawsuit, accused Google of copyright violation, I didn't think this was going to stick. I was pretty surprised when the PolicyNodeImpl comparison made its rounds a couple of weeks ago.

The complete “Exhibit J” is here.

There was a flurry of idle speculation, much of which could have been avoided by a bit of research.

  • It was pretty obvious that the Google version was produced by a decompiler. No programmer would write
        PolicyNodeImpl(PolicyNodeImpl policynodeimpl, 
                       PolicyNodeImpl policynodeimpl1) {
            this(policynodeimpl, policynodeimpl1.mValidPolicy,
            ((Set) (policynodeimpl1.mQualifierSet)),
            policynodeimpl1.mCriticalityIndicator,
            ((Set) (policynodeimpl1.mExpectedPolicySet)), false);
        }

    The variable names are obviously synthesized, and there is no point in casting the sets to Set (or, if you felt the urge to cast, to surround the result in more parentheses).

  • The Sun implementation is from J2SE 5.0, which you can download here. You can get the JDK source from here.
  • There aren't many decompilers around, and it doesn't take long to try them all. It turns out that JAD is the culprit. Download JAD from here. Extract sun/security/provider/certpath/PolicyNodeImpl.class from the J2SE 5.0 jre/lib/rt.jar and run jad     PolicyNodeImpl.class. You get a file PolicyNodeImpl.jad that contains exactly the same constructor as above.

    In fact, except for the location of the fields and minor formatting, the decompiled file is identical to that in Exhibit J. (Actually, there is a significant difference. The Android class is public, where the Sun class is non-public and final. Someone speculated that the programmer decompiled the code in order to subclass it. Huh? The tests need to run without the Sun JDK, so it doesn't matter whether Sun's implementation is final.)

  • The actual Android file is here. Note that it has an Apache license header.
  • The file is not a part of Apache Harmony. (Otherwise you'd see it here.)
  • It's easy to get the entire Android source. Using grep, you can see that PolicyNodeImpl is used by a single Java file, libcore/security/src/test/java/tests/security/cert/PolicyNodeTest.java. It is not a part of the actual OS that's on the phone.
  • I was curious if there were more decompiled files. I decided to look for files containing tokens of the form SomeClassName     someclassname, where the class name had length > 10 and at least two capitalized letters, and the variable name was all lowercase. (Here is the program I used.) I found 23 instances in the Android source tree. Most seemed innocuous when I looked at them, but a few were fishy, such as AclImpl.java, AclEntryImpl.java, and PrincipalImpl.java in libcore/support/src/test/java/org/apache/harmony/security/tests/support/acl. Compare with the J2SE 5.0 classes in src/share/classes/sun/security/acl. Interestingly, these too have an Apache header but are not part of Harmony.

Those are the facts. Now it is my turn to speculate. I figure someone decompiled a few files out of laziness, slapped the Apache license header on them without waiting for acceptance by Apache, and then forgot all about it when those files were never used for anything significant. That all is, of course, reprehensible.

You can find Google's response here. Note this quote:

Google further denies that the document attached to Oracle's Amended Complaint as Exhibit J contains a true and correct copy of a class file from either Android or "Oracle America's Java." Google states further that Oracle has redacted or deleted from the materials shown in Exhibit J both expressive material and copyright headers that appear in the actual materials, which are significant elements and features of the files in question.

That is disingenuous. Sure, Oracle took out the copyright headers, but if you look at the exhibit and the source files, the rest is complete.

Does it mean that Oracle hit paydirt? I don't think so—the copying was trivial in the grand scheme of things. (I assume that there wasn't any more egregious copying, or Oracle would have made hay of that.) Why did Oracle parade it to the media, even though they surely knew that it didn't amount to a hill of beans? Probably because they felt that copying code could be easily understood, and it would give them some good PR. Why didn't the Google lawyers admit that there was some minor hanky-panky going on? Probably because they didn't want to explain it—it's complicated.

All is fair in love and war, I suppose. It just doesn't make it easy for an onlooker to find out what is actually happening. Lesson learned: Don't trust the lawyers, don't trust the blog comments, but look at the source.

Related Topics >>

Comments

The Mystery of the

Here is a diff between the two versions (decompiled JDK 6 vs. Android):
http://wklej.org/id/419233/

The Mystery of the

Can somebody please check whether what I wrote in my latest post is correct? Thanks.

The Mystery of the

A good examination of the situation which unfortunately has a slight misconception: "I figure someone decompiled a few files out of laziness, slapped the Apache license header on them without waiting for acceptance by Apache". The Apache license can be used by _anyone_, not just Apache. As such, Apache do not need to give permission for the license to be 'slapped on'. Apache would need to approve any addition to Apache Harmony. (or perhaps thats waht you meant?)
Its also the case that anyone can write code in the Harmony package namespace without it being written by or for the ASF. This problem of shared package use confused the issue in PolicyNodeImpl.

The Mystery of the

@scolebourne: You are absolutely right, of course. I used "slapped on" to describe a state of mind. What I imagine (with zero evidence) is someone who just pasted in the license statement with no thought of what they were doing.

It is also possible that the

It is also possible that the class was decompiled from the OpenJDK version of the class which is GPLed.

It is also possible that the

@wwwizard: Instead of speculating whether that is possible, why don't you run JAD on JDK6 rt.jar and tell us whether the result is identical to the Harmony code. The JDK 6 source differs from the JDK 5 source.

It is also possible that the

<p>Only there isn't a OpenJDK for 5.0, so its be far more likely a developer would decompile from 5.0 classes rather than from 6.0 knowing the generics would vanish due to erasure: http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/5672a2be515a/src/share/cla... </p>
<p>Showing the above file in the court and trying to explain how the same proprietary code becomes GPL could confuse matters. Confuses me sometimes.</p>