Я занимаюсь веб-разработкой, на работе мы используем стэк технологий на scala для наших проектов, основу этого стэка составляет Lift framework, также известный как liftweb. Lift использует sbt для управления сборкой и jetty или другой контейнер сервлетов как веб-сервер.
Однажды мне пришлось поработать из дома, работалось прекрасно, разработческая версия сервера запускалась, все было как обычно. Но на следующий день, когда я вернулся к работе в офисе, при первом же запуске сервера случился полный облом. На экране консоли прямо во время запуска широко раскинулось исключение
Из подходящего нагуглил только это.
Решил почистить кэши и попробовать заново. Опять то же исключение. Что-ж, надо попробовать почистить кэши ivy, может библиотека какая-то поломанная затесалась. Не помогло. Может что-то с диском? Проверка диска показала отсутствие ошибок (диск SSD). Как же так, вчера дома всё работало?! А позавчера и тут, на работе, все работало. Может система не обновлена, и уже есть фикс? Новых обновлений нет. Может антивирус или файрволл? Отключил, не помогло. Подумалось, что быть может система посчитала мою версию java вконец небезопасной и заблокировала ей сеть. Переставил JDK, удалив все старые версии, на всякий случай еще раз почистил все кэши и сделал очистку диска средствами системы. Не помогло.
Странно, DNS сервера и дома и тут прописаны гугловские, по идее работать должны одинаково.
Стал искать, что же там за адрес может быть, нашел только определение схемы в файлике
Вот определение схемы:
Еще одна мысль, которую пришлось проверить — если взять ноутбук, на котором точно работает, принести на работу и в рабочей сети попробовать запустить, — будет работать или нет. Проверил. Не работает. То же исключение.
Это уже интересно. Значит виновата локальная сеть, но куда именно мы не можем попасть — непонятно. Попробовал запустить проект с машин других разработчиков — та же ошибка.
Тут у коллеги промелькнула здравая мысль — а что, если запустить вообще без сети. Проверил, — ругается на то, что не может зарезолвить все тот же
Работать так невозможно, сначала хотел выкачать нужный файл по каналам, по которым он доступен, и положить на свой сервер. Но позже по рекомендации коллеги попробовал удалить определение схемы из xml файла вообще. И о чудо! Всё заработало, никто не ругается. Текст исключения публикую здесь на случай, если еще кто-то наступит на него, — нагуглив статью сэкономит себе пару часов:
Сейчас у провайдера адрес тоже пингуется, судя по всему проблема самоустранилась.
И да, возможно при внимательном изучении стэктрейса глаз все же зацепился бы за строку
P.S.
Однажды мне пришлось поработать из дома, работалось прекрасно, разработческая версия сервера запускалась, все было как обычно. Но на следующий день, когда я вернулся к работе в офисе, при первом же запуске сервера случился полный облом. На экране консоли прямо во время запуска широко раскинулось исключение
java.net.ConnectException
с текстом Connection timed out: connect
и трейсом на 86 строк. К сожалению, не было написано куда именно оно не смогло установить подключение. Поскольку сервер только запускается, единственное соединение, которое он должен пытаться установить — это LISTEN
на определенном порту. Но исключение явно не об этом. Мало того, на порту уже отвечали с какой-то ошибкой больше 500.Из подходящего нагуглил только это.
Решил почистить кэши и попробовать заново. Опять то же исключение. Что-ж, надо попробовать почистить кэши ivy, может библиотека какая-то поломанная затесалась. Не помогло. Может что-то с диском? Проверка диска показала отсутствие ошибок (диск SSD). Как же так, вчера дома всё работало?! А позавчера и тут, на работе, все работало. Может система не обновлена, и уже есть фикс? Новых обновлений нет. Может антивирус или файрволл? Отключил, не помогло. Подумалось, что быть может система посчитала мою версию java вконец небезопасной и заблокировала ей сеть. Переставил JDK, удалив все старые версии, на всякий случай еще раз почистил все кэши и сделал очистку диска средствами системы. Не помогло.
Странно, DNS сервера и дома и тут прописаны гугловские, по идее работать должны одинаково.
Стал искать, что же там за адрес может быть, нашел только определение схемы в файлике
web.xml
в папке WEB-INF
в корне публичного каталога веб-сервера. Погуглил замену для файлика DTD web-app_2_3.dtd
и что-то толком ничего не нашел. Да и по правде, не верилось, что этот url вообще должен дергаться.Вот определение схемы:
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
Еще одна мысль, которую пришлось проверить — если взять ноутбук, на котором точно работает, принести на работу и в рабочей сети попробовать запустить, — будет работать или нет. Проверил. Не работает. То же исключение.
Это уже интересно. Значит виновата локальная сеть, но куда именно мы не можем попасть — непонятно. Попробовал запустить проект с машин других разработчиков — та же ошибка.
Тут у коллеги промелькнула здравая мысль — а что, если запустить вообще без сети. Проверил, — ругается на то, что не может зарезолвить все тот же
java.sun.com
. Решил детальней изучить проблемы именно с этим доменом. А ведь он вообще не пингуется! Попробовал traceroute
— таймаут возникает где-то в районе провайдера или немного дальше. Через мобильную сеть все работает. Т.е. либо провайдер, либо тот, кто ему продает канал, — не знает куда идти.Работать так невозможно, сначала хотел выкачать нужный файл по каналам, по которым он доступен, и положить на свой сервер. Но позже по рекомендации коллеги попробовал удалить определение схемы из xml файла вообще. И о чудо! Всё заработало, никто не ругается. Текст исключения публикую здесь на случай, если еще кто-то наступит на него, — нагуглив статью сэкономит себе пару часов:
Exception
java.net.ConnectException: Connection timed out: connect at java.net.DualStackPlainSocketImpl.connect0(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) at java.net.AbstractPlainSocketImpl.connect(Unknown Source) at java.net.PlainSocketImpl.connect(Unknown Source) at java.net.SocksSocketImpl.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at java.net.Socket.connect(Unknown Source) at sun.net.NetworkClient.doConnect(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.openServer(Unknown Source) at sun.net.www.http.HttpClient.<init>(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.http.HttpClient.New(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getNewHttpClient(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect0(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessController.doPrivilegedWithCombiner(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.connect(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.access$200(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection$9.run(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection$9.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessController.doPrivilegedWithCombiner(Unknown Source) at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(Unknown Source) at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source) at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(Unknown Source) at org.eclipse.jetty.xml.XmlParser.parse(XmlParser.java:255) at org.eclipse.jetty.webapp.Descriptor.parse(Descriptor.java:54) at org.eclipse.jetty.webapp.WebDescriptor.parse(WebDescriptor.java:207) at org.eclipse.jetty.webapp.MetaData.setWebXml(MetaData.java:189) at org.eclipse.jetty.webapp.WebXmlConfiguration.preConfigure(WebXmlConfiguration.java:60) at org.eclipse.jetty.webapp.WebAppContext.preConfigure(WebAppContext.java:474) at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:510) at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) at com.earldouglas.xsbtwebplugin.Jetty9Runner.reload(Jetty9Runner.scala:143) at com.earldouglas.xsbtwebplugin.Container$$anonfun$reloadTask$1$$anonfun$apply$3.apply(Container.scala:117) at com.earldouglas.xsbtwebplugin.Container$$anonfun$reloadTask$1$$anonfun$apply$3.apply(Container.scala:117) at scala.Function2$$anonfun$tupled$1.apply(Function2.scala:54) at scala.Function2$$anonfun$tupled$1.apply(Function2.scala:53) at scala.Function1$$anonfun$compose$1.apply(Function1.scala:47) at sbt.$tilde$greater$$anonfun$$u2219$1.apply(TypeFunctions.scala:40) at sbt.std.Transform$$anon$4.work(System.scala:63) at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:226) at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:17) at sbt.Execute.work(Execute.scala:235) at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:226) at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:159) at sbt.CompletionService$$anon$2.call(CompletionService.scala:28) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
Сейчас у провайдера адрес тоже пингуется, судя по всему проблема самоустранилась.
И да, возможно при внимательном изучении стэктрейса глаз все же зацепился бы за строку
com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity
и стало бы ясно, что дело именно в этом. Но имхо, адрес, к которому не удалось подключиться, писать в тексте исключения нужно обязательно! Куда сабмитить патчи для кода com.sun.org
не знаю, репортов никуда пока не посылал.P.S.
java.sun.com
сейчас — это CNAME на www-legacy.oraclegha.com
. Быть может оно настолько legacy, что это каким-то образом и стало причиной.