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

CORE-20557: Fix issue in CPB and CPK plugins preventing dependencies of transitive dependencies from being included #604

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

malachyb
Copy link
Contributor

The packaging plugins had an issue which prevented certain transitive dependencies from being included in the outputs, which meant that packages had to declare transitive dependencies themself. This PR changes that by creating a temporary directory where jar files are extracted from the CPB file of declared dependencies and including those files as dependencies.

…of transitive dependencies from being included
@malachyb malachyb marked this pull request as ready for review June 25, 2024 10:16
FileCollection jars = getInputs().getFiles();
Set<String> jarNames = new HashSet<>();
for (File file : jars) {
jarNames.add(file.getName());
Copy link

Choose a reason for hiding this comment

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

Can we move this inside the next for loop, which is iterating through the same FileCollection?

@@ -73,6 +73,7 @@ public void apply(@NotNull Project project) {
cpbTask.getArchiveVersion().convention(cpkTask.flatMap(Jar::getArchiveVersion));

cpbTask.doFirst(task -> cpbTask.checkForDuplicateCpkCordappNames());
cpbTask.doFirst(task -> cpbTask.extractTransitiveDeps());
Copy link

Choose a reason for hiding this comment

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

How much time has this task added to the entire build process?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Running a clean build on the DC repo (which creates 11 cpbs) 3 times on the previous version took me an average of 38.396 seconds. That same build with the new version 3 times took an average of 38.244 seconds. Since I doubt I've sped up the process I'm interpreting that as my changes not having much of an effect on the build time.

Copy link

@kyriathar kyriathar left a comment

Choose a reason for hiding this comment

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

The current review (comments) is just epidermic on minor things as a first pass.

A few questions on the description:

The packaging plugins had an issue which prevented certain transitive dependencies from being included in the outputs, which meant that packages had to declare transitive dependencies themself.

What do we mean with "certain"? Isn't this issue happening for all transitive dependencies?

This PR changes that by creating a temporary directory where jar files are extracted from the CPB file of declared dependencies and including those files as dependencies.

I think we already talked about this so just confirming; eventually we are emitting the transitive dependencies in the flat list of dependencies we have in CPB right?

Files.copy(inputStream, path);
path.toFile().deleteOnExit();
}
file = path.toFile();

Choose a reason for hiding this comment

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

Let's put together definition of var and initialization

}

@NotNull
private static Set<File> extractJarsFromCpb(Set<File> cpbs, Set<String> cordappFileNames) throws IOException {

Choose a reason for hiding this comment

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

This function could be named extractTransitiveDependeciesFromCpb?

@NotNull
private static Set<File> extractJarsFromCpb(Set<File> cpbs, Set<String> cordappFileNames) throws IOException {
Path pathToDir = Files.createTempDirectory("jars");
pathToDir.toFile().deleteOnExit();

Choose a reason for hiding this comment

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

Why deleteOnExit and not handle it ourselves synchronously?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I thought using the built-in deleteOnExit made more sense than making our own implementation since the files will be used in a separate class from where we create them and passing the data between them would make things more complicated.


@NotNull
private static Set<File> extractJarsFromCpb(Set<File> cpbs, Set<String> cordappFileNames) throws IOException {
Path pathToDir = Files.createTempDirectory("jars");

Choose a reason for hiding this comment

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

Maybe rename to tempDir?

jarDir.deleteOnExit();
} catch (IOException e) {
getLogger().warn("Could not create jar directory: {}", e.getMessage());
jarDir = null;

Choose a reason for hiding this comment

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

This probably is still null in this case

}

@Override
@NotNull
public AbstractCopyTask from(@NotNull Object... args) {
args = Arrays.copyOf(args, args.length + 1);
args[args.length - 1] = jarDir;

Choose a reason for hiding this comment

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

Where are these arguments passed to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The arguments are passed to super.from below which is used to source the files that will be included in the zip file

@@ -104,4 +123,55 @@ public void checkForDuplicateCpkCordappNames() {
}
}
}

public void extractTransitiveDeps() {
if (jarDir != null) {

Choose a reason for hiding this comment

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

Would we rather want to checkNotNull here? I think we always expect this dir to exist?

FileCollection jars = getInputs().getFiles();
Set<String> jarNames = new HashSet<>();
Set<File> cpbs = new HashSet<>();
for (File file : jars) {

Choose a reason for hiding this comment

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

jar

Set<File> cpbs = new HashSet<>();
for (File file : jars) {
jarNames.add(file.getName());
File parent = file.getParentFile();

Choose a reason for hiding this comment

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

What kind of file is this that we expect it to have multiple CPBs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, I don't think that's needed.

Comment on lines 75 to 78
} catch (IOException e) {
getLogger().warn("Could not create jar directory: {}", e.getMessage());
jarDir = null;
}
Copy link
Contributor

@josephzunigadaly josephzunigadaly Jul 15, 2024

Choose a reason for hiding this comment

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

I think we should re-throw the exception or remove the try/catch because this is needed for the bug fix to work. If we drop the exception and continue, we are allowing the incorrect behaviour to continue happening in this error path.

It is better to stop the build with an error. The end user will see the build fail and can fix the cause of the error. If we continue, we will build outputs with missing dependencies and gradle will print out "success" at the end of the build.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've changed it so it fails with the error now

@malachyb
Copy link
Contributor Author

@kyriathar

What do we mean with "certain"? Isn't this issue happening for all transitive dependencies?

I probably didn't word that as well as I could have. It's under specific circumstances that the issue occurs i.e. when we import a project dependency that has its own transitive dependencies.

I think we already talked about this so just confirming; eventually we are emitting the transitive dependencies in the flat list of dependencies we have in CPB right?

Yes, we place the jars in the temporary directory into the flat list of dependencies.

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.

4 participants