luontola / retrolambda

Backport of Java 8's lambda expressions to Java 7, 6 and 5
Apache License 2.0
3.54k stars 227 forks source link

Inconsistent library versions reminder. #158

Closed kaifeng-h closed 4 years ago

kaifeng-h commented 4 years ago

Hi. I have implemented a tool to detect library version inconsistencies. Your project have 1 inconsistent library.

Take com.google.guava:guava for example, this library is declared as version 11.0.2 in end-to-end-tests, 18.0 in retrolambda-maven-plugin and etc... Such version inconsistencies may cause unnecessary maintenance effort in the long run. For example, if two modules become inter-dependent, library version conflict may happen. It has already become a common issue and hinders development progress. Thus a version harmonization is necessary.

Provided we applied a version harmonization, I calculated the cost it may have to harmonize to all upper versions including an up-to-date one. The cost refers to POM config changes and API invocation changes. Take com.google.guava:guava for example, if we harmonize all the library versions into 28.2-android. The concern is, how much should the project code adapt to the newer library version. We list an effort table to quantify the harmonization cost.

The effort table is listed below. It shows the overall harmonization effort by modules. The columns represents the number of library APIs and API calls(NA,NAC), deleted APIs and API calls(NDA,NDAC) as well as modified API and API calls(NMA,NMAC). Modified APIs refers to those APIs whose call graph is not the same as previous version. Take the first row for example, if upgrading the library into version 28.2-android. Given that 10 APIs is used in module retrolambda, 0 of them is deleted in a recommended version(which will throw a NoMethodFoundError unless re-compiling the project), 10 of them is regarded as modified which could break the former API contract.

Index Module NA(NAC) NDA(NDAC) NMA(NMAC)
1 retrolambda 10(15) 0(0) 10(15)
2 retrolambda-maven-plugin 4(6) 0(0) 1(1)
3 end-to-end-tests 0(0) 0(0) 0(0)

Also we provided another table to show the potential files that may be affected due to library API change, which could help to spot the concerned API usage and rerun the test cases. The table is listed below.

Module File Type API
retrolambda-maven-plugin retrolambda-maven-plugin/src/main/java/net/orfjackal/retrolambda/maven/ProcessClassesMojo.java modify com.google.common.io.Files.write(java.lang.CharSequence,java.io.File,java.nio.charset.Charset)
retrolambda retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/MethodKind.java modify com.google.common.base.MoreObjects.toStringHelper(java.lang.Object)
retrolambda retrolambda/src/main/java/net/orfjackal/retrolambda/interfaces/MethodKind.java modify com.google.common.base.MoreObjects.ToStringHelper.toString()
4 .. .. ..

If you are interested, you can have a more complete and detailed report in the attached PDF file. orfjackal retrolambda.pdf

luontola commented 4 years ago

It’s on purpose.

kaifeng-h commented 4 years ago

@luontola Sorry for that false positive. So.. is the purpose mainly due to the incompatible guava version which could means a lot of effort to harmonize or something else? Will you explain it in detail? You reply means a lot to the tool and I am trying to improve it in the future.

BTW, the way I see inconsistencies, is that they works, most of the time as just fine. But sometimes an inconsistent version of library may behave different while developers still believe that they have the right version running in runtime, which causes unnecessary time to finally sort it out how an error happens.

luontola commented 4 years ago

Guava 11 is used in the end-to-end tests module because it's the last version which works on Java 5 and the tests need to work also on Java 5 (this is also mentioned in the dependency's comment). The core modules use Java 8.

Retrolambda is a special project in that it backports bytecode to older Java versions. This involves having to deal with the small differences between Java versions (here's a recent example). To test it, I even use a Docker container which contains every major Java version from 5 to 13 (see the build script).

kaifeng-h commented 4 years ago

Thanks a lot for your kind explanation~ We will take the runtime into consideration.