Skip to content

Commit 4b7d917

Browse files
authored
Merge pull request #1270 from nigredo-tori/1266-jlink-large-classpath
JlinkPlugin: add support for huge classpaths
2 parents a568bbe + 2b6a9bb commit 4b7d917

File tree

4 files changed

+42
-7
lines changed

4 files changed

+42
-7
lines changed

build.sbt

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ libraryDependencies ++= Seq(
1818
"org.apache.commons" % "commons-compress" % "1.18",
1919
// for jdkpackager
2020
"org.apache.ant" % "ant" % "1.10.5",
21+
// workaround for the command line size limit
22+
"com.github.eldis" % "tool-launcher" % "0.2.1",
2123
"org.scalatest" %% "scalatest" % "3.0.5" % Test
2224
)
2325

src/main/scala/com/typesafe/sbt/packager/archetypes/jlink/JlinkPlugin.scala

+20-6
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ object JlinkPlugin extends AutoPlugin {
7171

7272
// Jdeps has a few convenient options (like --print-module-deps), but those
7373
// are not flexible enough - we need to parse the full output.
74-
val jdepsOutput = runForOutput(run("jdeps", "--multi-release" +: javaVersion +: "-R" +: paths), log)
74+
val jdepsOutput = run("jdeps", "--multi-release" +: javaVersion +: "-R" +: paths)
7575

7676
val deps = jdepsOutput.linesIterator
7777
// There are headers in some of the lines - ignore those.
@@ -146,7 +146,7 @@ object JlinkPlugin extends AutoPlugin {
146146

147147
IO.delete(outDir)
148148

149-
runForOutput(run("jlink", jlinkOptions.value), log)
149+
run("jlink", jlinkOptions.value)
150150

151151
outDir
152152
},
@@ -176,12 +176,26 @@ object JlinkPlugin extends AutoPlugin {
176176
private lazy val defaultJavaHome: File =
177177
file(sys.props.getOrElse("java.home", sys.error("no java.home")))
178178

179-
private def runJavaTool(jvm: File, log: Logger)(exeName: String, args: Seq[String]): ProcessBuilder = {
180-
val exe = (jvm / "bin" / exeName).getAbsolutePath
179+
private def runJavaTool(jvm: File, log: Logger)(toolName: String, args: Seq[String]): String = {
180+
log.info("Running: " + (toolName +: args).mkString(" "))
181181

182-
log.info("Running: " + (exe +: args).mkString(" "))
182+
val toolLauncherClass = classOf[ru.eldis.toollauncher.ToolLauncher]
183+
val toolLauncherJar = file(
184+
// This assumes that the code source is a file or a directory (as opposed
185+
// to a remote URL) - but that should hold.
186+
toolLauncherClass.getProtectionDomain.getCodeSource.getLocation.getPath
187+
).getAbsolutePath
183188

184-
Process(exe, args)
189+
val javaExe = (jvm / "bin" / "java").getAbsolutePath
190+
191+
IO.withTemporaryFile(s"snp-$toolName-", "args") { argFile =>
192+
IO.writeLines(argFile, args)
193+
194+
val argFileArg = "@" + argFile.getAbsolutePath
195+
val builder = Process(Vector(javaExe, "-jar", toolLauncherJar, "-tool", toolName, argFileArg))
196+
197+
runForOutput(builder, log)
198+
}
185199
}
186200

187201
// Like `ProcessBuilder.!!`, but this logs the output in case of a non-zero

src/sbt-test/jlink/test-jlink-misc/build.sbt

+18
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,21 @@ val issue1247JakartaJavaModules = project
6262
),
6363
runChecks := jlinkBuildImage.value
6464
)
65+
66+
// Should succeed for large classpaths.
67+
val issue1266 = project
68+
.enablePlugins(JlinkPlugin)
69+
.settings(
70+
// An arbitrary JAR with a non-platform module.
71+
libraryDependencies += "com.sun.xml.fastinfoset" % "FastInfoset" % "1.2.16",
72+
// A lot of "dummy" dependencies, so that the resulting classpath is over
73+
// the command line limit (2MB on my machine)
74+
unmanagedJars in Compile ++= {
75+
def mkPath(ix: Int) = target.value / s"there-is-no-such-file-$ix.jar"
76+
77+
1.to(300000).map(mkPath)
78+
},
79+
logLevel in jlinkModules := Level.Error,
80+
81+
runChecks := jlinkBuildImage.value
82+
)

src/sbt-test/jlink/test-jlink-misc/test

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33
> issue1243/runChecks
44
> issue1247BadAutoModuleName/runChecks
55
> issue1247ExternalModule/runChecks
6-
> issue1247JakartaJavaModules/runChecks
6+
> issue1247JakartaJavaModules/runChecks
7+
> issue1266/runChecks

0 commit comments

Comments
 (0)