Nano Hash - криптовалюты, майнинг, программирование

Веб-приложение Scala Jetty на Heroku 404

Я тестирую веб-фреймворк Scala (Udash) и пытаюсь запустить игрушечный пример в Heroku. У меня он работает без проблем на локальном компьютере, следуя инструкциям в документации Heroku:

sbt compile stage
heroku local web

Однако после развертывания любой URL-адрес, который я ввожу, переходит на 404, даже на целевую страницу приложения. Это объекты, которые я использую:

object Launcher extends CrossLogging {
  def main(args: Array[String]): Unit = {
    val port = Properties.envOrElse("PORT", "5000").toInt
    val server = new ApplicationServer(port, "frontend/target/UdashStatics/WebContent")
    server.start()
    logger.info(s"Application started...")
  }
}

class ApplicationServer(val port: Int, resourceBase: String) {
  private val server = new Server(port)
  private val contextHandler = new ServletContextHandler
  private val appHolder = createAppHolder()

  contextHandler.setSessionHandler(new SessionHandler)
  contextHandler.setGzipHandler(new GzipHandler)
  contextHandler.getSessionHandler.addEventListener(new org.atmosphere.cpr.SessionSupport())
  contextHandler.addServlet(appHolder, "/*")
  server.setHandler(contextHandler)

  def start(): Unit = server.start()
  def stop(): Unit = server.stop()

  private def createAppHolder() = {
    val appHolder = new ServletHolder(new DefaultServlet)
    appHolder.setAsyncSupported(true)
    appHolder.setInitParameter("resourceBase", resourceBase)
    appHolder
  }
}

Есть ли какая-либо конфигурация/характеристика Heroku, которую мне не хватает?

ИЗМЕНИТЬ

Попытался применить предложенные изменения и получил следующий ApplicationContext:

class ApplicationServer(val port: Int, val resourceBase: String) {
  val server = new Server()
  val connector = new ServerConnector(server)
  connector.setPort(port)
  server.addConnector(connector)
  private val appHolder = createAppHolder()

  val context = new ServletContextHandler(ServletContextHandler.SESSIONS)

  context.setBaseResource(Resource.newResource(resourceBase))
  context.setContextPath("/")
  context.addServlet(appHolder, "/")
  server.setHandler(context)

  private def createAppHolder() = {
    val appHolder = new ServletHolder("default", classOf[DefaultServlet])
    appHolder.setInitParameter("dirAllowed", "true")
    appHolder.setInitParameter("resourceBase", resourceBase)
    appHolder
  }

  def start(): Unit = server.start()
  def stop(): Unit = server.stop()
}

Тем не менее, я все еще получаю ошибку 404 даже на целевой странице после развертывания в Heroku:

HTTP ERROR 404
Problem accessing /. Reason:
    Not Found

При запуске приложения локально я правильно попадаю на целевую страницу.

Спасибо! Спасибо!

24.03.2019

  • Ваш код работает, пока я помещаю что-то в каталог, на который указывает resourceBase, для получения через браузер. (например: я поместил в него hello.html с простым <h1>hello world</h1>, а затем получил к нему доступ через http://localhost:8080/hello.html) 26.03.2019

Ответы:


1

Несколько вещей для настройки, которые могут вам помочь.

  1. resourceBase в качестве параметра инициализации на DefaultServlet предназначен для альтернативного статического раздача файлов.
  2. Вместо этого используйте ServletContextHandler.setBaseResource(Resource).
  3. Используйте Resource.newResource(String) для создания новой ссылки на ресурс. Это должен быть абсолютный путь в файловой системе или абсолютная ссылка URI. никаких относительных путей или фрагментов URI.
  4. DefaultServlet должен быть на url-pattern из "/", а не "/*" (это требование спецификации сервлета)
  5. DefaultServlet должен быть назван и должен иметь имя "default" (это требование спецификации сервлета, например, см. ссылку в пункте 1)
  6. установите ServletContextHandler.setContextPath("/"), чтобы указать, какой базовый контекстный путь вы хотите использовать.

Некоторые наблюдения:

Ваш пример кода будет обслуживать только статический контент из resourceBase.

Поскольку у вас нет настроенного welcomeFiles, по умолчанию будет использоваться <resourceBase>/index.html (если вы не укажете конкретный статический ресурс, к которому хотите получить доступ)

У вас есть установка SessionListener (org.atmosphere.cpr.SessionSupport), но поскольку нет ничего, что могло бы получить доступ к Session, этот код в значительной степени не работает.

В вашем примере кодовой базы нет динамических результатов от пользовательского сервлета или фильтра.

25.03.2019
  • Спасибо за ответ, как приеду домой попробую, дам знать 25.03.2019
  • Привет @Joakim! Пробовал предложенные вами изменения безуспешно. Я использовал другой ответ, который вы связали в качестве шаблона. Извините, я немного запутался со всеми серверными вещами (: я думаю, однако, что правильно применил ваши предложения (новый сервер приложений, который я использовал, находится здесь gist.github.com/pmbrull/64de6497d52463542cc2ca902a03ffb4) Я был бы очень признателен за дальнейшие указания по этому вопросу, пока я продолжаю искать примеры и документы. Tyvm!! 25.03.2019
  • Можете ли вы обновить свой вопрос (отредактировать его) и указать, как вы запускаете код и какие результаты вы видите, а какие результаты вы ожидаете? 26.03.2019
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..