Skip to content
This repository has been archived by the owner on Apr 25, 2021. It is now read-only.

add JDK 9 support #143

Merged
merged 6 commits into from Mar 10, 2017
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .java-version
@@ -0,0 +1 @@
1.8
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -4,7 +4,7 @@ script:
scala:
- 2.10.3
jdk:
- oraclejdk7
- oraclejdk8
notifications:
email:
- sbt-dev-bot@googlegroups.com
Expand Down
18 changes: 17 additions & 1 deletion build.sbt
Expand Up @@ -105,7 +105,11 @@ val root = (project in file(".")).
// Universal ZIP download install.
packageName in Universal := packageName.value, // needs to be set explicitly due to a bug in native-packager
version in Universal := sbtVersionToRelease,
mappings in Universal <+= sbtLaunchJar map { _ -> "bin/sbt-launch.jar" },
mappings in Universal ++= {
val launchJar = sbtLaunchJar.value
val rtExportJar = (packageBin in Compile in java9rtexport).value
Seq(launchJar -> "bin/sbt-launch.jar", rtExportJar -> "bin/java9-rt-export.jar")
},

// Misccelaneous publishing stuff...
projectID in Debian <<= moduleID,
Expand All @@ -117,6 +121,18 @@ val root = (project in file(".")).
projectID in Universal <<= moduleID
)

lazy val java9rtexport = (project in file("java9-rt-export"))
.settings(
name := "java9-rt-export",
autoScalaLibrary := false,
crossPaths := false,
description := "Exports the contents of the Java 9. JEP-220 runtime image to a JAR for compatibility with older tools.",
homepage := Some(url("http://github.com/retronym/" + name.value)),
startYear := Some(2017),
licenses += ("Scala license", url(homepage.value.get.toString + "/blob/master/LICENSE")),
mainClass in Compile := Some("io.github.retronym.java9rtexport.Export")
)

def downloadUrlForVersion(v: String) = (v split "[^\\d]" flatMap (i => catching(classOf[Exception]) opt (i.toInt))) match {
case Array(0, 11, 3, _*) => "http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.11.3-2/sbt-launch.jar"
case Array(0, 11, x, _*) if x >= 3 => "http://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/"+v+"/sbt-launch.jar"
Expand Down
@@ -0,0 +1,49 @@
package io.github.retronym.java9rtexport;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.util.EnumSet;

import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class Copy {
public static void copyDirectory(final Path source, final Path target)
throws IOException {
Files.walkFileTree(source, EnumSet.of(FileVisitOption.FOLLOW_LINKS),
Integer.MAX_VALUE, new FileVisitor<Path>() {

@Override
public FileVisitResult preVisitDirectory(Path dir,
BasicFileAttributes sourceBasic) throws IOException {

String relative = source.relativize(dir).toString();
if (!Files.exists(target.getFileSystem().getPath(relative)))
Files.createDirectory(target.getFileSystem().getPath(relative));
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
String relative = source.relativize(file).toString();
Files.copy(file, target.getFileSystem().getPath(relative), COPY_ATTRIBUTES, REPLACE_EXISTING);
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFileFailed(Path file, IOException e) throws IOException {
throw e;
}

@Override
public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
if (e != null) throw e;
return FileVisitResult.CONTINUE;
}
});
}

}
@@ -0,0 +1,48 @@
package io.github.retronym.java9rtexport;

import java.io.IOException;
import java.net.URI;
import java.nio.file.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class Export {
public static void main(String[] args) {
try {

if (args.length == 0) {
System.err.println("Usage:");
System.err.println(" java -jar java9-rt-export-*.jar $HOME/.sbt/java9-rt-ext/rt.jar");
System.err.println(" Exports rt.jar to the specified path.");
System.err.println("");
System.err.println(" java -jar java9-rt-export-*.jar --global-base");
System.err.println(" Prints sbt global base.");
System.exit(-1);
}
String destination = args[0];
if (destination.equals("--global-base")) {
Path defaultGlobalBase = Paths.get(System.getProperty("user.home"), ".sbt", "0.13");
String globalBase = System.getProperty("sbt.global.base", defaultGlobalBase.toString());
System.out.println(globalBase);
System.exit(0);
}
FileSystem fileSystem = FileSystems.getFileSystem(URI.create("jrt:/"));
Path path = fileSystem.getPath("/modules");
Path destPath = Paths.get(destination);
URI uri = URI.create( "jar:" + destPath.toUri() );
Map<String, String> env = new HashMap<>();
env.put( "create", "true" );
try ( FileSystem zipfs = FileSystems.newFileSystem( uri, env ) ) {
Iterator<Path> iterator = Files.list(path).iterator();
while(iterator.hasNext()) {
Path next = iterator.next();
Copy.copyDirectory(next, zipfs.getPath("/"));
}
}
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
32 changes: 31 additions & 1 deletion src/universal/bin/sbt-launch-lib.bash
Expand Up @@ -38,6 +38,10 @@ acquire_sbt_jar () {
fi
}

rt_export_file () {
echo "${sbt_bin_dir}/java9-rt-export.jar"
}

execRunner () {
# print the arguments one to a line, quoting any containing spaces
[[ $verbose || $debug ]] && echo "# Executing command line:" && {
Expand Down Expand Up @@ -147,8 +151,16 @@ process_args () {
process_my_args "${myargs[@]}"
}

java_version=$("$java_cmd" -Xmx512M -version 2>&1 | sed 's/.*version "\([0-9]*\)\.\([0-9]*\)\..*"/\1.\2/; 1q')
## parses 1.7, 1.8, 9, etc out of java version "1.8.0_91"
java_version=$("$java_cmd" -Xmx512M -version 2>&1 | sed 's/.*version "\([0-9]*\)\(\.[0-9]*\)\{0,1\}\(.*\)*"/\1\2/; 1q')
vlog "[process_args] java_version = '$java_version'"
rtexport=$(rt_export_file)
sbt_global_dir=$("$java_cmd" ${JAVA_OPTS} ${SBT_OPTS:-$default_sbt_opts} ${java_args[@]} \
Copy link
Member Author

Choose a reason for hiding this comment

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

I need to move this out to copyRt so I can use this script from Java 1.6 and 1.7.

-jar "$rtexport" --global-base)
java9_ext=$(echo "$sbt_global_dir/java9-rt-ext")
java9_rt=$(echo "$java9_ext/rt.jar")
vlog "[process_args] sbt_global_dir = '$sbt_global_dir'"
vlog "[process_args] java9_rt = '$java9_rt'"
}

# Detect that we have java installed.
Expand All @@ -174,6 +186,21 @@ checkJava() {
fi
}

copyRt() {
if [[ "$java_version" > "8" ]] && [[ ! -f "$java9_rt" ]]; then
echo Copying runtime jar.
execRunner "$java_cmd" \
${JAVA_OPTS} \
${SBT_OPTS:-$default_sbt_opts} \
${java_args[@]} \
-jar "$rtexport" \
"${java9_rt}"
fi
Copy link

Choose a reason for hiding this comment

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

This will copy rt.jar only once. However, jdk 9 might be updated over time. People may select different versions for debugging reasons, or may flip from OpenJDK to Oracle's JDK, to IBM's JVM. That may cause unexpected behavior or crashes. Probably rt.jar should be copied on each startup; alternatively, the full version string could be dumped to a text file and matched upon startup, so that if it differs the rt.jar file is extracted again.

if [[ "$java_version" > "8" ]]; then
addJava "-Dscala.ext.dirs=${java9_ext}"
fi
}


run() {
# no jar? download it.
Expand All @@ -191,6 +218,9 @@ run() {
# TODO - java check should be configurable...
checkJava "1.6"

# Java 9 support
copyRt

#If we're in cygwin, we should use the windows config, and terminal hacks
if [[ "$CYGWIN_FLAG" == "true" ]]; then
stty -icanon min 1 -echo > /dev/null 2>&1
Expand Down