diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/pom.xml b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/pom.xml
index 7c00080373e7d..5e79b5015cd8a 100644
--- a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/pom.xml
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/pom.xml
@@ -31,7 +31,27 @@
io.quarkus
- quarkus-resteasy
+ quarkus-agroal
+
+
+ io.quarkus
+ quarkus-rest
+
+
+ io.quarkus
+ quarkus-rest-jackson
+
+
+ io.quarkus
+ quarkus-hibernate-orm
+
+
+ io.quarkus
+ quarkus-arc
+
+
+ io.quarkus
+ quarkus-jdbc-postgresql
io.quarkus
diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/java/org/acme/Fruit.java b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/java/org/acme/Fruit.java
new file mode 100644
index 0000000000000..72dd4c602d87e
--- /dev/null
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/java/org/acme/Fruit.java
@@ -0,0 +1,50 @@
+package org.acme;
+
+import jakarta.persistence.Cacheable;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.Id;
+import jakarta.persistence.NamedQuery;
+import jakarta.persistence.QueryHint;
+import jakarta.persistence.SequenceGenerator;
+import jakarta.persistence.Table;
+
+@Entity
+@Table(name = "known_fruits")
+@NamedQuery(name = "Fruits.findAll", query = "SELECT f FROM Fruit f ORDER BY f.name", hints = @QueryHint(name = "org.hibernate.cacheable", value = "true"))
+@Cacheable
+public class Fruit {
+
+ @Id
+ @SequenceGenerator(name = "fruitsSequence", sequenceName = "known_fruits_id_seq", allocationSize = 1, initialValue = 10)
+ @GeneratedValue(generator = "fruitsSequence")
+ private Integer id;
+
+ @Column(length = 40, unique = true)
+ private String name;
+
+ public Fruit() {
+ }
+
+ public Fruit(String name) {
+ this.name = name;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+}
diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/java/org/acme/FruitResource.java b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/java/org/acme/FruitResource.java
new file mode 100644
index 0000000000000..cd8f8914fbb5a
--- /dev/null
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/java/org/acme/FruitResource.java
@@ -0,0 +1,124 @@
+package org.acme;
+
+import java.util.List;
+
+import jakarta.enterprise.context.ApplicationScoped;
+import jakarta.inject.Inject;
+import jakarta.persistence.EntityManager;
+import jakarta.transaction.Transactional;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+
+import org.jboss.logging.Logger;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+@Path("fruits")
+@ApplicationScoped
+@Produces("application/json")
+@Consumes("application/json")
+public class FruitResource {
+
+ private static final Logger LOGGER = Logger.getLogger(FruitResource.class.getName());
+
+ @Inject
+ EntityManager entityManager;
+
+ @GET
+ public List get() {
+ return entityManager.createNamedQuery("Fruits.findAll", Fruit.class)
+ .getResultList();
+ }
+
+ @GET
+ @Path("{id}")
+ public Fruit getSingle(Integer id) {
+ Fruit entity = entityManager.find(Fruit.class, id);
+ if (entity == null) {
+ throw new WebApplicationException("Fruit with id of " + id + " does not exist.", 404);
+ }
+ return entity;
+ }
+
+ @POST
+ @Transactional
+ public Response create(Fruit fruit) {
+ if (fruit.getId() != null) {
+ throw new WebApplicationException("Id was invalidly set on request.", 422);
+ }
+
+ entityManager.persist(fruit);
+ return Response.ok(fruit).status(201).build();
+ }
+
+ @PUT
+ @Path("{id}")
+ @Transactional
+ public Fruit update(Integer id, Fruit fruit) {
+ if (fruit.getName() == null) {
+ throw new WebApplicationException("Fruit Name was not set on request.", 422);
+ }
+
+ Fruit entity = entityManager.find(Fruit.class, id);
+
+ if (entity == null) {
+ throw new WebApplicationException("Fruit with id of " + id + " does not exist.", 404);
+ }
+
+ entity.setName(fruit.getName());
+
+ return entity;
+ }
+
+ @DELETE
+ @Path("{id}")
+ @Transactional
+ public Response delete(Integer id) {
+ Fruit entity = entityManager.getReference(Fruit.class, id);
+ if (entity == null) {
+ throw new WebApplicationException("Fruit with id of " + id + " does not exist.", 404);
+ }
+ entityManager.remove(entity);
+ return Response.status(204).build();
+ }
+
+ @Provider
+ public static class ErrorMapper implements ExceptionMapper {
+
+ @Inject
+ ObjectMapper objectMapper;
+
+ @Override
+ public Response toResponse(Exception exception) {
+ LOGGER.error("Failed to handle request", exception);
+
+ int code = 500;
+ if (exception instanceof WebApplicationException) {
+ code = ((WebApplicationException) exception).getResponse().getStatus();
+ }
+
+ ObjectNode exceptionJson = objectMapper.createObjectNode();
+ exceptionJson.put("exceptionType", exception.getClass().getName());
+ exceptionJson.put("code", code);
+
+ if (exception.getMessage() != null) {
+ exceptionJson.put("error", exception.getMessage());
+ }
+
+ return Response.status(code)
+ .entity(exceptionJson)
+ .build();
+ }
+
+ }
+}
diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/resources/application.properties b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/resources/application.properties
new file mode 100644
index 0000000000000..88e433c289c38
--- /dev/null
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/resources/application.properties
@@ -0,0 +1,2 @@
+quarkus.hibernate-orm.log.sql=true
+quarkus.hibernate-orm.sql-load-script=import.sql
diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/resources/import.sql b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/resources/import.sql
new file mode 100644
index 0000000000000..a64afab059f65
--- /dev/null
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/main/resources/import.sql
@@ -0,0 +1,4 @@
+INSERT INTO known_fruits(id, name) VALUES (1, 'Cherry');
+INSERT INTO known_fruits(id, name) VALUES (2, 'Apple');
+INSERT INTO known_fruits(id, name) VALUES (3, 'Banana');
+ALTER SEQUENCE known_fruits_id_seq RESTART WITH 4;
diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/FruitsEndpointIT.java b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/FruitsEndpointIT.java
new file mode 100644
index 0000000000000..91b15288e129c
--- /dev/null
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/FruitsEndpointIT.java
@@ -0,0 +1,10 @@
+package org.acme;
+
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+
+@QuarkusIntegrationTest
+public class FruitsEndpointIT extends FruitsEndpointTest {
+
+ // Runs the same tests as the parent class
+
+}
diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/FruitsEndpointTest.java b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/FruitsEndpointTest.java
new file mode 100644
index 0000000000000..e3027672ffd67
--- /dev/null
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/FruitsEndpointTest.java
@@ -0,0 +1,63 @@
+package org.acme;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.core.IsNot.not;
+
+import org.junit.jupiter.api.Test;
+
+import io.quarkus.test.junit.QuarkusTest;
+
+@QuarkusTest
+public class FruitsEndpointTest {
+
+ @Test
+ public void testListAllFruits() {
+ //List all, should have all 3 fruits the database has initially:
+ given()
+ .when().get("/fruits")
+ .then()
+ .statusCode(200)
+ .body(
+ containsString("Cherry"),
+ containsString("Apple"),
+ containsString("Banana"));
+
+ //Delete the Cherry:
+ given()
+ .when().delete("/fruits/1")
+ .then()
+ .statusCode(204);
+
+ //List all, cherry should be missing now:
+ given()
+ .when().get("/fruits")
+ .then()
+ .statusCode(200)
+ .body(
+ not(containsString("Cherry")),
+ containsString("Apple"),
+ containsString("Banana"));
+
+ //Create the Pear:
+ given()
+ .when()
+ .body("{\"name\" : \"Pear\"}")
+ .contentType("application/json")
+ .post("/fruits")
+ .then()
+ .statusCode(201);
+
+ //List all, cherry should be missing now:
+ given()
+ .when().get("/fruits")
+ .then()
+ .statusCode(200)
+ .body(
+ not(containsString("Cherry")),
+ containsString("Apple"),
+ containsString("Banana"),
+ containsString("Pear"));
+ }
+
+}
diff --git a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/GreetingResourceTest.java b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/GreetingResourceTest.java
index 2f0e3284d3d71..df95381a1ffe6 100644
--- a/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/GreetingResourceTest.java
+++ b/integration-tests/maven/src/test/resources-filtered/projects/native-agent-integration/src/test/java/org/acme/GreetingResourceTest.java
@@ -25,7 +25,6 @@ public void testUnknownName()
given()
.when().get("/hello/Bob")
.then()
- .statusCode(404)
- .body(is(""));
+ .statusCode(404);
}
}
\ No newline at end of file
diff --git a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java
index 3f7680375d4a6..d63eff417389e 100644
--- a/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java
+++ b/test-framework/junit5/src/main/java/io/quarkus/test/junit/QuarkusIntegrationTestExtension.java
@@ -1,6 +1,7 @@
package io.quarkus.test.junit;
import static io.quarkus.test.junit.ArtifactTypeUtil.isContainer;
+import static io.quarkus.test.junit.ArtifactTypeUtil.isJar;
import static io.quarkus.test.junit.IntegrationTestUtil.activateLogging;
import static io.quarkus.test.junit.IntegrationTestUtil.determineBuildOutputDirectory;
import static io.quarkus.test.junit.IntegrationTestUtil.determineTestProfileAndProperties;
@@ -194,7 +195,10 @@ private QuarkusTestExtensionState doProcessStart(Properties quarkusArtifactPrope
String artifactType = getArtifactType(quarkusArtifactProperties);
- boolean isDockerLaunch = isContainer(artifactType);
+ Config config = LauncherUtil.installAndGetSomeConfig();
+ String testProfile = TestConfigUtil.integrationTestProfile(config);
+ boolean isDockerLaunch = isContainer(artifactType)
+ || (isJar(artifactType) && "test-with-native-agent".equals(testProfile));
ArtifactLauncher.InitContext.DevServicesLaunchResult devServicesLaunchResult = handleDevServices(context,
isDockerLaunch);
@@ -272,10 +276,8 @@ public void close() throws Throwable {
if ((testHost != null) && !testHost.isEmpty()) {
launcher = new TestHostLauncher();
} else {
- Config config = LauncherUtil.installAndGetSomeConfig();
Duration waitDuration = TestConfigUtil.waitTimeValue(config);
String target = TestConfigUtil.runTarget(config);
- String testProfile = TestConfigUtil.integrationTestProfile(config);
// try to execute a run command published by an extension if it exists. We do this so that extensions that have a custom run don't have to create any special artifact type
launcher = RunCommandLauncher.tryLauncher(devServicesLaunchResult.getCuratedApplication().getQuarkusBootstrap(),
target, waitDuration);