Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Scala Script to create a symbolic link to JDK for Mac OS X
#!/usr/bin/env scala
// #############################################
// ## Simple Scala script to create ##
// ## a symbolic link to JDK for Mac OS X ##
// ## ##
// ## @author Lee, SeongHyun (Kevin) ##
// ## @version 0.0.1 (2015-04-03) ##
// ## ##
// ## http://lckymn.com ##
// #############################################
import sys.process._
import scala.io.StdIn
import scala.language.postfixOps
val javaBaseDirPath = "/Library/Java/JavaVirtualMachines"
lazy val javaBaseDir = new java.io.File(s"$javaBaseDirPath")
lazy val bold = "\u001b[1m"
lazy val normal = "\u001b[0m"
def bold(text: String): String = s"$bold$text$normal"
def isPositiveNumber(text: String) = text.matches("""[\d]+""")
def help(): Unit = printHelp(Nil)
def printHelp(whatever: List[String]): Unit =
println(s"""
|Usage:
|${bold("ln-s-jdk")} [arguments]
|
| ${bold("-l")}, ${bold("--list")}: list all JDK installed
| e.g.)
| # list JDKs
| ln-s-jdk --list
| ln-s-jdk -l
|
| ${bold("-s")}, ${bold("--slink")} version_number: Create a new symbolic link to the default jdk (i.e. jdk# => actual folder).
|
| # To set the default JDK for Java 8
| ln-s-jdk --slink 8
| ln-s-jdk -s 8
|
| # To set the default JDK for Java 7
| ln-s-jdk --slink 7
| ln-s-jdk -s 7
""".stripMargin)
if (args.isEmpty) {
help()
sys.exit(1)
}
val Command1s = Map("l" -> listAll _, "s" -> slink _, "h" -> printHelp _)
val Command2s = Map("list" -> listAll _, "slink" -> slink _, "help" -> printHelp _)
val argPatter = """([-]+)([\w]+)""".r
(args.toList match {
case argPatter("--", arg) :: rest => Command2s.get(arg).map(_(rest))
case argPatter("-", arg) :: rest => Command1s.get(arg).map(_(rest))
case _ => None
}) match {
case Some(_) => println("Done")
case None => println(s"""
|Unknown args: ${args.mkString(" ")}
|
| # To see available args please run
| ln-s-jdk --help
|
| #or just
| ln-s-jdk
""".stripMargin)
sys.exit(1)
}
def listAll(args: List[String]): Unit = {
println(s"""${Process(s"ls -l", Option(javaBaseDir)) !!}""".stripMargin)
}
def slink(args: List[String]): Unit = {
val version = args match {
case x :: xs => x.trim
case _ => ""
}
if (version.isEmpty || !isPositiveNumber(version)) {
println(s"The argument must be a positive integer. Entered: [${args.mkString(", ")}]")
sys.exit(1)
}
val names = (Process(Seq("bash", "-c", "ls -d */"), Option(javaBaseDir)).lineStream)
.map(line => if (line.endsWith("/")) line.dropRight(1) else line)
.map(name => (name, name.split("[\\._]").toList))
.filter { case (name, split) => split.length >= 3 &&
split(1).forall(_.isDigit) &&
split(1) == version }
.sortWith { case ((_, split1), (_, split2)) => split1(2).toInt.compareTo(split2(2).toInt) match {
case 0 =>
split1(3).toInt > split2(3).toInt
case cmp =>
cmp > 0
}
}
.toVector
def askUserToSelectJdk(names: Vector[(String, List[String])]): Option[(String, List[String])] = {
val listOfJdk = names.zipWithIndex.map { case ((name, split), index) => s"[$index] $name" }
println(s"""
|Version(s) found:
|${listOfJdk.mkString("\n")}
|[c] Cancel
""".stripMargin)
val length = listOfJdk.length
@scala.annotation.tailrec
def getAnswer(choice: String): Option[String] = choice match {
case "c" | "C" => None
case whatever if isPositiveNumber(choice) && choice.toInt < length => Option(choice)
case _ =>
print("Please enter a number on the list: ")
getAnswer(StdIn.readLine())
}
getAnswer("x").map(_.toInt).map(names(_))
}
println(askUserToSelectJdk(names).flatMap {
case (name, split) =>
println(s"""
|You chose '$name'.
|It will create a symbolic link to '$name' (i.e. jdk${split(1)} -> $name) and may ask you to enter your password.""".stripMargin)
print("Would you like to proceed? (Yes / No) or (Y / N) ")
StdIn.readLine() match {
case "Yes" | "yes" | "Y" | "y" =>
val before = s"""${Process(s"ls -l", Option(javaBaseDir)) !!}""".stripMargin
val lsResultLogger = ProcessLogger(line => println(s"\n$line: It is found so will be removed and recreated."),
line => println(s"\n$line: So it is not found so it will be created."))
val result = s"ls -d $javaBaseDirPath/jdk$version" !(lsResultLogger) match {
case 0 =>
if ((s"find $javaBaseDirPath -type l -iname jdk$version" !!).isEmpty) {
println(s"\n'$javaBaseDirPath/jdk$version' already exists and it's not a symbolic link so nothing will be done.")
1
} else {
println(s"""
|$javaBaseDir $$ sudo rm jdk$version
|$javaBaseDir $$ sudo ln -s $name jdk$version """.stripMargin)
Process(s"sudo rm jdk$version", Option(javaBaseDir)) #&& Process(s"sudo ln -s $name jdk$version", Option(javaBaseDir)) !
}
case _ =>
println(s"""
|$javaBaseDir $$ sudo ln -s $name jdk$version """.stripMargin)
Process(s"sudo ln -s $name jdk$version", Option(javaBaseDir)) !
}
Option(result match {
case 0 =>
s"""
|Done!
|
|# Before
|--------------------------------------
|$before
|======================================
|
|# After
|--------------------------------------
|${Process(s"ls -l", Option(javaBaseDir)) !!}
|======================================
|""".stripMargin
case _ => "\nFailed: Creating a symbolic link to JDK has failed.\n"
})
case _ =>
None
}
}
.getOrElse("\nCancelled.\n"))
}
Owner

Kevin-Lee commented Apr 3, 2015

READ Create Symbolic Link to JDK on Mac OSX.md INSTEAD.

Prerequisite

  • Java
  • Scala
  • Homebrew (Not necessary if Java and Scala are already installed).

Cask (required to install Java using Homebrew.)

brew install caskroom/cask/brew-cask 

Java (It will install the latest version.)

brew cask install java 

Scala

brew install scala 

or to install with source code and docs,

brew install scala --with-src --with-docs 

Usage

Run ln-s-jdk.sh

  • It's good to add an alias to ln-s-jdk.sh

e.g.) In the ~/.bashrc or ~/.zshrc

alias ln-s-jdk='/path/to/script/ln-s-jdk.sh'
  • Then run
$ ln-s-jdk [VERSION NUMBER] 

e.g.)

$ ln-s-jdk 8 

A result might be

Version(s) found:

[0] jdk1.8.0_40.jdk
[1] jdk1.8.0_31.jdk
[2] jdk1.8.0_25.jdk
[c] Cancel

Please enter a number on the list: 0

You chose 'jdk1.8.0_40.jdk'.
It will create a symbolic link to 'jdk1.8.0_40.jdk' (i.e. jdk8 -> jdk1.8.0_40.jdk) and may ask you to enter your password.
Would you like to proceed? (Yes / No) or (Y / N) y

/Library/Java/JavaVirtualMachines/jdk8: It is found so will be removed and recreated.

/Library/Java/JavaVirtualMachines $ sudo rm jdk8 
/Library/Java/JavaVirtualMachines $ sudo ln -s jdk1.8.0_40.jdk jdk8 
Password:

Done!

# Before
--------------------------------------
total 16
drwxr-xr-x  3 root  wheel  102  5 Nov 20:18 jdk1.7.0_71.jdk
drwxr-xr-x  2 root  wheel   68  3 Apr 22:20 jdk1.8.0_25.jdk
drwxr-xr-x  2 root  wheel   68  3 Apr 22:37 jdk1.8.0_31.jdk
drwxr-xr-x  3 root  wheel  102  7 Mar 01:30 jdk1.8.0_40.jdk
lrwxr-xr-x  1 root  wheel   15  3 Apr 18:08 jdk7 -> jdk1.7.0_71.jdk
lrwxr-xr-x  1 root  wheel   15  3 Apr 22:38 jdk8 -> jdk1.8.0_31.jdk

======================================

# After
--------------------------------------
total 16
drwxr-xr-x  3 root  wheel  102  5 Nov 20:18 jdk1.7.0_71.jdk
drwxr-xr-x  2 root  wheel   68  3 Apr 22:20 jdk1.8.0_25.jdk
drwxr-xr-x  2 root  wheel   68  3 Apr 22:37 jdk1.8.0_31.jdk
drwxr-xr-x  3 root  wheel  102  7 Mar 01:30 jdk1.8.0_40.jdk
lrwxr-xr-x  1 root  wheel   15  3 Apr 18:08 jdk7 -> jdk1.7.0_71.jdk
lrwxr-xr-x  1 root  wheel   15  3 Apr 22:44 jdk8 -> jdk1.8.0_40.jdk

======================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment