Skip to content

Commit

Permalink
Update to support JDK 21 library changes and functionality (#434)
Browse files Browse the repository at this point in the history
* Change URL -> URI in many places for jdk 21
* Complete conversion of URL -> URI interface with tests working
---------
Signed-off-by: reidspencer <reid.spencer@yoppworks.com>
  • Loading branch information
reid-spencer committed Sep 22, 2023
1 parent 839112f commit db4f452
Show file tree
Hide file tree
Showing 13 changed files with 42 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ object CommonOptionsHelper {
|
|""".stripMargin

val commonOptionsParser: OParser[Unit, CommonOptions] = {
lazy val commonOptionsParser: OParser[Unit, CommonOptions] = {
val builder: OParserBuilder[CommonOptions] = OParser.builder[CommonOptions]

import builder.*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ object HugoCommand {
siteDescription: Option[String] = None,
siteLogoPath: Option[String] = Some("images/logo.png"),
siteLogoURL: Option[URL] = None,
baseUrl: Option[URL] = Option(new URL("https://example.com/")),
baseUrl: Option[URL] = Option(java.net.URI.create("https://example.com/").toURL),
themes: Seq[(String, Option[URL])] =
Seq("hugo-geekdoc" -> Option(HugoPass.geekDoc_url)),
sourceURL: Option[URL] = None,
Expand Down Expand Up @@ -105,7 +105,7 @@ class HugoCommand extends PassCommand[HugoCommand.Options]("hugo") {
.action((v, c) => c.copy(baseUrl = Some(v)))
.text("Optional base URL for root of generated http URLs"),
opt[Map[String, String]]('t', name = "themes").action((t, c) =>
c.copy(themes = t.toSeq.map(x => x._1 -> Some(new URL(x._2))))
c.copy(themes = t.toSeq.map(x => x._1 -> Some(java.net.URI.create(x._2).toURL)))
).text("Add theme name/url pairs to use alternative Hugo themes"),
opt[URL]('s', name = "source-url")
.action((u, c) => c.copy(baseUrl = Option(u)))
Expand All @@ -118,7 +118,7 @@ class HugoCommand extends PassCommand[HugoCommand.Options]("hugo") {
.text("""Path, in 'static' directory to placement and use
|of the site logo.""".stripMargin),
opt[String]('n', "site-logo-url")
.action((s, c) => c.copy(siteLogoURL = Option(new URL(s))))
.action((s, c) => c.copy(siteLogoURL = Option(java.net.URI(s).toURL)))
.text("URL from which to copy the site logo.")
) -> HugoCommand.Options()
}
Expand Down Expand Up @@ -185,7 +185,7 @@ class HugoCommand extends PassCommand[HugoCommand.Options]("hugo") {
yield {
def handleURL(url: Option[String]): Option[URL] = {
if url.isEmpty || url.get.isEmpty then None
else Option(new java.net.URL(url.get))
else Option(java.net.URI(url.get).toURL)
}

val themes =
Expand Down
6 changes: 3 additions & 3 deletions hugo/src/main/scala/com/reactific/riddl/hugo/HugoPass.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ object HugoPass extends PassInfo {
val name: String = "hugo"
val geekDoc_version = "v0.40.1"
val geekDoc_file = "hugo-geekdoc.tar.gz"
val geekDoc_url = new URL(
val geekDoc_url = java.net.URI.create(
s"https://github.com/thegeeklab/hugo-geekdoc/releases/download/$geekDoc_version/$geekDoc_file"
)
).toURL
}

case class HugoOutput(
Expand Down Expand Up @@ -326,7 +326,7 @@ case class HugoPass(input: PassInput, state: HugoTranslatorState) extends Pass(i
|[author]
| name = "${auth.name.s}"
| email = "${auth.email.s}"
| homepage = "${auth.url.getOrElse(new URL("https://example.org/"))}"
| homepage = "${auth.url.getOrElse(java.net.URI.create("https://example.org/").toURL)}"
|
|# Required to get well formatted code blocks
|pygmentsUseClasses = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import com.reactific.riddl.language.ast.At
import fastparse.*
import fastparse.ScalaWhitespace.*

import java.net.URL
import java.net.URI
import java.nio.file.Files
import scala.reflect.{ClassTag, classTag}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class CommonParserTest extends ParsingTest {
description = Some(
URLDescription(
(2, 1),
new java.net.URL("https://www.wordnik.com/words/phi")
java.net.URI("https://www.wordnik.com/words/phi").toURL
)
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ case class PrettifyPass(input: PassInput, state: PrettifyState) extends Hierarch
if !state.options.singleFile then {
include.source match {
case Some(path: String) if path.startsWith("http") =>
val url = new java.net.URL(path)
val url = java.net.URI.create(path).toURL
state.current.add(s"include \"$path\"")
val outPath = state.outPathFor(url)
state.pushFile(RiddlFileEmitter(outPath))
Expand Down
14 changes: 7 additions & 7 deletions project/Helpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.HeaderLicense
import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.HeaderLicenseStyle
import de.heikoseeberger.sbtheader.HeaderPlugin.autoImport.headerLicense
import sbt.Keys.organizationName
import sbt.Keys.*
import sbt.*
import sbt.Keys._
import sbt._
import sbt.io.Path.allSubpaths
import sbtbuildinfo.BuildInfoKey
import sbtbuildinfo.BuildInfoKeys.{buildInfoKeys, buildInfoObject, buildInfoPackage, buildInfoUsePackageAsPath}
import sbtbuildinfo.BuildInfoOption.{BuildTime, ToJson, ToMap}
import sbtbuildinfo.BuildInfoPlugin.autoImport.buildInfoOptions
import scoverage.ScoverageKeys.*
import scoverage.ScoverageKeys._
import sbtdynver.DynVerPlugin.autoImport.dynverSeparator
import sbtdynver.DynVerPlugin.autoImport.dynverSonatypeSnapshots
import sbtdynver.DynVerPlugin.autoImport.dynverVTagPrefix

import java.net.URI
import java.util.Calendar
import scala.collection.Seq

Expand Down Expand Up @@ -58,14 +59,13 @@ object C {
ThisBuild / maintainer := "reid@ossum.biz",
ThisBuild / maintainer := "reid@ossum.biz",
ThisBuild / organization := "com.reactific",
ThisBuild / organizationHomepage :=
Some(new URL("https://reactific.com/")),
ThisBuild / organizationHomepage := Some(URI.create("https://reactific.com/").toURL),
ThisBuild / organizationName := "Ossum Inc.",
ThisBuild / startYear := Some(2019),
ThisBuild / licenses +=
(
"Apache-2.0",
new URL("https://www.apache.org/licenses/LICENSE-2.0.txt")
URI.create("https://www.apache.org/licenses/LICENSE-2.0.txt").toURL
),
ThisBuild / versionScheme := Option("early-semver"),
ThisBuild / dynverVTagPrefix := false,
Expand Down Expand Up @@ -233,7 +233,7 @@ object C {
|architecture practices.""".stripMargin,
licenses := List(
"Apache License, Version 2.0" ->
new URL("https://www.apache.org/licenses/LICENSE-2.0")
URI.create("https://www.apache.org/licenses/LICENSE-2.0").toURL
),
homepage := Some(url("https://riddl.tech")),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ object RiddlSbtPlugin extends AutoPlugin {
state
}

override lazy val projectSettings: Seq[Setting[_]] = Seq(
override val projectSettings: Seq[Setting[_]] = Seq(
riddlcPath := file("riddlc"),
riddlcConf := file("src/main/riddl/riddlc.conf"),
riddlcMinVersion := SbtRiddlPluginBuildInfo.version,
Expand All @@ -72,7 +72,7 @@ object RiddlSbtPlugin extends AutoPlugin {
}.value
)

def versionTriple(version: String): (Int, Int, Int) = {
private def versionTriple(version: String): (Int, Int, Int) = {
val trimmed = version.indexOf('-') match {
case x: Int if x < 0 => version
case y: Int => version.take(y)
Expand All @@ -85,15 +85,15 @@ object RiddlSbtPlugin extends AutoPlugin {
} else { (parts(0).toInt, parts(1).toInt, parts(2).toInt) }
}

def versionSameOrLater(actualVersion: String, minVersion: String): Boolean = {
private def versionSameOrLater(actualVersion: String, minVersion: String): Boolean = {
if (actualVersion != minVersion) {
val (aJ, aN, aP) = versionTriple(actualVersion)
val (mJ, mN, mP) = versionTriple(minVersion)
aJ > mJ || ((aJ == mJ) && ((aN > mN) || ((aN == mN) && (aP >= mP))))
} else { true }
}

def checkVersion(
private def checkVersion(
riddlc: sbt.File,
minimumVersion: String
): Unit = {
Expand All @@ -108,14 +108,15 @@ object RiddlSbtPlugin extends AutoPlugin {
} else { println(s"riddlc version = $actualVersion") }
}

def runRiddlc(
private def runRiddlc(
riddlc: sbt.File,
options: Seq[String],
minimumVersion: String
): Unit = {
checkVersion(riddlc, minimumVersion)
val command = riddlc.toString + " " + options.mkString(" ")
val logger = ProcessLogger(println(_))
command.!(logger)
val rc = command.!(logger)
logger.out(s"RC=$rc")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ abstract class RunCommandOnExamplesTest[OPT <: CommandOptions, CMD <: CommandPlu

val examplesRepo: String =
"https://github.com/reactific/riddl-examples/archive/refs/heads/main.zip"
val examplesURL: URL = new URL(examplesRepo)
val examplesURL: URL = java.net.URI.create(examplesRepo).toURL
val tmpDir: Path = Files.createTempDirectory("riddl-examples")
val examplesPath: Path = Path.of(s"riddl-examples-main/src/riddl")
val srcDir: Path = tmpDir.resolve(examplesPath)
Expand Down
21 changes: 8 additions & 13 deletions utils/src/main/scala/com/reactific/riddl/utils/FileWatcher.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,7 @@ object FileWatcher {
key: WatchKey,
events: Seq[WatchEvent[?]],
interval: Int
)(onEvents: Seq[WatchEvent[?]] => Boolean
)(notOnEvents: => Boolean
): Unit = {
)(onEvents: Seq[WatchEvent[?]] => Boolean)(notOnEvents: => Boolean): Unit = {
events match {
case x: Seq[WatchEvent[?]] if x.isEmpty =>
if notOnEvents then {
Expand All @@ -67,27 +65,24 @@ object FileWatcher {
path: Path,
periodInSeconds: Int,
intervalInMillis: Int
)(onEvents: Seq[WatchEvent[?]] => Boolean
)(notOnEvents: => Boolean
): Boolean = {
val deadline = Instant.now().plus(periodInSeconds, ChronoUnit.SECONDS)
.toEpochMilli
)(onEvents: Seq[WatchEvent[?]] => Boolean)(notOnEvents: => Boolean): Boolean = {
val deadline = Instant.now().plus(periodInSeconds, ChronoUnit.SECONDS).toEpochMilli
val watchService: WatchService = FileSystems.getDefault.newWatchService()
try {
registerRecursively(path, watchService)
var saveKey: WatchKey = null
while ((saveKey == null || saveKey.isValid) && (Instant.now().toEpochMilli < deadline)) do {
while (saveKey == null || saveKey.isValid) && (Instant.now().toEpochMilli < deadline) do {
watchService.take() match {
case key: WatchKey if key != null =>
saveKey = key
val events = key.pollEvents().asScala.toSeq
handlePolledEvents(key, events, intervalInMillis)(onEvents)(
notOnEvents
)
handlePolledEvents(key, events, intervalInMillis)(onEvents)(notOnEvents)
case _ =>
notOnEvents
}
}
System.currentTimeMillis() < deadline
val current = System.currentTimeMillis()
current < deadline
} finally { watchService.close() }
}
}
6 changes: 5 additions & 1 deletion utils/src/main/scala/com/reactific/riddl/utils/Plugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import scala.jdk.StreamConverters.*
import scala.jdk.CollectionConverters.*
import scala.reflect.ClassTag
import scala.reflect.classTag
import java.net.URI

object Plugin {

Expand Down Expand Up @@ -49,7 +50,10 @@ object Plugin {
Files.isReadable(path),
s"Candidate plugin $path is not a regular file"
)
new URL("jar", "", -1, path.toAbsolutePath.toString)
val ssp = "file://" + path.toAbsolutePath.toString + "!/"
val uri = new URI("jar", ssp, "")
uri.toURL
// URI.create(s"jar:file:${path.toAbsolutePath.toString}").toURL
}
PluginClassLoader(urls, getClass.getClassLoader)
} else { getClass.getClassLoader }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import java.net.URLClassLoader

/** Loads a plugin using a [[java.net.URLClassLoader]].
*/
case class PluginClassLoader(
urls: List[URL],
parentClassLoader: ClassLoader)
case class PluginClassLoader(urls: List[URL], parentClassLoader: ClassLoader)
extends URLClassLoader(urls.toArray, parentClassLoader) {
require(urls.forall(_.getProtocol == "jar"))
override protected def loadClass(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ class FileWatcherTest extends AnyWordSpec with Matchers {
if Files.exists(changeFile) then { Files.delete(changeFile) }
// watch for changes
val f = Future[Boolean] {
FileWatcher.watchForChanges(dir, 2, 10)(onEvents)(notOnEvents)
FileWatcher.watchForChanges(dir, 4, 50)(onEvents)(notOnEvents)
}
Thread.sleep(800)
Files.createFile(changeFile)
Thread.sleep(100)
require(Files.exists(changeFile), "File should exist")
Thread.sleep(200)
val result = Await.result(f, Duration(60, "seconds"))
Files.delete(changeFile)
val result = Await.result(f, Duration(3, "seconds"))
result must be(true)
}
}
Expand Down

0 comments on commit db4f452

Please sign in to comment.