As part of the Apache NetBeans IP clearance we are combing through all the code and dependencies.
One interesting thing we bumped into was that the jsch 0.1.54 binary JAR we are using has a different hash (and size) than the binary JAR from Maven Central.
The old hash is 0D7D8ABA0D11E8CD2F775F47CD3A6CFBF2837DA4, the new one is DA3584329A263616E277E15462B387ADDD1B208D.
The binaries are 278,612 bytes vs 280,515 bytes in Maven Central.
Our version is actually the same as the one found on http://www.jcraft.com/jsch/
Also, the Maven JAR is properly signed with the author's CA7FA1F0 key.
This is where it becomes clear that reproducible builds are important. You do not want to have to wonder why a binary differs, especially years later when you are doing a review. And this one is a library doing SSH!
So, why the different binaries?
It seems the original JAR was compiled on Aug 30, 2016 with Java 1.4 (major version 48) while the Maven Central JAR was compiled Sep 3, 2016 with Java 5 (major version 49).
The original JAR also concatenates strings using StringBuffer while the Maven Central JAR uses the newly introduced in 1.5 StringBuilder. Which should also be a bit faster since it's not synchronized.
Next, most of the cypher classes use some reflection via a static static java.lang.Class class$(java.lang.String) method.
What is this? It's just the way class literals worked in Java 1.4. As explained here, in Java 5 the ldc_w instruction was introduced to load a Class object.
In 1.4 the class literal was helped by the compiler by actually introducing the helper Class class$(java.lang.String className) method and replacing the Person.class with a class$("Person") call.
It conclusion, it seems that excluding the Java 1.4 to Java 5 compiler changes, the two JARs are identical. With the Maven Central JAR even a bit better due to StringBuilder being used.
There is no check so far that the sources do produce the specific JAR. This is an exercise left for the reader.
Note: I have also cross-posted this blog post to the Apache NetBeans blog.
One interesting thing we bumped into was that the jsch 0.1.54 binary JAR we are using has a different hash (and size) than the binary JAR from Maven Central.
The old hash is 0D7D8ABA0D11E8CD2F775F47CD3A6CFBF2837DA4, the new one is DA3584329A263616E277E15462B387ADDD1B208D.
The binaries are 278,612 bytes vs 280,515 bytes in Maven Central.
Our version is actually the same as the one found on http://www.jcraft.com/jsch/
Also, the Maven JAR is properly signed with the author's CA7FA1F0 key.
This is where it becomes clear that reproducible builds are important. You do not want to have to wonder why a binary differs, especially years later when you are doing a review. And this one is a library doing SSH!
It seems the original JAR was compiled on Aug 30, 2016 with Java 1.4 (major version 48) while the Maven Central JAR was compiled Sep 3, 2016 with Java 5 (major version 49).
The original JAR also concatenates strings using StringBuffer while the Maven Central JAR uses the newly introduced in 1.5 StringBuilder. Which should also be a bit faster since it's not synchronized.
Next, most of the cypher classes use some reflection via a static static java.lang.Class class$(java.lang.String) method.
What is this? It's just the way class literals worked in Java 1.4. As explained here, in Java 5 the ldc_w instruction was introduced to load a Class object.
In 1.4 the class literal was helped by the compiler by actually introducing the helper Class class$(java.lang.String className) method and replacing the Person.class with a class$("Person") call.
It conclusion, it seems that excluding the Java 1.4 to Java 5 compiler changes, the two JARs are identical. With the Maven Central JAR even a bit better due to StringBuilder being used.
There is no check so far that the sources do produce the specific JAR. This is an exercise left for the reader.
Note: I have also cross-posted this blog post to the Apache NetBeans blog.