Description
In the testing phase of the Scala build, there should be an assertion that:
-
There are no classes with the same name but different case in the same package. Some operating systems do not make a distinction between upper and lower case letters in file names and exploding the jars results in overwriting class files.
-
Packages are contained only within one jar. If the package is split between two jars OSGI breaks.
The scripts that perform this check are already written (in #6315) but they need to be included in the build testing phase.
NOTE: These scripts can not be included in partest since partest does not have all the distribution jars on the classpath.
Including scripts here for convenience.
Checking for the same file name:
( (sys.props("java.class.path") split ':').toList
flatMap (p => new scala.tools.nsc.io.Jar(p).iterator)
map (_.getName)
filter (_ endsWith ".class")
groupBy (_.toLowerCase)
collect { case (k, vs) if vs.size > 1 => f"$k%30s -> $vs" }
foreach println
)
Checking that a package is not split between two jars:
val jars = (sys.props("java.class.path") split ':').toList
val jarPackages = jars.map(j => j.toString.drop(j.toString.lastIndexOf("/") + 1)).
zip(jars.map(p =>
new scala.tools.nsc.io.Jar(p).iterator.
map(_.toString).
filter(_.endsWith(".class")).
map(s => s.take(s.lastIndexOf("/"))).toSet)
).toSet
jarPackages.foreach {case (n1, j) =>
j foreach {p =>
jarPackages filterNot(_._2 == j) foreach { case (n2, jj) =>
if (jj.contains(p)) println(s"($p from $n1) duplicated in $n2")
}
}
}