-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Examine performing compilation against API JARs #8
Comments
As a follow up from the reddit discussion I'd like to add. That
|
Definitely. We already use ASM to perform other tasks in the build system so this should be easy.
Note that determining the set of JARs that need to be present for the compilation is not the scope of this issue. This is the responsibility of the dependency resolution algorithm/repository. E.g. Maven, or saker.nest For saker.nest, we already do this by making it possible to declare a dependency For Maven, I'm not sure at the moment how it handles this use-case, maybe something with dependency scopes?
I agree in this. It makes no sense to perform API extraction in every build. There are two scenarios that come up:
For clean builds, the API extracted versions of a JAR should only be used if it is directly available from an already populated cache. If it is not, then the extraction shouldn't be performed as part of the build, as that would most likely only slow it down.
For incremental builds, the extraction can be performed, and cached in the build directory. In the next builds, it will be faster, as the previously made JAR can be reused without performing the whole operation again. Repository caching The repositories could make the API versions of a JAR available by performing the extraction ahead of time, or on-demand, but caching them in the repository somewhere.
I personally wouldn't be a fan of caching the extracted JARs in the Maven repository. It may or may not disturb other build tools in some way that we don't forsee. I think caching the JARs in a saker.build specific location is more appropriate. |
There is one more angle to look into this. API-jars can be sometime identical between artifact's versions. I don't know personally if this use-case is worth catering for, but in case when a user updates a dependency version and the new version has the same API-jar as the old version we can prevent rebuilding anything. |
It is. We already perform some compilation avoidance based on the signatures of the classpath classes, and this use-case integrates well in the current implementation of the Java compiler task. It should be noted that this is a rare use-case. I think it is acceptable (and sometimes advisory) to perform a clean build when some dependency is updated for the project. Incremental builds tend to shine the most when the changes are mininal, while updating a dependency is considered to be a greater one IMO. |
As suggested on Reddit, the compilation performance could be improved by compiling against API JARs instead of full implementation JARs.
This can be achieved by taking the impl JARs and performing API extraction on them. Every non-anonymous class should be in it (even private ones) and every non-private members. Module-info and package-infos as well.
The private and package-private classes should be present, as there may be declarations that expose them as:
In the second iteration of the issue, we may perform deep analysis of the accessability of non-public elements, however, it may be unfeasible, as the analysis may incure greater performance cost than the improvement.
Solution
This shouldn't be performed by the compiler task itself. This is the responsibility of the code that sets up the input classpath. Therefore a solution could be to introduce a new build task that performs the API extraction. Something along the lines of:
Another thing that could be examined is if repositories are able to directly provide compilation input JARs. If a JAR is uploaded to some common repository, it could perform the API extraction themselves, and provide it alongside of the implementation JAR. Therefore, if the client wants to compile for the given JAR, it could download the API instead of the implementation. However, if they want to use it, they can download the implementation as usual.
This issue may be moved from this repository.
The text was updated successfully, but these errors were encountered: