Embedded Jetty не может получить доступ к статическому веб-контенту в jar в Spring Boot uber-jar

Я запускаю веб-приложение Spring Boot с базовой базой данных Neo4j. Чтобы иметь возможность просматривать браузер Neo4j (прямой просмотр в Интернете на db), веб-сервер Neo4j встроен в приложение с использованием следующей конфигурации.

@Bean(initMethod = "start", destroyMethod = "stop")
public WrappingNeoServerBootstrapper neo4jWebServer() {
    return new WrappingNeoServerBootstrapper((GraphDatabaseAPI) graphDatabaseService());
}

и включив в maven pom следующее:

<dependency>
    <groupId>org.neo4j.app</groupId>
    <artifactId>neo4j-server</artifactId>
    <classifier>static-web</classifier>
    <version>2.0.2</version>
</dependency>

Все это отлично работает при запуске из STS (т.е. без упаковки).

Когда я упаковываю приложение, используя spring-boot-maven-plugin. Это создает uber-jar, правильно содержащий neo4j-server-2.0.2-static-web.jar файл в папке / lib uber-jar.

Когда я запускаю приложение напрямую, используя файл uber-jar, а затем пытаюсь перейти по URL-адресу http://localhost:7474/browser/ для браузера Neo4j, оно возвращает ошибку 404.

Причина этого в том, что Jetty DefaultServlet пытается getResource() из WebAppContext, который, в свою очередь, вызывает JarFileResource.exists(), который пытается работать со следующей строкой URL:

jar:file:/home/dev/myapp/target/myapp-0.0.1-SNAPSHOT.jar!/lib/neo4j-browser-2.0.2.jar!/browser/

Jetty не может найти что-либо в своем списке ресурсов, поскольку ищет ресурс с именем /lib/neo4j-browser-2.0.2.jar!/browser/ в качестве кода, например на http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-util/src/main/java/org/eclipse/jetty/util/resource/JarFileResource.java#n123 (и несколько других мест) ищет первый !/ в строке.

Я собираюсь сообщить об ошибке Jetty для этого с предложением использовать String.lastIndexOf("!/") в своем коде, что решит проблему.

А пока, помимо создания нашей стандартной сборки maven, есть ли у кого-нибудь предложения, как я могу заставить это работать в убер-банке Spring Boot?

Большое спасибо.


person Dave Hallam    schedule 01.05.2014    source источник
comment
Это работает с Tomcat?   -  person Dave Syer    schedule 01.05.2014
comment
Я не пробовал использовать Tomcat, поскольку CommunityNeoServer явно использует веб-сервер Jetty 9: ref CommunityNeoServer создает один из Jetty9WebServer   -  person Dave Hallam    schedule 01.05.2014
comment
Тогда я думаю, это не приложение Spring Boot. Разве вы не можете просто запустить его так, как вам говорят ребята из Neo4j?   -  person Dave Syer    schedule 01.05.2014
comment
Это приложение Spring Boot - здесь, в котором используется сокращенный пример проекта, SpringApplication и EnableAutoConfiguration, хотя на данный момент это не демонстрирует никаких spring-boot-starter-web контроллеров или чего-либо еще. Браузерная часть Neo4j - это просто дополнительный интерфейс для просмотра базы данных.   -  person Dave Hallam    schedule 01.05.2014
comment
Часть Spring Boot предоставляет все загрузочные компоненты, например spring-boot-starter-jetty, spring-boot-starter-web, spring-boot-starter-test и т. Д. Это не проблема Spring Boot - это проблема Jetty - Spring Boot ведет себя так, как я ожидал. Мне просто интересно, есть ли обходной путь, который я мог бы развернуть (кроме сборки maven), чтобы по-прежнему использовать убер-банку Spring Boot, пока проблема с Jetty все еще существует. Не думаю, что есть - просто хотел задать вопрос.   -  person Dave Hallam    schedule 01.05.2014
comment
Что касается запуска браузера Neo4j отдельно, я не могу, так как это встроенная база данных в приложении - например, это сообщение в блоге   -  person Dave Hallam    schedule 01.05.2014
comment
Я понимаю. Я ничего не знаю о сервере Neo. Это сервлет (или что-то подобное)? Вероятно, вы могли бы просто зарегистрировать его в контексте Spring Boot и забыть о работе со встроенным сервером, который он предоставляет.   -  person Dave Syer    schedule 01.05.2014
comment
Это больше, чем просто сервлет. В коде Neo настраиваются расширения JAXRS, сервлеты, фильтры, безопасность, статический контент и т. Д. Он работает с простой сборкой maven, поэтому я пока буду придерживаться этого и посмотрю, что скажут ребята из Jetty. Большое спасибо за ваши комментарии.   -  person Dave Hallam    schedule 01.05.2014


Ответы (2)


Убер-jar-файлы Spring Boot используют некоторые специальные методы, позволяющие загружать контент из вложенных jar-файлов. Jetty (вполне понятно) предполагает, что URL-адреса jar будут содержать только один !, что, к сожалению, здесь не так.

Самым простым решением, вероятно, является переход на maven-shade-plugin. Это создает убер-банку, распаковывая все ваши зависимости, прежде чем переупаковывать их в одну банку.

Некоторые другие альтернативы предлагаются в справочной документации по Spring Boot < / а>

person Phil Webb    schedule 01.05.2014

Если вы используете SpringBoot + Maven, вы можете добавить следующее:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <requiresUnpack>
            <dependency>
                <groupId>org.neo4j.app</groupId>
                <artifactId>neo4j-browser</artifactId>
            </dependency>
        </requiresUnpack>
    </configuration>
    <executions>
       ...
</plugin>

Получено из этого предложения градиента

person Mike Holdsworth    schedule 12.03.2016