Open FroMage opened 1 year ago
I'll take a look tomorrow
@FroMage do you have your sample code anywhere?
Not already, but I guess I could push it. You can't reproduce?
My point is that I don't want to try to reproduce and fail :)
Well, meet me half way :) This code should be enough, and you have to add a test for this anyway, so giving you a full project won't make your test materialise. And if it doesn't fail to reproduce, I'll give you a full project? Come to think of it, how do we even write tests for extensions?
Come to think of it, how do we even write tests for extensions?
The deployment
module tests are usually the answer
The easiest thing for me would be to just use your extension code instead of coming up with a new one
Well, OK, so I found how to write an extension test to have a special build step today:
package io.quarkus.vertx.http;
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
import org.hamcrest.Matchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import io.quarkus.builder.BuildChainBuilder;
import io.quarkus.builder.BuildContext;
import io.quarkus.builder.BuildStep;
import io.quarkus.deployment.builditem.GeneratedResourceBuildItem;
import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.vertx.http.deployment.spi.AdditionalStaticResourceBuildItem;
import io.restassured.RestAssured;
public class AdditionalStaticResourceTest {
@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.addBuildChainCustomizer(buildCustomizer());
static Consumer<BuildChainBuilder> buildCustomizer() {
return new Consumer<BuildChainBuilder>() {
@Override
public void accept(BuildChainBuilder builder) {
builder.addBuildStep(new BuildStep() {
@Override
public void execute(BuildContext context) {
String path = "/routes.js";
context.produce(new GeneratedResourceBuildItem("META-INF/resources" + path,
"//hello".getBytes(StandardCharsets.UTF_8)));
context.produce(new AdditionalStaticResourceBuildItem(path, false));
}
}).produces(GeneratedResourceBuildItem.class)
.produces(AdditionalStaticResourceBuildItem.class)
.build();
}
};
}
@Test
public void testNonApplicationEndpointDirect() {
RestAssured.given()
.when().get("/routes.js")
.then()
.statusCode(200)
.body(Matchers.is("//hello"));
}
}
Here's your reproducer ;)
Where would routes.js
be found in this test?
It's not found, it's generated by the extension:
context.produce(new GeneratedResourceBuildItem("META-INF/resources" + path,
"//hello".getBytes(StandardCharsets.UTF_8)));
Ah, okay, I misread that.
You are on way too many issues at the same time, this tells me ;)
There are a few ways to deal with this:
1) The extension actually generates a file as well (that's what excludeFromDevCL
is used for) - see this discussion
2) We could make Vert.x use the URLStreamHandler
of a URL for protocols it does not know
Huh, I thought GeneratedResourceBuildItem
would generate the file. What does it do then? And how do I generate it if not using that?
It does generates it in prod mode, in the other modes it's just kept "in memory" backed by the QuarkusClassLoader
.
Oh. So it's not clear what you're suggesting I do for 1. then ;)
You would have to actually persist it on the disk yourself
If I knew where to put it, it could be an option. I suppose this depends on the build system. Or we could stop the Quarkus CL from defining its own protocol perhaps? Is this even used by anything other than the vert.x static handler?
The protocol is not used AFAIK - but even if we do, I don't think Vert.x will work
Well, if Quarkus itself creates the file and stops using this protocol, then Vert.x will find it on disk, no?
@FroMage you need to be cautious here, because when using the classloader instead of the FS, there is a cache preventing update of the file.
FYI, I am working on a very similar issue with the Web Bundler: https://github.com/quarkiverse/quarkus-web-bundler/issues/171
Describe the bug
In my extension, I created a static resource with:
When I try to test this:
I'm getting the following exception:
This is because those are served via a Vert.x
StaticHandler
, which accesses them via the file system, and obtains the URL to the resource via theQuarkusClassLoader
: https://github.com/eclipse-vertx/vert.x/blob/master/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java#L173 and then attempts to open it in https://github.com/eclipse-vertx/vert.x/blob/bbb4ddc417a604697d2ff4f5a8eda2e74113697e/src/main/java/io/vertx/core/file/impl/FileResolverImpl.java#L225The problem is that
QuarkusClassLoader
serves it using aMemoryClassPathElement
https://github.com/quarkusio/quarkus/blob/main/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/MemoryClassPathElement.java#L86 that has aquarkus:
URL scheme, which is registered via aUrlStreamHandler
at https://github.com/quarkusio/quarkus/blob/main/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/MemoryClassPathElement.java#L131 but Vert.x doesn't know about it and doesn't know how to deal with it.I'm not sure what to do to fix this, frankly.
Expected behavior
No response
Actual behavior
No response
How to Reproduce?
No response
Output of
uname -a
orver
No response
Output of
java -version
No response
GraalVM version (if different from Java)
No response
Quarkus version or git rev
No response
Build tool (ie. output of
mvnw --version
orgradlew --version
)No response
Additional information
No response