Detect broken macOS localhost resolution and tell the user how to fix it.

This commit is contained in:
Mike Hearn 2017-05-08 13:27:07 +02:00
parent b5dea88b39
commit 8016bc5fcd
3 changed files with 57 additions and 3 deletions

View File

@ -23,6 +23,7 @@ object Emoji {
@JvmStatic val CODE_NO_ENTRY: String = codePointsString(0x1F6AB)
@JvmStatic val CODE_SKULL_AND_CROSSBONES: String = codePointsString(0x2620)
@JvmStatic val CODE_BOOKS: String = codePointsString(0x1F4DA)
@JvmStatic val CODE_SLEEPING_FACE: String = codePointsString(0x1F634)
/**
* When non-null, toString() methods are allowed to use emoji in the output as we're going to render them to a
@ -38,6 +39,7 @@ object Emoji {
val paperclip: String get() = if (emojiMode.get() != null) "$CODE_PAPERCLIP " else ""
val coolGuy: String get() = if (emojiMode.get() != null) "$CODE_COOL_GUY " else ""
val books: String get() = if (emojiMode.get() != null) "$CODE_BOOKS " else ""
val sleepingFace: String get() = if (emojiMode.get() != null) "$CODE_SLEEPING_FACE " else ""
// These have old/non-emoji symbols with better platform support.
val greenTick: String get() = if (emojiMode.get() != null) "$CODE_GREEN_TICK " else ""

View File

@ -125,6 +125,32 @@ See entry under Java (above).
Other common issues
-------------------
Slow localhost resolution
*************************
Out of the box, Apple Mac's have machine names that end in ".local", by default something like "MacBook-Pro.local".
This can cause long delays with starting Corda nodes as every attempt to look up the name of the local computer triggers
a five second pause. This is not a bug in Corda but rather `a problem with the macOS networking stack <http://stackoverflow.com/questions/39636792/jvm-takes-a-long-time-to-resolve-ip-address-for-localhost>`_.
To fix it, you will need to use the Terminal app and edit your ``/etc/hosts`` file. For instance, you can do this by
typing:
``sudo nano /etc/hosts``
then typing in your own password, assuming you are an administrator user of the computer.
You will need to ensure there are two lines for the name of your machine (which you can find in the Sharing section
of System Preferences), which look like this:
.. parsed-literal::
127.0.0.1 MacBook-Pro.local
fe80::1%lo0 MacBook-Pro.local
If you've changed the name of your computer in Sharing or via the ``hostname`` command, obviously ensure you replace
``MacBook-Pro.local`` with the correct name. Then press Ctrl-O to save the file and Ctrl-X to exit.
“xterm: command not found”
**************************

View File

@ -3,6 +3,7 @@
package net.corda.node
import com.jcabi.manifests.Manifests
import com.sun.org.apache.xml.internal.serializer.utils.Utils.messages
import com.typesafe.config.ConfigException
import joptsimple.OptionException
import net.corda.core.*
@ -22,8 +23,9 @@ import java.io.*
import java.lang.management.ManagementFactory
import java.net.InetAddress
import java.nio.file.Paths
import java.util.Locale
import java.util.*
import kotlin.system.exitProcess
import kotlin.system.measureTimeMillis
private var renderBasicInfoToConsole = true
@ -35,6 +37,7 @@ fun printBasicNodeInfo(description: String, info: String? = null) {
}
val LOGS_DIRECTORY_NAME = "logs"
private val log by lazy { LoggerFactory.getLogger("Main") }
private fun initLogging(cmdlineOptions: CmdLineOptions) {
val loggingLevel = cmdlineOptions.loggingLevel.name.toLowerCase(Locale.ENGLISH)
@ -90,7 +93,6 @@ fun main(args: Array<String>) {
drawBanner(versionInfo)
val log = LoggerFactory.getLogger("Main")
printBasicNodeInfo("Logs can be found in", System.getProperty("log-path"))
val conf = try {
@ -123,7 +125,7 @@ fun main(args: Array<String>) {
log.info("bootclasspath: ${info.bootClassPath}")
log.info("classpath: ${info.classPath}")
log.info("VM ${info.vmName} ${info.vmVendor} ${info.vmVersion}")
log.info("Machine: ${InetAddress.getLocalHost().hostName}")
checkForSlowLocalhostResolution()
log.info("Working Directory: ${cmdlineOptions.baseDirectory}")
val agentProperties = sun.misc.VMSupport.getAgentProperties()
if (agentProperties.containsKey("sun.jdwp.listenerAddress")) {
@ -164,6 +166,30 @@ fun main(args: Array<String>) {
exitProcess(0)
}
private fun checkForSlowLocalhostResolution() {
val start = System.currentTimeMillis()
val hostName: String = InetAddress.getLocalHost().hostName
val elapsed = System.currentTimeMillis() - start
if (elapsed > 1000 && hostName.endsWith(".local")) {
// User is probably on macOS and experiencing this problem: http://stackoverflow.com/questions/10064581/how-can-i-eliminate-slow-resolving-loading-of-localhost-virtualhost-a-2-3-secon
//
// Also see https://bugs.openjdk.java.net/browse/JDK-8143378
val messages = listOf(
"Your computer took over a second to resolve localhost due an incorrect configuration. Corda will work but start very slowly until this is fixed. ",
"Please see https://docs.corda.net/getting-set-up-fault-finding.html#slow-localhost-resolution for information on how to fix this. ",
"It will only take a few seconds for you to resolve."
)
log.warn(messages.joinToString(""))
Emoji.renderIfSupported {
print(Ansi.ansi().fgBrightRed())
messages.forEach {
println("${Emoji.sleepingFace}$it")
}
print(Ansi.ansi().reset())
}
}
}
private fun assertCanNormalizeEmptyPath() {
// Check we're not running a version of Java with a known bug: https://github.com/corda/corda/issues/83
try {