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

Tasks that use jdeps analyzer #983

Closed
wants to merge 43 commits into from

Conversation

esword
Copy link
Contributor

@esword esword commented Oct 17, 2019

Before this PR

Maven dependency analyzer has several shortcomings, including those that lead to:
#847
#614

Plus, the current analyzer tasks cache everything which can lead to OoMs with large projects.

After this PR

==COMMIT_MSG==
New dependency analyzer yields cleaner results and tasks store output in files so better
caching and analysis can be reused for other purposes
==COMMIT_MSG==

Possible downsides?

Possibly slightly slower since don't cache contents of all jars across projects.

@changelog-app
Copy link

changelog-app bot commented Oct 17, 2019

Generate changelog in changelog/@unreleased

Type

  • Feature
  • Improvement
  • Fix
  • Break
  • Deprecation
  • Manual task
  • Migration

Description

New dependency analyzer yields cleaner results and tasks store output in files so better
caching and analysis can be reused for other purposes

Check the box to generate changelog(s)

  • Generate changelog entry

@policy-bot policy-bot bot requested a review from CRogers October 17, 2019 18:32
@esword
Copy link
Contributor Author

esword commented Oct 17, 2019

I have not moved over the existing tasks to use the new analysis file yet. The file is useful on it's own if we want to make that a separate PR, or can do as part of this one.

The gradle APIs that use resolved items will be deprecated eventually.
so best not to use them.  This also reduces memory overhead.
Gradle task validation would fail if the directory already existed with
the other annotation.
the classpath configuration has "runtime" varients for artifacts that
allow it to look at classes directories rather than jars.  This avoids
errors because project-dependencies may not always have jars generated.
Now generates a stub output file so that downstream tasks don't bomb.
Looks like ABSOLUTE is relative to the root project
will merge in Analyzer to the task to avoid duplication
Copy link
Contributor

@CRogers CRogers left a comment

Choose a reason for hiding this comment

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

I didn't manage to allocated as much time as I wanted to review this, still need to test it out locally.

@@ -58,6 +61,10 @@ gradlePlugin {
id = 'com.palantir.baseline-exact-dependencies'
implementationClass = 'com.palantir.baseline.plugins.BaselineExactDependencies'
}
baselineDependencyPluginv2 {
id = 'com.palantir.baseline-dependencies-v2'
implementationClass = 'com.palantir.baseline.plugins.BaselineDependencyPluginv2'
Copy link
Contributor

Choose a reason for hiding this comment

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

We should just replace it entirely if we have confidence it's good. If we have lower confidence we should take a gradle property to excavate it out rather than an entirely new task (this allows us to track adoption and easily excavate the changes).

return report;
}

public static final class ReportContent {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would use immutables here as it will build this class for you and handle the yaml dumping by generating the correct jackson classes as well, meaning we don't need snakeyaml.

}

/**
* Dependencies that are declared in one of the given configurations but not used in byte code. This will only
Copy link
Contributor

Choose a reason for hiding this comment

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

Does it detect things like Class.forName(...) or other dynamic class loading?

import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

public final class DependencyUtils {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think most of these public classes should be package-private.

}

static void writeDepReport(File file, DependencyAnalysisTask.ReportContent content) {
Yaml yaml = new Yaml();
Copy link
Contributor

Choose a reason for hiding this comment

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

We should try to use jackson rather than snakeyaml here to be consistent with everything else that uses jackson.

@@ -17,6 +17,9 @@ dependencies {
compile 'org.github.ngbinh.scalastyle:gradle-scalastyle-plugin_2.11'
implementation 'com.palantir.javaformat:palantir-java-format-spi'
implementation 'com.palantir.javaformat:gradle-palantir-java-format'
implementation 'com.paypal.digraph:digraph-parser'
implementation 'org.zeroturnaround:zt-exec'
Copy link
Contributor

Choose a reason for hiding this comment

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

We should avoid taking dependencies on extra stuff if it's not necessary. The java process API may be nasty but it's workable. Since we put everything into gradle buildscript internally there's great capacity to have breaking changes between gradle plugins wreak, especially from something as widely used as baseline.

@@ -17,6 +17,9 @@ dependencies {
compile 'org.github.ngbinh.scalastyle:gradle-scalastyle-plugin_2.11'
implementation 'com.palantir.javaformat:palantir-java-format-spi'
implementation 'com.palantir.javaformat:gradle-palantir-java-format'
implementation 'com.paypal.digraph:digraph-parser'
implementation 'org.zeroturnaround:zt-exec'
implementation 'org.yaml:snakeyaml'
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we avoid snakeyaml and use jackson everywhere?

.getSourceSets();

createTasksForSourceSet(project, sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME));
createTasksForSourceSet(project, sourceSets.getByName(SourceSet.TEST_SOURCE_SET_NAME));
Copy link
Contributor

Choose a reason for hiding this comment

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

What about people using custom integrationTest or integTest source sets?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we can perhaps just ignore them.

t.getIgnored().add("javax.annotation:javax.annotation-api");
//Projects may apply this in compileOnly to work around
//https://github.com/immutables/immutables/issues/291
t.getIgnored().add("org.immutables:value::annotations");
Copy link
Contributor

Choose a reason for hiding this comment

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

It might make sense to ignore all dependencies which are in compileOnly and also annotationProcessor as this happens to more libraries than just immutables, iirc.

correct for bug where jdeps doesn't report dependency if referenced
class in same package as current class, even if it's in a different
module.
@stale
Copy link

stale bot commented Nov 20, 2019

This PR has been automatically marked as stale because it has not been touched in the last 14 days. If you'd like to keep it open, please leave a comment or add the 'long-lived' label, otherwise it'll be closed in 7 days.

@stale stale bot added the stale label Nov 20, 2019
@stale stale bot closed this Nov 27, 2019
@iamdanfox
Copy link
Contributor

I think we may want to resuscitate this because the maven-dependency-analyzer can't parse bytecode produced by java13.

@iamdanfox iamdanfox reopened this Dec 12, 2019
@stale stale bot removed the stale label Dec 12, 2019
@stale
Copy link

stale bot commented Dec 26, 2019

This PR has been automatically marked as stale because it has not been touched in the last 14 days. If you'd like to keep it open, please leave a comment or add the 'long-lived' label, otherwise it'll be closed in 7 days.

@stale stale bot added the stale label Dec 26, 2019
@stale stale bot closed this Jan 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants