Switch to Java 6

This commit is contained in:
Alexandre Archambault 2016-11-27 13:44:14 +01:00
parent d2c827a1a0
commit fe529fb9f4
11 changed files with 183 additions and 25 deletions

48
.ci/java-6-test.sh Executable file
View File

@ -0,0 +1,48 @@
#!/bin/bash
set -ev
# We're not using a jdk6 matrix entry with Travis here as some sources of coursier require Java 7 to compile
# (even though it won't try to call Java 7 specific methods if it detects it runs under Java 6).
# The tests here check that coursier is nonetheless fine when run under Java 6.
if echo "$TRAVIS_SCALA_VERSION" | grep -q "^2\.11"; then
~/sbt ++${TRAVIS_SCALA_VERSION} cli/pack
docker run -it --rm \
-v $(pwd)/cli/target/pack:/opt/coursier \
-e CI=true \
openjdk:6-jre \
/opt/coursier/bin/coursier fetch org.scalacheck::scalacheck:1.13.4
docker run -it --rm \
-v $(pwd)/cli/target/pack:/opt/coursier \
-e CI=true \
openjdk:6-jre \
/opt/coursier/bin/coursier launch --help
fi
function clean_plugin_sbt() {
mv plugins.sbt plugins.sbt0
grep -v coursier plugins.sbt0 > plugins.sbt || true
echo '
addSbtPlugin("io.get-coursier" % "sbt-coursier" % "1.0.0-SNAPSHOT")
' >> plugins.sbt
}
if echo "$TRAVIS_SCALA_VERSION" | grep -q "^2\.10"; then
~/sbt ++${TRAVIS_SCALA_VERSION} publishLocal
git clone https://github.com/alexarchambault/scalacheck-shapeless.git
cd scalacheck-shapeless
cd project
clean_plugin_sbt
cd project
clean_plugin_sbt
cd ../..
docker run -it --rm \
-v $HOME/.ivy2/local:/root/.ivy2/local \
-v $HOME/sbt:/root/sbt \
-v $(pwd):/root/project \
-e CI=true \
openjdk:6-jre \
/bin/bash -c "cd /root/project && /root/sbt update"
cd ..
fi

View File

@ -50,8 +50,12 @@ fi
SBT_COMMANDS="$SBT_COMMANDS tut coreJVM/mimaReportBinaryIssues cache/mimaReportBinaryIssues"
~/sbt ++${TRAVIS_SCALA_VERSION} $SBT_COMMANDS
.ci/java-6-test.sh
if isNotPr && publish && isMaster; then
SBT_COMMANDS="$SBT_COMMANDS publish"
~/sbt ++${TRAVIS_SCALA_VERSION} publish
fi
PUSH_GHPAGES=0
@ -61,6 +65,4 @@ if isNotPr && publish && isMasterOrDevelop; then
fi
fi
~/sbt ++${TRAVIS_SCALA_VERSION} $SBT_COMMANDS
# [ "$PUSH_GHPAGES" = 0 ] || "$(dirname "$0")/push-gh-pages.sh" "$TRAVIS_SCALA_VERSION"

View File

@ -18,9 +18,15 @@ matrix:
- env: TRAVIS_SCALA_VERSION=2.11.8 PUBLISH=1
os: linux
jdk: oraclejdk8
sudo: required
services:
- docker
- env: TRAVIS_SCALA_VERSION=2.10.6 PUBLISH=1
os: linux
jdk: oraclejdk8
sudo: required
services:
- docker
env:
global:
- COURSIER_NO_TERM=1

View File

@ -77,7 +77,7 @@ lazy val scalaVersionAgnosticCommonSettings = Seq(
scalacOptions ++= {
scalaBinaryVersion.value match {
case "2.10" | "2.11" =>
Seq("-target:jvm-1.7")
Seq("-target:jvm-1.6")
case _ =>
Seq()
}
@ -86,8 +86,8 @@ lazy val scalaVersionAgnosticCommonSettings = Seq(
scalaBinaryVersion.value match {
case "2.10" | "2.11" =>
Seq(
"-source", "1.7",
"-target", "1.7"
"-source", "1.6",
"-target", "1.6"
)
case _ =>
Seq()

View File

@ -3,13 +3,13 @@ package coursier
import java.math.BigInteger
import java.net.{ HttpURLConnection, URL, URLConnection, URLStreamHandler, URLStreamHandlerFactory }
import java.nio.channels.{ OverlappingFileLockException, FileLock }
import java.nio.file.{ StandardCopyOption, Files => NioFiles }
import java.security.MessageDigest
import java.util.concurrent.{ ConcurrentHashMap, Executors, ExecutorService }
import java.util.regex.Pattern
import coursier.core.Authentication
import coursier.ivy.IvyRepository
import coursier.internal.FileUtil
import coursier.util.Base64.Encoder
import scala.annotation.tailrec
@ -583,7 +583,8 @@ object Cache {
else if (responseCode(conn) == Some(401))
FileError.Unauthorized(url, realm = realm(conn)).left
else {
for (len0 <- Option(conn.getContentLengthLong) if len0 >= 0L) {
// TODO Use the safer getContentLengthLong when switching back to Java >= 7
for (len0 <- Option(conn.getContentLength) if len0 >= 0L) {
val len = len0 + (if (partialDownload) alreadyDownloaded else 0L)
logger.foreach(_.downloadLength(url, len, alreadyDownloaded))
}
@ -602,7 +603,7 @@ object Cache {
withStructureLock(cache) {
file.getParentFile.mkdirs()
NioFiles.move(tmp.toPath, file.toPath, StandardCopyOption.ATOMIC_MOVE)
FileUtil.atomicMove(tmp, file)
}
for (lastModified <- Option(conn.getLastModified) if lastModified > 0L)
@ -641,7 +642,7 @@ object Cache {
Task {
if (referenceFileExists) {
if (!errFile.exists())
NioFiles.write(errFile.toPath, "".getBytes("UTF-8"))
FileUtil.write(errFile, "".getBytes("UTF-8"))
}
().right[FileError]
@ -796,7 +797,7 @@ object Cache {
Task {
val sumOpt = parseChecksum(
new String(NioFiles.readAllBytes(sumFile.toPath), "UTF-8")
new String(FileUtil.readAllBytes(sumFile), "UTF-8")
)
sumOpt match {
@ -910,7 +911,7 @@ object Cache {
def notFound(f: File) = Left(s"${f.getCanonicalPath} not found")
def read(f: File) =
try Right(new String(NioFiles.readAllBytes(f.toPath), "UTF-8").stripPrefix(utf8Bom))
try Right(new String(FileUtil.readAllBytes(f), "UTF-8").stripPrefix(utf8Bom))
catch {
case NonFatal(e) =>
Left(s"Could not read (file:${f.getCanonicalPath}): ${e.getMessage}")

View File

@ -0,0 +1,101 @@
package coursier.internal
import java.io._
import java.util.UUID
/** Java 6-compatible helpers mimicking NIO */
object FileUtil {
private object Java7 {
import java.nio.file.{ Files, StandardCopyOption }
def atomicMove(from: File, to: File): Unit =
Files.move(from.toPath, to.toPath, StandardCopyOption.ATOMIC_MOVE)
def createTempDirectory(prefix: String): File =
Files.createTempDirectory(prefix).toFile
}
private object Java6 {
def move(from: File, to: File): Unit =
if (!from.renameTo(to))
throw new IOException(s"Cannot move $from to $to")
def createTempDirectory(prefix: String): File = {
val tmpBaseDir = new File(sys.props("java.io.tmpdir"))
val tmpDir = new File(tmpBaseDir, s"$prefix-${UUID.randomUUID()}")
tmpDir.mkdirs()
tmpDir
}
}
private def versionGteq(version: String, to: (Int, Int)): Boolean =
version.split('.').take(2).map(s => scala.util.Try(s.toInt).toOption) match {
case Array(Some(major), Some(minor)) =>
Ordering[(Int, Int)].gteq((major, minor), (1, 7))
case _ => false
}
// Fine if set several times (if java7Available() is initially called concurrently)
@volatile private var java7AvailableOpt = Option.empty[Boolean]
private def java7Available(): Boolean =
java7AvailableOpt.getOrElse {
val available = sys.props.get("java.version").exists { version =>
versionGteq(version, (1, 7))
}
java7AvailableOpt = Some(available)
available
}
/** Not guaranteed to be atomic on Java 6 */
def atomicMove(from: File, to: File): Unit =
if (java7Available())
Java7.atomicMove(from, to)
else
Java6.move(from, to)
def write(file: File, bytes: Array[Byte]): Unit = {
var fos: FileOutputStream = null
try {
fos = new FileOutputStream(file)
fos.write(bytes)
fos.close()
} finally {
if (fos != null) fos.close()
}
}
private def readFully(is: InputStream): Array[Byte] = {
val buffer = new ByteArrayOutputStream
val data = Array.ofDim[Byte](16384)
var nRead = 0
while ({
nRead = is.read(data, 0, data.length)
nRead != -1
})
buffer.write(data, 0, nRead)
buffer.flush()
buffer.toByteArray
}
def readAllBytes(file: File): Array[Byte] = {
var fis: FileInputStream = null
try {
fis = new FileInputStream(file)
readFully(fis)
} finally {
if (fis != null)
fis.close()
}
}
def createTempDirectory(prefix: String): File =
if (java7Available())
Java7.createTempDirectory(prefix)
else
Java6.createTempDirectory(prefix)
}

View File

@ -9,6 +9,7 @@ import java.util.zip.{ZipEntry, ZipInputStream, ZipOutputStream}
import caseapp._
import coursier.cli.util.Zip
import coursier.internal.FileUtil
case class Bootstrap(
@Recurse
@ -200,7 +201,7 @@ case class Bootstrap(
"exec java -jar " + options.javaOpt.map(s => "'" + s.replace("'", "\\'") + "'").mkString(" ") + " \"$0\" \"$@\""
).mkString("", "\n", "\n")
try Files.write(output0.toPath, shellPreamble.getBytes("UTF-8") ++ buffer.toByteArray)
try FileUtil.write(output0, shellPreamble.getBytes("UTF-8") ++ buffer.toByteArray)
catch { case e: IOException =>
Console.err.println(s"Error while writing $output0${Option(e.getMessage).fold("")(" (" + _ + ")")}")
sys.exit(1)

View File

@ -2,12 +2,12 @@ package coursier.cli
import java.io.{PrintStream, BufferedReader, File, PipedInputStream, PipedOutputStream, InputStream, InputStreamReader}
import java.net.URLClassLoader
import java.nio.file.Files
import caseapp._
import coursier.{ Attributes, Dependency }
import coursier.cli.spark.{ Assembly, Submit }
import coursier.internal.FileUtil
import coursier.util.Parse
import scala.util.control.NonFatal
@ -273,9 +273,8 @@ object OutputHelper {
lock.synchronized {
if (!written) {
println(s"Detected YARN app ID $id")
val path = yarnAppFile.toPath
Option(path.getParent).foreach(_.toFile.mkdirs())
Files.write(path, id.getBytes("UTF-8"))
Option(yarnAppFile.getParentFile).foreach(_.mkdirs())
FileUtil.write(yarnAppFile, id.getBytes("UTF-8"))
written = true
}
}

View File

@ -2,7 +2,6 @@ package coursier.cli.spark
import java.io.{File, FileInputStream, FileOutputStream}
import java.math.BigInteger
import java.nio.file.{Files, StandardCopyOption}
import java.security.MessageDigest
import java.util.jar.{Attributes, JarFile, JarOutputStream, Manifest}
import java.util.regex.Pattern
@ -11,6 +10,7 @@ import java.util.zip.{ZipEntry, ZipInputStream, ZipOutputStream}
import coursier.Cache
import coursier.cli.{CommonOptions, Helper}
import coursier.cli.util.Zip
import coursier.internal.FileUtil
import scala.collection.mutable
import scalaz.\/-
@ -224,7 +224,7 @@ object Assembly {
}
val sumOpt = Cache.parseChecksum(
new String(Files.readAllBytes(f.toPath), "UTF-8")
new String(FileUtil.readAllBytes(f), "UTF-8")
)
sumOpt match {
@ -273,7 +273,7 @@ object Assembly {
val tmpDest = new File(dest.getParentFile, s".${dest.getName}.part")
// FIXME Acquire lock on tmpDest
Assembly.make(jars, tmpDest, assemblyRules)
Files.move(tmpDest.toPath, dest.toPath, StandardCopyOption.ATOMIC_MOVE)
FileUtil.atomicMove(tmpDest, dest)
\/-((dest, jars))
}.leftMap(_.describe).toEither
}

View File

@ -8,6 +8,7 @@ import coursier.core.{ Authentication, Publication }
import coursier.ivy.{ IvyRepository, PropertiesPattern }
import coursier.Keys._
import coursier.Structure._
import coursier.internal.FileUtil
import coursier.util.{ Config, Print }
import org.apache.ivy.core.module.id.ModuleRevisionId
@ -730,11 +731,11 @@ object Tasks {
b += '\n'
b ++= printer.format(MakeIvyXml(currentProject))
cacheIvyFile.getParentFile.mkdirs()
Files.write(cacheIvyFile.toPath, b.result().getBytes("UTF-8"))
FileUtil.write(cacheIvyFile, b.result().getBytes("UTF-8"))
// Just writing an empty file here... Are these only used?
cacheIvyPropertiesFile.getParentFile.mkdirs()
Files.write(cacheIvyPropertiesFile.toPath, "".getBytes("UTF-8"))
FileUtil.write(cacheIvyPropertiesFile, "".getBytes("UTF-8"))
}
val res = {

View File

@ -2,10 +2,9 @@ package coursier
package test
import java.io.File
import java.nio.file.Files
import coursier.cache.protocol.TestprotocolHandler
import coursier.core.Authentication
import coursier.internal.FileUtil
import utest._
@ -15,7 +14,7 @@ object CacheFetchTests extends TestSuite {
def check(extraRepo: Repository): Unit = {
val tmpDir = Files.createTempDirectory("coursier-cache-fetch-tests").toFile
val tmpDir = FileUtil.createTempDirectory("coursier-cache-fetch-tests")
def cleanTmpDir() = {
def delete(f: File): Boolean =