vert-x3 / vertx-web

HTTP web applications for Vert.x
Apache License 2.0
1.11k stars 531 forks source link

FileNotFoundException when using Apex in a Springboot application #104

Closed ufoscout closed 9 years ago

ufoscout commented 9 years ago

Hi all,

I am preparing a demo to show how to embed Vertx and Apex in a springboot application. The small demo code can be found here: https://github.com/ufoscout/demo-springboot-vertx3

The application has three modules:

The issue is that, when the application is started and I try to access the localhost:8080/index.html page served by Apex, the following exception is thrown:

io.vertx.core.VertxException: java.io.FileNotFoundException: /pathToTheFolder/demo-springboot-vertx3/build/target/build-0.0.1-SNAPSHOT.jar!/lib/web-0.0.1-SNAPSHOT.jar (No such file or directory)
        at io.vertx.core.impl.FileResolver.unpackFromJarURL(FileResolver.java:169)
        at io.vertx.core.impl.FileResolver.resolveFile(FileResolver.java:107)
        at io.vertx.core.impl.VertxImpl.resolveFile(VertxImpl.java:633)
        at io.vertx.core.file.impl.FileSystemImpl$6.perform(FileSystemImpl.java:517)
        at io.vertx.core.file.impl.FileSystemImpl$6.perform(FileSystemImpl.java:514)
        at io.vertx.core.file.impl.FileSystemImpl.propsBlocking(FileSystemImpl.java:150)
        at io.vertx.ext.apex.handler.impl.StaticHandlerImpl.getFileProps(StaticHandlerImpl.java:206)
        at io.vertx.ext.apex.handler.impl.StaticHandlerImpl.handle(StaticHandlerImpl.java:164)
        at io.vertx.ext.apex.handler.impl.StaticHandlerImpl.handle(StaticHandlerImpl.java:46)
        at io.vertx.ext.apex.impl.RouteImpl.handleContext(RouteImpl.java:204)
        at io.vertx.ext.apex.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:67)
        at io.vertx.ext.apex.impl.RoutingContextImpl.next(RoutingContextImpl.java:98)
        at io.vertx.ext.apex.impl.RouterImpl.accept(RouterImpl.java:61)

I expected Apex to find the webroot folder in the classpath but it seems that Apex is not able to access the web-0.0.1-SNAPSHOT.jar which is into the build-0.0.1-SNAPSHOT.jar. Of course the file is present. I am not sure of what is the cause of the issue and I am not even sure that it is a bug as it could be related to something not standard in the springboot way of creating the jar; however, I think that the use of Vertx/Apex within a spring application could become a popular configuration, so it could be worth to figure out how to solve this issue.

ufoscout commented 9 years ago

The issue is probably due to the fact that Apex does not really read the content from the classpath (i.e. directly from the jar file) but it needs to extract it somewhere. Performing this operation it expects the jar that has to be unzipped to be in a filesystem path, but in this case it is into another jar.

purplefox commented 9 years ago

Why put the web resources inside a jar which is then inside the fatjar?

Why not just wrap the resources directly in the fatjar? (like we do with vert.x fatjars)

purplefox commented 9 years ago

One thing I don't quite understand... It's very easy to use Vert.x to create a simple application in a fatjar: https://github.com/vert-x3/vertx-examples/tree/master/maven-simplest

So what is the advantage of embedding Vert.x in springboot? The end result is just an application in a fatjar, and it seems the version that only uses Vert.x is simpler than the SpringBoot version.

ufoscout commented 9 years ago

Hi Tim,

Why put the web resources inside a jar which is then inside the fatjar? Why not just wrap the resources directly in the fatjar? (like we do with vert.x fatjars)

There's no really an answer here, this is just the way spring-boot works.

So what is the advantage of embedding Vert.x in springboot?

Spring is not only about fatjar, there is a universe behind it. The use of Vertx into a spring app it's a win-win, the reactivity of vertx and the straithforward integration of thousand of technologies offered by Spring (think to Spring Cloud for example). It is, of course, a matter of personal taste, but as soon as I discussed about Vert.x in my company, people wanted to see an example of it working with Spring.

purplefox commented 9 years ago

Are you sure it's not possible to put the resources directly into the spring boot fatjar? It seems very strange to have to wrap them in another jar first.

If it's just a standard Maven project then anything from src/main/resources should end up in the jar.

ufoscout commented 9 years ago

Are you sure it's not possible to put the resources directly into the spring boot fatjar? It seems very strange to have to wrap them in another jar first.

I don't know if there is a way of setting it as you said. However, I think I have found a workaround for the issue but I have to double check it. Hope to find some time for this today or tomorrow.

purplefox commented 9 years ago

I've created a simpler example here https://github.com/purplefox/vertx-springboot

It's basically the helloworld vertx-web example from the examples repo but it's started by SpringBoot not Vert.x

purplefox commented 9 years ago

It seems that putting the resources directly in the jar works fine.

millross commented 9 years ago

I'm pretty sure that it's perfectly ok to embed the web resources directly in a Spring Boot jar, which is exactly as you found Tim (it certainly used to be when I previously played with Spring Boot). The choice to wrap them in another jar is a packaging choice only.

millross commented 9 years ago

Further to your question, it's pretty easy to integrate the other Spring technologies without Spring Boot (my current client uses Spring contexts loaded by vert.x just fine - we use Spring as a convenient local service discovery mechanism), Spring Boot is a convenience to make, for example, setting up JPA a bit easier by using the Boot conventions which are based on what jars you depend on. We certainly don't consider that we're missing out on anything by leveraging Spring without Spring Boot.

purplefox commented 9 years ago

Thanks for the insight Jez.

Just wondering if you have some spare cycles maybe you would consider adding a vanilla Spring + Vert.x example to the vertx-examples repo.

I think that would be pretty useful as we get people asking about how to use Spring + Vert.x quite a lot.

millross commented 9 years ago

Let me see what I can do over the weekend - it shouldn't take long to do a trivial one though I may stick some stuff in the readme about things which people should consider (blocking vs non-blocking calls, for example) but basically it's not hard to wrap a Spring context in a verticle which can route messagebus requests to Spring beans. I'll start trivial then we can extend later.

ufoscout commented 9 years ago

It seems that putting the resources directly in the jar works fine.

Yes, I know it, the issue happens only for multi module projects where the web resources are in a separate jar. However, I found a workaround for the original issue. Everything works fine even in a multi module project if the jar containing the web resources is declared in the "requiresUnpack" section of the spring-boot-maven-plugin configuration. E.g.:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <requiresUnpack>
            <dependency>
                <groupId>org.test</groupId>
                <artifactId>web</artifactId>
            </dependency>
        </requiresUnpack>
    </configuration>
</plugin>
millross commented 9 years ago

Hi Tim, added a spring-vertx example as a PR to the examples repo - please let me know if you want any amendments before approving it.

rworsnop commented 8 years ago

Resolved by https://github.com/eclipse/vert.x/pull/1193