Skip to content
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

Add version of UnusedTracker that supports full shrinking using R8. #566

Closed
wants to merge 0 commits into from

Conversation

netomi
Copy link
Contributor

@netomi netomi commented Apr 15, 2020

Pull request for #565 .

@netomi
Copy link
Contributor Author

netomi commented Apr 15, 2020

There are some test failures wrt to exclude settings. I have to look into them, so far I did not take these settings into account.

@netomi
Copy link
Contributor Author

netomi commented Apr 15, 2020

I have fixed the test failures. There is one remaining but this one can not be easily solved when using a full shrinker. The test setup is as follows:

an unused class in an api dependency is implementing an interface from a transitive dependency. This interface is never used or accessed, thus the interface is removed, leaving no trace of it. The test wants to ensure that the interface is not removed (LibEntity). Cases like that are normally not handled by a shrinker, it usually can safely remove such interfaces. If the test would be slightly adapted to a more real world example (LibEntity would be used somehow in the otherwise UnusedEntity), the interface would not be removed and the test would succeed.

Edit: I have updated the last failing test slightly to take the shrinking capabilities of R8 into account.

build.gradle Outdated Show resolved Hide resolved
gradle/dependencies.gradle Outdated Show resolved Hide resolved
@netomi netomi mentioned this pull request May 31, 2020
@covers1624
Copy link

Is there any update on this PR? I am interested in using this functionality.

@bowsersenior
Copy link

It would be nice if we could have some feedback on this PR. It seems very useful from my team's needs.

@@ -98,7 +98,7 @@ public InheritManifest getManifest() {
@Override
protected CopyAction createCopyAction() {
DocumentationRegistry documentationRegistry = getServices().get(DocumentationRegistry.class);
final UnusedTracker unusedTracker = minimizeJar ? UnusedTracker.forProject(getProject(), configurations, dependencyFilterForMinimize) : null;
final UnusedTracker unusedTracker = minimizeJar ? UnusedTrackerWithR8.forProject(getProject(), configurations, dependencyFilterForMinimize) : null;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That choice of using the standard tracker vs the r8 tracker needs to be configurable by the user.
A couple of options here:

  1. Add an useR8 = true option that works in conjunction with minimizeJar to configure the implementation.
  2. Detect the presence of the R8 classes on the classpath and then use the R8 implementation if present.

@@ -15,6 +15,8 @@ dependencies {
exclude group: 'org.ow2.asm'
}

implementation 'com.android.tools:r8:2.0.61'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should make this compileOnly and force the user to add their only r8 dependency so we don't have to maintain the compatibility. This should happened regardless of the extension implementation in the comment below.

this.toMinimize = toMinimize
projectUnits = classDirs.collect { cp.addClazzpathUnit(it) }
projectUnits.addAll(classJars.collect { cp.addClazzpathUnit(it) })
}

boolean performsFullShrinking() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of these methods are necessary in this class since they aren't used by it. If they are only needed by the R8 implementation, then they should reside in that class.

* It is an extension of the existing UnusedTracker to make it easy to exchange them,
* if the pull request is accepted, a common base interface should be extracted.
*/
class UnusedTrackerWithR8 extends UnusedTracker {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could just write this in pure Java in the src/main/java directory if this is a concern.

@CompileStatic
static void addJDKLibrary(BaseCommand.Builder builder) {
String JAVA_HOME = System.getenv("JAVA_HOME")
builder.addLibraryResourceProvider(JdkClassFileProvider.fromJdkHome(Paths.get(JAVA_HOME)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure we can/should rely on this. Perhaps this needs to be exposed to the user directly? We could maybe figure out a default setting based on the configuration of the compileMain task or somethign.

@@ -495,12 +495,12 @@ class ShadowPluginSpec extends PluginSpecification {

file('lib/src/main/java/lib/LibEntity.java') << """
package lib;
public interface LibEntity {}
public interface LibEntity { void simple(); }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should follow appropriate Java styling and put this on a new line for ease of reading. Same for all the changes in this file.

@johnrengelman johnrengelman added this to the 8.0 milestone Aug 8, 2021
@nicolabeghin
Copy link

Any update on this PR? seems really promising! thanks

@netomi
Copy link
Contributor Author

netomi commented Oct 11, 2022

Somehow I missed that changes have been requested to this PR which make total sense and I would be willing to work on them.
In the meantime I worked on my own bytecode manipulation library including a shrinker: https://github.com/netomi/bat and I created a fork of the shadow plugin to use it for relocation and shrinking (still to be done): https://github.com/netomi/gradle-shadow

It takes the current shadow plugin, converts it to kotlin only and uses my bat library for the byte code stuff. Its still very early work, but I will come back to this PR and make it clean to be included. @johnrengelman

@netomi
Copy link
Contributor Author

netomi commented Oct 11, 2022

When I sync'd my PR branch with latest master and reworked the PR the PR was closed as a consequence. I am not sure how to fix that, but I created a new PR at #796 , its a pity that the comments and suggestions are lost somehow, but I hope that suffices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants