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

JlinkPlugin: add support for huge classpaths #1270

Merged
merged 4 commits into from
Oct 25, 2019

Conversation

nigredo-tori
Copy link
Collaborator

@nigredo-tori nigredo-tori commented Oct 24, 2019

Closes #1266.

As described here, this uses a launcher with @argfile support to pass large argument lists to jdeps (and jlink, just in case).

Since this approach only uses the java executable, I've changed the process handling to use SBT's ForkRun. This way we don't need to reimplement javaOptions and javaHome support. There are more hoops to jump through to get the process output out of it, but I think this is worth it.

@nigredo-tori nigredo-tori force-pushed the 1266-jlink-large-classpath branch from 7ae1edf to d2a2cdc Compare October 24, 2019 09:56
@nigredo-tori
Copy link
Collaborator Author

Ugh, SBT 0.13 doesn't expose ForkOptions in Keys and Defaults, and ScalaRun API is different. I had to revert to ProcessBuilders.

@nigredo-tori
Copy link
Collaborator Author

I'm not sure what this is about, but it's doesn't seem to be caused by this MR.

@muuki88 muuki88 added the jlink label Oct 24, 2019
Copy link
Contributor

@muuki88 muuki88 left a comment

Choose a reason for hiding this comment

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

Thanks for your pull request ❤️

The changes look reasonable to me. A small comment for the dependency would be nice :)

@@ -18,6 +18,7 @@ libraryDependencies ++= Seq(
"org.apache.commons" % "commons-compress" % "1.18",
// for jdkpackager
"org.apache.ant" % "ant" % "1.10.5",
"com.github.eldis" % "tool-launcher" % "0.2.1",
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a comment why we need this dependency? :)

Also. How did you find this lib? It looks rather new and built for a specific use case. Will this work in the future?

Copy link
Collaborator Author

@nigredo-tori nigredo-tori Oct 24, 2019

Choose a reason for hiding this comment

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

It is new, and it is, indeed, built for this exact use case. 😄 I've put it into the company github/sonatype organization so that I don't have to go through the trouble of establishing an organization for myself.

The library is pure Java, and has zero dependencies, so short of Java breaking the ToolProvider API, I don't see why this wouldn't work for the foreseeable future. And, since the library itself is a hundred lines of Java code under the MIT license, it should be reasonably easy to update/fix/rewrite it if the unthinkable happens. That is, if we stil have to support Java 8 by that point. 😄

Comment on lines +182 to +187
val toolLauncherClass = classOf[ru.eldis.toollauncher.ToolLauncher]
val toolLauncherJar = file(
// This assumes that the code source is a file or a directory (as opposed
// to a remote URL) - but that should hold.
toolLauncherClass.getProtectionDomain.getCodeSource.getLocation.getPath
).getAbsolutePath
Copy link
Contributor

Choose a reason for hiding this comment

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

Just if I got this right:
We summon the ToolLauncher class to get the path to the jar file, which we require to run it with Process

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, that is correct. We could resolve the JAR separately (via libraryDependencies, or directly via DependencyResolution), but it's easier to just bring it as a plugin dependency. It has no transitive dependencies, so it shouldn't break anything here.

@@ -146,7 +146,7 @@ object JlinkPlugin extends AutoPlugin {

IO.delete(outDir)

runForOutput(run("jlink", jlinkOptions.value), log)
run("jlink", jlinkOptions.value)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the sbt ForkRun method you mentioned in the ticket description, right?

Copy link
Collaborator Author

@nigredo-tori nigredo-tori Oct 24, 2019

Choose a reason for hiding this comment

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

No, that is a convenience helper for runJavaTool. The ForkRun thing required too much Compat noise to be worthwhile. So I've reverted the MR to use ProcessBuilders.

That idea can be revisited once we drop SBT 0.13.

@muuki88
Copy link
Contributor

muuki88 commented Oct 24, 2019

I'm not sure what this is about, but it's doesn't seem to be caused by this MR.

This is due to an issue with bintray. See lightbend-labs/mima#422

@muuki88
Copy link
Contributor

muuki88 commented Oct 24, 2019

Feel free to merge 😄

@nigredo-tori
Copy link
Collaborator Author

@muuki88, I can't merge this, since I am not a maintainer. Or it could be because of the failing checks - I'm not sure what the requirements are here. This can be merged once you're OK with it.

@muuki88
Copy link
Contributor

muuki88 commented Oct 25, 2019

Sorry @nigredo-tori . you are right. Only as an admin it's possible to merge if a test is failing. I updated the branch with your latest change. This should fix it 👍

@nigredo-tori nigredo-tori merged commit 4b7d917 into sbt:master Oct 25, 2019
@nigredo-tori nigredo-tori deleted the 1266-jlink-large-classpath branch October 25, 2019 12:46
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.

JlinkPlugin: find a workaround for the jdeps command line length limit
2 participants