com.mayabot.nlp.common.utils.Jars.kt Maven / Gradle / Ivy
package com.mayabot.nlp.common.utils
import java.net.MalformedURLException
import java.net.URL
import java.util.*
class Jars {
/**
* Parses the classpath into an array of URLs
* @return array of URLs
* @throws IllegalStateException if the classpath contains empty elements
*/
fun parseClassPath(): Set {
return parseClassPath(System.getProperty("java.class.path"))
}
/**
* Parses the classpath into a set of URLs. For testing.
* @param classPath classpath to parse (typically the system property `java.class.path`)
* @return array of URLs
* @throws IllegalStateException if the classpath contains empty elements
*/
internal fun parseClassPath(classPath: String): Set {
val pathSeparator = System.getProperty("path.separator")
val fileSeparator = System.getProperty("file.separator")
val elements = classPath.split(pathSeparator.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val urlElements = LinkedHashSet() // order is already lost, but some filesystems have it
for (x in elements) {
var element = x
// Technically empty classpath element behaves like CWD.
// So below is the "correct" code, however in practice with ES, this is usually just a misconfiguration,
// from old shell scripts left behind or something:
// if (element.isEmpty()) {
// element = System.getProperty("user.dir");
// }
// Instead we just throw an exception, and keep it clean.
if (element.isEmpty()) {
throw IllegalStateException("Classpath should not contain empty elements! (outdated shell script from a previous" +
" version?) classpath='" + classPath + "'")
}
// we should be able to just Paths.get() each element, but unfortunately this is not the
// whole story on how classpath parsing works: if you want to know, start at sun.misc.Launcher,
// be sure to stop before you tear out your eyes. we just handle the "alternative" filename
// specification which java seems to allow, explicitly, right here...
if (element.startsWith("/") && "\\" == fileSeparator) {
// "correct" the entry to become a normal entry
// change to correct file separators
element = element.replace("/", "\\")
// if there is a drive letter, nuke the leading separator
if (element.length >= 3 && element[2] == ':') {
element = element.substring(1)
}
}
// now just parse as ordinary file
try {
val url = PathUtils.get(element).toUri().toURL()
if (urlElements.add(url) == false) {
throw IllegalStateException("jar hell!" + System.lineSeparator() +
"duplicate jar [" + element + "] on classpath: " + classPath)
}
} catch (e: MalformedURLException) {
// should not happen, as we use the filesystem API
throw RuntimeException(e)
}
}
return Collections.unmodifiableSet(urlElements)
}
}