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

Изпълнявам уеб приложение 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 и след това се опитам да натисна http://localhost:7474/browser/ URL за браузъра 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/ресурс/JarFileResource.java#n123 (и няколко други места) търси първото !/ в низа.

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

Междувременно, освен производството на нашата стандартна maven сборка, някой има ли някакви предложения за това как мога да накарам това да работи в рамките на uber-jar на 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
Това е приложение за пролетно зареждане - има съкратен примерен проект тук, който използва 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), за да продължа да използвам uber-jar на 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
Това е повече от обикновен сервлет. Има JAXRS разширения, сървлети, филтри, сигурност, статично съдържание и т.н., които са настроени в кода на Neo. Работи с проста сборка на maven, така че ще се придържам към това засега и ще видя какво ще кажат момчетата от Джети. Много благодаря за вашите коментари.   -  person Dave Hallam    schedule 01.05.2014


Отговори (2)


Spring Boot uber-jars използва някои специални техники, за да позволи съдържанието да бъде заредено от вложени буркани. Jetty (съвсем разбираемо) приема, че URL адресите на jar ще съдържат само един !, което за съжаление не е така тук.

Вашето най-лесно решение вероятно е да преминете към maven-shade-plugin. Това създава uber-буркан, като разопакова всички ваши зависимости, преди да ги опакова отново в един буркан.

Някои други алтернативи са предложени в справочната документация за 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>

Получено от това предложение за gradle

person Mike Holdsworth    schedule 12.03.2016