├── spring-jooq-gradle ├── settings.gradle ├── src │ ├── main │ │ ├── resources │ │ │ └── application.properties │ │ └── java │ │ │ └── org │ │ │ └── moditect │ │ │ └── jfrunit │ │ │ └── demos │ │ │ └── spring_jooq │ │ │ ├── SpringJooqGradleApplication.java │ │ │ └── TestUserService.java │ └── test │ │ └── java │ │ └── org │ │ └── moditect │ │ └── jfrunit │ │ └── demos │ │ └── spring_jooq │ │ ├── ExecuteContextSqlConverter.java │ │ └── SpringJooqGradleApplicationTests.java ├── init.sql ├── docker-compose.yaml ├── README.md ├── jooq-probes.xml ├── gradlew.bat ├── build.gradle └── gradlew ├── quarkus-hibernate-maven ├── user-service │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ ├── application.properties │ │ │ │ └── META-INF │ │ │ │ │ └── resources │ │ │ │ │ └── index.html │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── moditect │ │ │ │ │ └── jfrunit │ │ │ │ │ └── demos │ │ │ │ │ └── user │ │ │ │ │ ├── User.java │ │ │ │ │ └── UserResource.java │ │ │ └── docker │ │ │ │ ├── Dockerfile.native │ │ │ │ ├── Dockerfile.jvm │ │ │ │ └── Dockerfile.fast-jar │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── moditect │ │ │ └── jfrunit │ │ │ └── demos │ │ │ └── user │ │ │ ├── NativeGreetingResourceIT.java │ │ │ └── UserResourceTest.java │ ├── .dockerignore │ ├── README.md │ └── pom.xml ├── example-service │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ ├── init.sql │ │ │ │ ├── META-INF │ │ │ │ │ └── resources │ │ │ │ │ │ └── index.html │ │ │ │ └── application.properties │ │ │ ├── java │ │ │ │ └── org │ │ │ │ │ └── moditect │ │ │ │ │ └── jfrunit │ │ │ │ │ └── demos │ │ │ │ │ └── todo │ │ │ │ │ ├── User.java │ │ │ │ │ ├── Todo.java │ │ │ │ │ ├── TodoDetail.java │ │ │ │ │ ├── TodoWithAvatar.java │ │ │ │ │ ├── TodoWithDetails.java │ │ │ │ │ └── TodoResource.java │ │ │ └── docker │ │ │ │ ├── Dockerfile.native │ │ │ │ └── Dockerfile.jvm │ │ └── test │ │ │ └── java │ │ │ └── org │ │ │ └── moditect │ │ │ └── jfrunit │ │ │ └── demos │ │ │ └── todo │ │ │ ├── HelloJfrUnitTest.java │ │ │ ├── testutil │ │ │ ├── MatchesJson.java │ │ │ └── PostgresResource.java │ │ │ ├── TodoResourceSqlStatementsTest.java │ │ │ ├── TodoResourceMemoryAllocationTest.java │ │ │ └── TodoResourceSocketIoTest.java │ ├── .dockerignore │ ├── hibernate-probes.xml │ └── pom.xml ├── docker-compose.yaml └── README.md ├── .gitignore ├── README.md └── LICENSE.txt /spring-jooq-gradle/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'spring_jooq' 2 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/resources/init.sql: -------------------------------------------------------------------------------- 1 | create schema todo; 2 | 3 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/.dockerignore: -------------------------------------------------------------------------------- 1 | * 2 | !target/*-runner 3 | !target/*-runner.jar 4 | !target/lib/* 5 | !target/quarkus-app/* -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/README.md: -------------------------------------------------------------------------------- 1 | # User service (Quarkus) 2 | 3 | This service is used by the [example-service](../example-service/). 4 | -------------------------------------------------------------------------------- /spring-jooq-gradle/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:postgresql://localhost:5433/tododb 2 | spring.datasource.username=todouser 3 | spring.datasource.password=todopw 4 | -------------------------------------------------------------------------------- /spring-jooq-gradle/init.sql: -------------------------------------------------------------------------------- 1 | create schema todo; 2 | 3 | create table if not exists test_user 4 | ( 5 | id bigserial primary key, 6 | username text not null, 7 | age int not null 8 | ); 9 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/resources/META-INF/resources/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /spring-jooq-gradle/src/test/java/org/moditect/jfrunit/demos/spring_jooq/ExecuteContextSqlConverter.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.spring_jooq; 2 | 3 | import org.jooq.ExecuteContext; 4 | 5 | public class ExecuteContextSqlConverter { 6 | public static String convert(ExecuteContext ctx) { 7 | return ctx.sql(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/src/test/java/org/moditect/jfrunit/demos/user/NativeGreetingResourceIT.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.user; 2 | 3 | import io.quarkus.test.junit.NativeImageTest; 4 | 5 | @NativeImageTest 6 | public class NativeGreetingResourceIT extends UserResourceTest { 7 | 8 | // Execute the same tests but in native mode. 9 | } -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/src/main/java/org/moditect/jfrunit/demos/user/User.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.user; 2 | 3 | public class User { 4 | public long id; 5 | public String name; 6 | 7 | public User() { 8 | } 9 | 10 | public User(long id, String name) { 11 | this.id = id; 12 | this.name = name; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/java/org/moditect/jfrunit/demos/todo/User.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.todo; 2 | 3 | public class User { 4 | public long id; 5 | public String name; 6 | 7 | public User() { 8 | } 9 | 10 | public User(long id, String name) { 11 | this.id = id; 12 | this.name = name; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Eclipse 2 | .project 3 | .classpath 4 | .factorypath 5 | .settings/ 6 | bin/ 7 | 8 | /.idea/ 9 | 10 | # NetBeans 11 | nb-configuration.xml 12 | 13 | # Visual Studio Code 14 | .vscode 15 | 16 | # OSX 17 | .DS_Store 18 | 19 | # Vim 20 | *.swp 21 | *.swo 22 | 23 | # patch 24 | *.orig 25 | *.rej 26 | 27 | # Maven 28 | target/ 29 | 30 | # Gradle 31 | build/ 32 | .gradle/ 33 | gradle/ 34 | -------------------------------------------------------------------------------- /spring-jooq-gradle/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | 3 | services: 4 | 5 | todo-db: 6 | image: postgres:13 7 | ports: 8 | - 5433:5432 9 | environment: 10 | - POSTGRES_USER=todouser 11 | - POSTGRES_PASSWORD=todopw 12 | - POSTGRES_DB=tododb 13 | volumes: 14 | - ./init.sql:/docker-entrypoint-initdb.d/init.sql 15 | networks: 16 | - my-network 17 | networks: 18 | my-network: 19 | name: flight-recorder-network2 20 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | 3 | services: 4 | 5 | todo-db: 6 | image: postgres:13 7 | ports: 8 | - 5432:5432 9 | environment: 10 | - POSTGRES_USER=todouser 11 | - POSTGRES_PASSWORD=todopw 12 | - POSTGRES_DB=tododb 13 | volumes: 14 | - ./example-service/src/main/resources/init.sql:/docker-entrypoint-initdb.d/init.sql 15 | networks: 16 | - my-network 17 | networks: 18 | my-network: 19 | name: flight-recorder-network 20 | -------------------------------------------------------------------------------- /spring-jooq-gradle/src/main/java/org/moditect/jfrunit/demos/spring_jooq/SpringJooqGradleApplication.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.spring_jooq; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class SpringJooqGradleApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(SpringJooqGradleApplication.class, args); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /spring-jooq-gradle/README.md: -------------------------------------------------------------------------------- 1 | # Gradle + Spring Boot + JOOQ Example 2 | 3 | This example shows how to emit JFR events from jOOQ upon the execution of SQL queries. 4 | It uses [Gradle JVM toolchains](https://docs.gradle.org/current/userguide/toolchains.html) and Java 17. 5 | 6 | To run this example: 7 | 8 | ```shell 9 | cd examples/spring-jooq-gradle 10 | docker-compose up -d # Start the Postgres container on port 5433 11 | 12 | ./gradlew downloadFile # Download jmc-agent to ./build/jmc-agent 13 | ./gradlew test # Compile and test 14 | ``` 15 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/src/test/java/org/moditect/jfrunit/demos/user/UserResourceTest.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.user; 2 | 3 | import static io.restassured.RestAssured.given; 4 | import static org.hamcrest.CoreMatchers.containsString; 5 | 6 | import org.junit.jupiter.api.Test; 7 | 8 | import io.quarkus.test.junit.QuarkusTest; 9 | 10 | @QuarkusTest 11 | public class UserResourceTest { 12 | 13 | @Test 14 | public void testHelloEndpoint() { 15 | given() 16 | .when().get("/users/2") 17 | .then() 18 | .statusCode(200) 19 | .body(containsString("Alice")); 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.datasource.db-kind=postgresql 2 | quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/tododb 3 | # quarkus.datasource.driver=org.postgresql.Driver 4 | quarkus.datasource.username=todouser 5 | quarkus.datasource.password=todopw 6 | #quarkus.hibernate-orm.log.sql=true 7 | 8 | quarkus.hibernate-orm.database.generation=drop-and-create 9 | # quarkus.hibernate-orm.database.generation=update 10 | quarkus.hibernate-orm.database.default-schema=todo 11 | quarkus.log.level=INFO 12 | quarkus.log.min-level=INFO 13 | quarkus.log.console.enable=true 14 | quarkus.log.console.format=%d{HH:mm:ss} %-5p [%c] %s%e%n -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Examples for JfrUnit 2 | 3 | Some examples for spotting potential performance regressions using [JfrUnit](https://github.com/moditect/jfrunit). 4 | 5 | There are currently two examples: 6 | | Example | Technology | Description | 7 | | --- | --- | --- | 8 | | [quarkus-hibernate-maven](./quarkus-hibernate-maven) | Maven, Quarkus, Hibernate, JMC Agent, JUnit | Service Testing GC, object allocation, socket I/O, and Hibernate HQL/SQL events | 9 | | [spring-jooq-gradle](./examples/spring-jooq-gradle) | Gradle, Spring Boot, jOOQ, JMC Agent, JUnit | Service Demonstrating launching Gradle tests with the JMC Agent to test queries executed with the jOOQ DSL | 10 | 11 | ## License 12 | 13 | This code base is available under the Apache License, version 2. 14 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode 3 | # 4 | # Before building the docker image run: 5 | # 6 | # mvn package -Pnative -Dquarkus.native.container-build=true 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/flight-recorder-demo . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/flight-recorder-demo 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal 18 | WORKDIR /work/ 19 | COPY target/*-runner /work/application 20 | RUN chmod 775 /work 21 | EXPOSE 8080 22 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/src/main/docker/Dockerfile.native: -------------------------------------------------------------------------------- 1 | #### 2 | # This Dockerfile is used in order to build a container that runs the Quarkus application in native (no JVM) mode 3 | # 4 | # Before building the container image run: 5 | # 6 | # ./mvnw package -Pnative 7 | # 8 | # Then, build the image with: 9 | # 10 | # docker build -f src/main/docker/Dockerfile.native -t quarkus/user-service . 11 | # 12 | # Then run the container using: 13 | # 14 | # docker run -i --rm -p 8080:8080 quarkus/user-service 15 | # 16 | ### 17 | FROM registry.access.redhat.com/ubi8/ubi-minimal:8.3 18 | WORKDIR /work/ 19 | RUN chown 1001 /work \ 20 | && chmod "g+rwX" /work \ 21 | && chown 1001:root /work 22 | COPY --chown=1001:root target/*-runner /work/application 23 | 24 | EXPOSE 8080 25 | USER 1001 26 | 27 | CMD ["./application", "-Dquarkus.http.host=0.0.0.0"] 28 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/java/org/moditect/jfrunit/demos/todo/Todo.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.todo; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import javax.persistence.SequenceGenerator; 8 | 9 | import io.quarkus.hibernate.orm.panache.PanacheEntityBase; 10 | 11 | @Entity 12 | public class Todo extends PanacheEntityBase { 13 | 14 | @Id 15 | @SequenceGenerator( 16 | name = "todoSequence", 17 | sequenceName = "todo_id_seq", 18 | allocationSize = 10, 19 | initialValue = 1) 20 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "todoSequence") 21 | public Long id; 22 | 23 | public String title; 24 | public int priority; 25 | public boolean completed; 26 | public long userId; 27 | public String userName; 28 | } 29 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/java/org/moditect/jfrunit/demos/todo/TodoDetail.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.todo; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import javax.persistence.ManyToOne; 8 | import javax.persistence.SequenceGenerator; 9 | 10 | import com.fasterxml.jackson.annotation.JsonIgnore; 11 | 12 | import io.quarkus.hibernate.orm.panache.PanacheEntityBase; 13 | 14 | @Entity 15 | public class TodoDetail extends PanacheEntityBase { 16 | 17 | @Id 18 | @SequenceGenerator( 19 | name = "todoDetailSequence", 20 | sequenceName = "todo_detail_id_seq", 21 | allocationSize = 10, 22 | initialValue = 1) 23 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "todoDetailSequence") 24 | public Long id; 25 | 26 | @ManyToOne 27 | @JsonIgnore 28 | public TodoWithDetails todo; 29 | public String title; 30 | } 31 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/main/java/org/moditect/jfrunit/demos/todo/TodoWithAvatar.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.todo; 2 | 3 | import javax.persistence.Entity; 4 | import javax.persistence.GeneratedValue; 5 | import javax.persistence.GenerationType; 6 | import javax.persistence.Id; 7 | import javax.persistence.Lob; 8 | import javax.persistence.SequenceGenerator; 9 | 10 | import io.quarkus.hibernate.orm.panache.PanacheEntityBase; 11 | 12 | @Entity 13 | public class TodoWithAvatar extends PanacheEntityBase { 14 | 15 | @Id 16 | @SequenceGenerator( 17 | name = "todoWithAvatarSequence", 18 | sequenceName = "todo_with_avatar_id_seq", 19 | allocationSize = 10, 20 | initialValue = 1) 21 | @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "todoWithAvatarSequence") 22 | public Long id; 23 | 24 | public String title; 25 | public int priority; 26 | public boolean completed; 27 | public long userId; 28 | public String userName; 29 | 30 | @Lob 31 | public byte[] avatar; 32 | } 33 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/user-service/src/main/java/org/moditect/jfrunit/demos/user/UserResource.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.user; 2 | 3 | import javax.ws.rs.GET; 4 | import javax.ws.rs.NotFoundException; 5 | import javax.ws.rs.Path; 6 | import javax.ws.rs.PathParam; 7 | import javax.ws.rs.Produces; 8 | import javax.ws.rs.core.MediaType; 9 | 10 | @Path("/users") 11 | public class UserResource { 12 | 13 | @GET 14 | @Produces(MediaType.APPLICATION_JSON) 15 | @Path("/{id}") 16 | public User getUser(@PathParam("id") long id) { 17 | if (id == 1) { 18 | return new User(1, "Bob"); 19 | } 20 | else if (id == 2) { 21 | return new User(2, "Alice"); 22 | } 23 | else if (id == 3) { 24 | return new User(3, "Sarah"); 25 | } 26 | else if (id == 4) { 27 | return new User(4, "Brandon"); 28 | } 29 | else if (id == 5) { 30 | return new User(5, "Megan"); 31 | } 32 | else { 33 | throw new NotFoundException("No user with id " + id); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/test/java/org/moditect/jfrunit/demos/todo/HelloJfrUnitTest.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.todo; 2 | 3 | import org.junit.jupiter.api.Test; 4 | 5 | import org.moditect.jfrunit.EnableEvent; 6 | import org.moditect.jfrunit.JfrEventTest; 7 | import org.moditect.jfrunit.JfrEvents; 8 | import static org.moditect.jfrunit.JfrEventsAssert.*; 9 | 10 | import java.time.Duration; 11 | 12 | import static org.moditect.jfrunit.ExpectedEvent.*; 13 | 14 | @JfrEventTest 15 | public class HelloJfrUnitTest { 16 | 17 | public JfrEvents events = new JfrEvents(); 18 | 19 | @Test 20 | @EnableEvent("jdk.GarbageCollection") 21 | @EnableEvent("jdk.ThreadSleep") 22 | public void basicTest() throws Exception { 23 | System.gc(); 24 | Thread.sleep(1_000); 25 | 26 | events.awaitEvents(); 27 | 28 | assertThat(events).contains(event("jdk.GarbageCollection")); 29 | assertThat(events).contains(event("jdk.ThreadSleep").with("time", Duration.ofSeconds(1))); 30 | 31 | events.events() 32 | .forEach(e -> System.out.println(e)); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /spring-jooq-gradle/src/main/java/org/moditect/jfrunit/demos/spring_jooq/TestUserService.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.spring_jooq; 2 | 3 | import org.jooq.DSLContext; 4 | import org.moditect.jfrunit.demos.spring_jooq.generated.tables.TestUser; 5 | import org.moditect.jfrunit.demos.spring_jooq.generated.tables.records.TestUserRecord; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | @Service 10 | public class TestUserService { 11 | 12 | private final DSLContext dsl; 13 | 14 | @Autowired 15 | public TestUserService(DSLContext dsl) { 16 | this.dsl = dsl; 17 | } 18 | 19 | public boolean createUser(String username, int age) { 20 | int numInserted = dsl.insertInto(TestUser.TEST_USER) 21 | .set(TestUser.TEST_USER.USERNAME, username) 22 | .set(TestUser.TEST_USER.AGE, age) 23 | .execute(); 24 | return numInserted == 1; 25 | } 26 | 27 | public TestUserRecord getUserByUsername(String username) { 28 | return dsl.selectFrom(TestUser.TEST_USER) 29 | .where(TestUser.TEST_USER.USERNAME.eq(username)) 30 | .fetchOne(); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /quarkus-hibernate-maven/example-service/src/test/java/org/moditect/jfrunit/demos/todo/testutil/MatchesJson.java: -------------------------------------------------------------------------------- 1 | package org.moditect.jfrunit.demos.todo.testutil; 2 | 3 | import org.hamcrest.Description; 4 | import org.hamcrest.Matcher; 5 | import org.hamcrest.TypeSafeMatcher; 6 | import org.json.JSONException; 7 | import org.skyscreamer.jsonassert.JSONAssert; 8 | 9 | public class MatchesJson extends TypeSafeMatcherCongratulations, you have created a new Quarkus cloud application.
186 | 187 |This page is served by Quarkus. The source is in
190 | src/main/resources/META-INF/resources/index.html.
If not already done, run the application in dev mode using: ./mvnw compile quarkus:dev.
195 |
src/main/java:
198 | A Hello World RESTEasy resource
206 | 207 |src/main/resources/META-INF/resources.src/main/resources/application.properties.Go give it a star on GitHub.
220 |