Every one us is an Infrigner May 12, 2014
Okay, everybody who touches Java bytecode
The Oracle v. Google holds that copying the Structure, Sequence, and Organization of the Java APIs is a copyright violation. And a copyright violation is not just the act of copying, but also applies to all the intermediate parties that have a copy of the work.
That's anybody who writes/compiles any JVM language and anyone who has a JAR file on any device they posses... including a Java ME applet on your old Motorola flip phone. In fact, the JVM in all its incarnations is so pervasive, it's likely that every adult in every industrialized nation has some JVM running someplace.
And every non-Sun/Oracle JAR files has a copy of some or all of the Java API embedded in it because it's technically necessary to include a shadow of the API in compiled bytecode in order to invoke the API.
Let me demonstrate.
Here's a perfectly legal Java program that I wrote and I own the copyright to:
public class HelloWorld {
public static void main(String[] args) {
int strlen = 0;
for (int x = 0; x < args.length; x++) {
strlen += args[x].length();
}
System.out.println("Hello, world, you passed in "+args.length+" arguments, "+
"total size: "+strlen);
}
}
Nothing in there looks infringing. I run the program through the OpenJDK
Java compiler, javac
which results in a HelloWorld.class
file.
According to how the industry has used Java and compilers in general,
the resulting bytecode is a derivative work of the source code and
I own the copyright in the source code.
So, let's take a look at the resulting bytecode, disassembled with
javap
:
dpp@crown:~/proj/dpp-blog/images$ javap -c HelloWorld
Compiled from "HelloWorld.java"
public class HelloWorld {
public HelloWorld();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iconst_0
3: istore_2
4: iload_2
5: aload_0
6: arraylength
7: if_icmpge 25
10: iload_1
11: aload_0
12: iload_2
13: aaload
14: invokevirtual #2 // Method java/lang/String.length:()I
17: iadd
18: istore_1
19: iinc 2, 1
22: goto 4
25: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
28: new #4 // class java/lang/StringBuilder
31: dup
32: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V
35: ldc #6 // String Hello, world, you passed in
37: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
40: aload_0
41: arraylength
42: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
45: ldc #9 // String arguments,
47: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
50: ldc #10 // String total size:
52: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
55: iload_1
56: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
59: invokevirtual #11 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
62: invokevirtual #12 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
65: return
}
Oh my... look, some of the Java APIs snuck right into the code.
In fact, the JVM requires the call site (the place where code is called) to include information about the API that's being called in order for the JVM to figure out the method to be called. And not just the method name, but also the parameter types passed in and the expected return type.
So each and every compiled JAR contains some part of the Java API embedded in it. Each and every compiled JAR file is a copyright violation under the Oracle decision.
"But," you say, "the JAR file doesn't contain all of the disputed API."
First, how much is enough. The Oracle court explicitly rejected the argument that the APIs were a small part of the overall work of the Java base classes and that percentage arguments were not persuasive.
Second, for repositories like Maven Central that house tens of thousands of JAR files, substantially all of the Java APIs are copied into the collective works that are housed in those JAR files.
What to do?
If I were hosting a ton of JAR files, I'd be on the phone to my lawyers
trying to figure out what to do. Yeah, maybe there's an inducement argument
because Oracle distributes javac
and therefore is inducing me
to copy the Java APIs. But still, it's a technical violation of
the Oracle court's decision.
If I were the Apache Software Foundation or the Free Software Foundation, I'd be filing an ex parte motion this morning to get a stay of the Oracle decision because it means that what we've been thinking is our software that we can license on our open terms in fact contains Oracle copyrighted code and we will have to suspend all of our JVM-related open source projects.
Oh, and I should point out that if Oracle claims that the APIs copied into the JAR files are not covered by copyright, then all Google has to do is pull all the JAR files from Maven Central, find all the Java API references in all those JAR files and use that information to declare an API for Android. That's about 10 man-days of effort, at most.