You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ja...@apache.org on 2021/11/24 08:24:08 UTC
[camel-quarkus] branch main updated: JFR Native support
This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new c82a51c JFR Native support
c82a51c is described below
commit c82a51c72b37e3d8c6fb1377d7e27ea6f773584f
Author: James Netherton <ja...@gmail.com>
AuthorDate: Thu Nov 18 07:45:29 2021 +0000
JFR Native support
Fixes #2151
---
.../ROOT/pages/reference/extensions/jfr.adoc | 61 +++++++++++++++++----
.../ROOT/partials/reference/others/jfr.adoc | 6 +--
.../core/deployment/CamelContextProcessor.java | 3 --
.../quarkus/core/deployment/CamelProcessor.java | 8 ---
.../spi/CamelStartupStepRecorderBuildItem.java | 41 --------------
.../camel/quarkus/core/CamelContextRecorder.java | 4 --
.../quarkus/component/jfr/CamelJfrRecorder.java | 52 ------------------
extensions-jvm/pom.xml | 1 -
.../jfr/deployment/pom.xml | 0
.../component/jfr/deployment/JfrProcessor.java | 17 ++----
.../jfr/deployment/JfrConfigInterceptorTest.java | 0
{extensions-jvm => extensions}/jfr/pom.xml | 2 +-
{extensions-jvm => extensions}/jfr/runtime/pom.xml | 1 +
extensions/jfr/runtime/src/main/doc/usage.adoc | 33 ++++++++++++
.../CamelJfrConfigSourceInterceptorFactory.java | 2 +-
.../quarkus/component/jfr/CamelJfrRecorder.java | 62 ++++++++++++++++++++++
.../component/jfr/RuntimeCamelJfrConfig.java | 4 +-
.../main/resources/META-INF/quarkus-extension.yaml | 0
....smallrye.config.ConfigSourceInterceptorFactory | 0
extensions/pom.xml | 1 +
integration-tests-jvm/pom.xml | 1 -
.../jfr/pom.xml | 27 ++++++++++
.../quarkus/component/jfr/it/JfrResource.java | 0
.../camel/quarkus/component/jfr/it/JfrRoutes.java | 0
.../jfr/src/main/resources/application.properties | 19 +++++++
.../camel/quarkus/component/jfr/it/JfrIT.java | 10 ++--
.../camel/quarkus/component/jfr/it/JfrTest.java | 0
.../quarkus/component/jfr/it/JfrTestResource.java | 6 +++
integration-tests/pom.xml | 1 +
tooling/scripts/test-categories.yaml | 1 +
30 files changed, 217 insertions(+), 146 deletions(-)
diff --git a/docs/modules/ROOT/pages/reference/extensions/jfr.adoc b/docs/modules/ROOT/pages/reference/extensions/jfr.adoc
index 74ac397..d000cf7 100644
--- a/docs/modules/ROOT/pages/reference/extensions/jfr.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/jfr.adoc
@@ -3,16 +3,16 @@
= Jfr
:linkattrs:
:cq-artifact-id: camel-quarkus-jfr
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview
+:cq-native-supported: true
+:cq-status: Stable
+:cq-status-deprecation: Stable
:cq-description: Diagnose Camel applications with Java Flight Recorder
:cq-deprecated: false
:cq-jvm-since: 1.7.0
-:cq-native-since: n/a
+:cq-native-since: 2.6.0
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##1.7.0## [.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##1.7.0## [.badge-key]##Native since##[.badge-supported]##2.6.0##
Diagnose Camel applications with Java Flight Recorder
@@ -24,6 +24,10 @@ Please refer to the above link for usage and configuration details.
== Maven coordinates
+https://code.quarkus.io/?extension-search=camel-quarkus-jfr[Create a new project with this extension on code.quarkus.io, window="_blank"]
+
+Or add the coordinates to your existing project:
+
[source,xml]
----
<dependency>
@@ -34,6 +38,43 @@ Please refer to the above link for usage and configuration details.
Check the xref:user-guide/index.adoc[User guide] for more information about writing Camel Quarkus applications.
+== Usage
+
+### Starting flight recording
+
+To enable Java Flight Recorder to start a recording and automatically dump the recording to disk after Camel startup is complete, use the following configuration in `application.properties`.
+
+[source,properties]
+----
+quarkus.camel.jfr.startup-recorder-recording=true
+----
+
+Alternatively you can pass some Java options to the runnable application JAR or the native executable to enable flight recording at application startup.
+
+In JVM mode the application runnable JAR can be executed as follows.
+
+[source,shell]
+----
+$ java -XX:+FlightRecorder -XX:StartFlightRecording=filename=recording.jfr -jar quarkus-run.jar
+----
+
+In native mode, the native executable can be executed as follows.
+
+[source,shell]
+----
+$ ./my-application-runner -XX:+FlightRecorder -XX:StartFlightRecording=filename=recording.jfr
+----
+
+### Flight recording in native mode
+
+To build a native image with Java Flight Recorder support, it is mandatory to enable VM inspection via the following configuration property in `application.properties`.
+
+[source,properties]
+----
+quarkus.native.enable-vm-inspection=true
+----
+
+
== Additional Camel Quarkus configuration
[width="100%",cols="80,5,15",options="header"]
@@ -41,31 +82,31 @@ Check the xref:user-guide/index.adoc[User guide] for more information about writ
| Configuration property | Type | Default
-|icon:lock[title=Fixed at build time] [[quarkus.camel.jfr.startup-recorder-dir]]`link:#quarkus.camel.jfr.startup-recorder-dir[quarkus.camel.jfr.startup-recorder-dir]`
+| [[quarkus.camel.jfr.startup-recorder-dir]]`link:#quarkus.camel.jfr.startup-recorder-dir[quarkus.camel.jfr.startup-recorder-dir]`
Directory to store the recording. By default the current directory will be used. Use false to turn off saving the recording to disk.
| `string`
|
-|icon:lock[title=Fixed at build time] [[quarkus.camel.jfr.startup-recorder-duration]]`link:#quarkus.camel.jfr.startup-recorder-duration[quarkus.camel.jfr.startup-recorder-duration]`
+| [[quarkus.camel.jfr.startup-recorder-duration]]`link:#quarkus.camel.jfr.startup-recorder-duration[quarkus.camel.jfr.startup-recorder-duration]`
How long time to run the startup recorder. Use 0 (default) to keep the recorder running until the JVM is exited. Use -1 to stop the recorder right after Camel has been started (to only focus on potential Camel startup performance bottlenecks) Use a positive value to keep recording for N seconds. When the recorder is stopped then the recording is auto saved to disk (note: save to disk can be disabled by setting startupRecorderDir to false).
| `java.lang.Long`
|
-|icon:lock[title=Fixed at build time] [[quarkus.camel.jfr.startup-recorder-max-depth]]`link:#quarkus.camel.jfr.startup-recorder-max-depth[quarkus.camel.jfr.startup-recorder-max-depth]`
+| [[quarkus.camel.jfr.startup-recorder-max-depth]]`link:#quarkus.camel.jfr.startup-recorder-max-depth[quarkus.camel.jfr.startup-recorder-max-depth]`
To filter our sub steps at a maximum depth. Use -1 for no maximum. Use 0 for no sub steps. Use 1 for max 1 sub step, and so forth. The default is -1.
| `java.lang.Integer`
|
-|icon:lock[title=Fixed at build time] [[quarkus.camel.jfr.startup-recorder-profile]]`link:#quarkus.camel.jfr.startup-recorder-profile[quarkus.camel.jfr.startup-recorder-profile]`
+| [[quarkus.camel.jfr.startup-recorder-profile]]`link:#quarkus.camel.jfr.startup-recorder-profile[quarkus.camel.jfr.startup-recorder-profile]`
To use a specific Java Flight Recorder profile configuration, such as default or profile. The default is default.
| `string`
|
-|icon:lock[title=Fixed at build time] [[quarkus.camel.jfr.startup-recorder-recording]]`link:#quarkus.camel.jfr.startup-recorder-recording[quarkus.camel.jfr.startup-recorder-recording]`
+| [[quarkus.camel.jfr.startup-recorder-recording]]`link:#quarkus.camel.jfr.startup-recorder-recording[quarkus.camel.jfr.startup-recorder-recording]`
To enable Java Flight Recorder to start a recording and automatic dump the recording to disk after startup is complete. This requires that camel-jfr is on the classpath. The default is false.
| `java.lang.Boolean`
diff --git a/docs/modules/ROOT/partials/reference/others/jfr.adoc b/docs/modules/ROOT/partials/reference/others/jfr.adoc
index b3d4714..c7ba938 100644
--- a/docs/modules/ROOT/partials/reference/others/jfr.adoc
+++ b/docs/modules/ROOT/partials/reference/others/jfr.adoc
@@ -2,11 +2,11 @@
// This file was generated by camel-quarkus-maven-plugin:update-extension-doc-page
:cq-artifact-id: camel-quarkus-jfr
:cq-artifact-id-base: jfr
-:cq-native-supported: false
-:cq-status: Preview
+:cq-native-supported: true
+:cq-status: Stable
:cq-deprecated: false
:cq-jvm-since: 1.7.0
-:cq-native-since: n/a
+:cq-native-since: 2.6.0
:cq-camel-part-name: jfr
:cq-camel-part-title: Jfr
:cq-camel-part-description: Diagnose Camel applications with Java Flight Recorder
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelContextProcessor.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelContextProcessor.java
index 814ac56..5d2f023 100644
--- a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelContextProcessor.java
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelContextProcessor.java
@@ -47,7 +47,6 @@ import org.apache.camel.quarkus.core.deployment.spi.CamelRegistryBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelRoutesBuilderClassBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelRuntimeTaskBuildItem;
-import org.apache.camel.quarkus.core.deployment.spi.CamelStartupStepRecorderBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelTypeConverterRegistryBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.ContainerBeansBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.RuntimeCamelContextCustomizerBuildItem;
@@ -81,7 +80,6 @@ public class CamelContextProcessor {
CamelModelToXMLDumperBuildItem modelDumper,
CamelFactoryFinderResolverBuildItem factoryFinderResolver,
List<CamelContextCustomizerBuildItem> customizers,
- CamelStartupStepRecorderBuildItem startupStepRecorder,
CamelComponentNameResolverBuildItem componentNameResolver,
CamelConfig config) {
@@ -91,7 +89,6 @@ public class CamelContextProcessor {
modelJAXBContextFactory.getContextFactory(),
modelDumper.getValue(),
factoryFinderResolver.getFactoryFinderResolver(),
- startupStepRecorder.getValue(),
componentNameResolver.getComponentNameResolver(),
beanContainer.getValue(),
CamelSupport.getCamelVersion(),
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
index a333305..639e386 100644
--- a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
+++ b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/CamelProcessor.java
@@ -65,7 +65,6 @@ import org.apache.camel.quarkus.core.deployment.spi.CamelServiceDestination;
import org.apache.camel.quarkus.core.deployment.spi.CamelServiceFilter;
import org.apache.camel.quarkus.core.deployment.spi.CamelServiceFilterBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelServicePatternBuildItem;
-import org.apache.camel.quarkus.core.deployment.spi.CamelStartupStepRecorderBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelTypeConverterLoaderBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.CamelTypeConverterRegistryBuildItem;
import org.apache.camel.quarkus.core.deployment.spi.ContainerBeansBuildItem;
@@ -334,13 +333,6 @@ class CamelProcessor {
return new CamelFactoryFinderResolverBuildItem(recorder.factoryFinderResolver(builder));
}
- @Overridable
- @BuildStep
- @Record(value = ExecutionTime.STATIC_INIT, optional = true)
- public CamelStartupStepRecorderBuildItem createStartupStepRecorder(CamelRecorder recorder) {
- return new CamelStartupStepRecorderBuildItem(recorder.newDefaultStartupStepRecorder());
- }
-
@BuildStep
UnremovableBeanBuildItem unremovableRoutesBuilders() {
return new UnremovableBeanBuildItem(
diff --git a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CamelStartupStepRecorderBuildItem.java b/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CamelStartupStepRecorderBuildItem.java
deleted file mode 100644
index cd4229f..0000000
--- a/extensions-core/core/deployment/src/main/java/org/apache/camel/quarkus/core/deployment/spi/CamelStartupStepRecorderBuildItem.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.quarkus.core.deployment.spi;
-
-import io.quarkus.builder.item.SimpleBuildItem;
-import io.quarkus.runtime.RuntimeValue;
-import org.apache.camel.spi.StartupStepRecorder;
-
-/**
- * Holds the {@link RuntimeValue} of a {@link StartupStepRecorder} to be configured on the CamelContext.
- *
- * By default this BuildItem is produced holding a {@link org.apache.camel.support.startup.DefaultStartupStepRecorder}.
- *
- * However, this is overridable by other extensions that choose to produce CamelStartupStepRecorderBuildItem with a
- * different {@link StartupStepRecorder} implementation.
- */
-public final class CamelStartupStepRecorderBuildItem extends SimpleBuildItem {
- private final RuntimeValue<StartupStepRecorder> value;
-
- public CamelStartupStepRecorderBuildItem(RuntimeValue<StartupStepRecorder> value) {
- this.value = value;
- }
-
- public RuntimeValue<StartupStepRecorder> getValue() {
- return value;
- }
-}
diff --git a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelContextRecorder.java b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelContextRecorder.java
index 1e03f27..d73891b 100644
--- a/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelContextRecorder.java
+++ b/extensions-core/core/runtime/src/main/java/org/apache/camel/quarkus/core/CamelContextRecorder.java
@@ -22,7 +22,6 @@ import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import org.apache.camel.CamelContext;
-import org.apache.camel.ExtendedCamelContext;
import org.apache.camel.RoutesBuilder;
import org.apache.camel.builder.LambdaRouteBuilder;
import org.apache.camel.builder.RouteBuilder;
@@ -33,7 +32,6 @@ import org.apache.camel.spi.FactoryFinderResolver;
import org.apache.camel.spi.ModelJAXBContextFactory;
import org.apache.camel.spi.ModelToXMLDumper;
import org.apache.camel.spi.Registry;
-import org.apache.camel.spi.StartupStepRecorder;
import org.apache.camel.spi.TypeConverterRegistry;
@Recorder
@@ -44,7 +42,6 @@ public class CamelContextRecorder {
RuntimeValue<ModelJAXBContextFactory> contextFactory,
RuntimeValue<ModelToXMLDumper> xmlModelDumper,
RuntimeValue<FactoryFinderResolver> factoryFinderResolver,
- RuntimeValue<StartupStepRecorder> startupStepRecorder,
RuntimeValue<ComponentNameResolver> componentNameResolver,
BeanContainer beanContainer,
String version,
@@ -63,7 +60,6 @@ public class CamelContextRecorder {
context.setTypeConverterRegistry(typeConverterRegistry.getValue());
context.setLoadTypeConverters(false);
context.setModelJAXBContextFactory(contextFactory.getValue());
- context.adapt(ExtendedCamelContext.class).setStartupStepRecorder(startupStepRecorder.getValue());
context.build();
context.setComponentNameResolver(componentNameResolver.getValue());
diff --git a/extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrRecorder.java b/extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrRecorder.java
deleted file mode 100644
index 53cc277..0000000
--- a/extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrRecorder.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.quarkus.component.jfr;
-
-import io.quarkus.runtime.RuntimeValue;
-import io.quarkus.runtime.annotations.Recorder;
-import org.apache.camel.spi.StartupStepRecorder;
-import org.apache.camel.startup.jfr.FlightRecorderStartupStepRecorder;
-
-@Recorder
-public class CamelJfrRecorder {
-
- public RuntimeValue<StartupStepRecorder> createStartupStepRecorder(CamelJfrConfig config) {
- FlightRecorderStartupStepRecorder flightRecorder = new FlightRecorderStartupStepRecorder();
-
- if (config.startupRecorderRecording.isPresent()) {
- flightRecorder.setRecording(config.startupRecorderRecording.get());
- }
-
- if (config.startupRecorderProfile.isPresent()) {
- flightRecorder.setRecordingProfile(config.startupRecorderProfile.get());
- }
-
- if (config.startupRecorderMaxDepth.isPresent()) {
- flightRecorder.setMaxDepth(config.startupRecorderMaxDepth.get());
- }
-
- if (config.startupRecorderDuration.isPresent()) {
- flightRecorder.setStartupRecorderDuration(config.startupRecorderDuration.get());
- }
-
- if (config.startupRecorderDir.isPresent()) {
- flightRecorder.setRecordingDir(config.startupRecorderDir.get());
- }
-
- return new RuntimeValue<>(flightRecorder);
- }
-}
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index f217db0..61f0a1a 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -83,7 +83,6 @@
<module>jcache</module>
<module>jclouds</module>
<module>jcr</module>
- <module>jfr</module>
<module>jgroups</module>
<module>jgroups-raft</module>
<module>jooq</module>
diff --git a/extensions-jvm/jfr/deployment/pom.xml b/extensions/jfr/deployment/pom.xml
similarity index 100%
rename from extensions-jvm/jfr/deployment/pom.xml
rename to extensions/jfr/deployment/pom.xml
diff --git a/extensions-jvm/jfr/deployment/src/main/java/org/apache/camel/quarkus/component/jfr/deployment/JfrProcessor.java b/extensions/jfr/deployment/src/main/java/org/apache/camel/quarkus/component/jfr/deployment/JfrProcessor.java
similarity index 73%
rename from extensions-jvm/jfr/deployment/src/main/java/org/apache/camel/quarkus/component/jfr/deployment/JfrProcessor.java
rename to extensions/jfr/deployment/src/main/java/org/apache/camel/quarkus/component/jfr/deployment/JfrProcessor.java
index 8956642..58ad85a 100644
--- a/extensions-jvm/jfr/deployment/src/main/java/org/apache/camel/quarkus/component/jfr/deployment/JfrProcessor.java
+++ b/extensions/jfr/deployment/src/main/java/org/apache/camel/quarkus/component/jfr/deployment/JfrProcessor.java
@@ -20,13 +20,12 @@ import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.deployment.annotations.ExecutionTime;
import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeBuild;
-import org.apache.camel.quarkus.component.jfr.CamelJfrConfig;
import org.apache.camel.quarkus.component.jfr.CamelJfrRecorder;
+import org.apache.camel.quarkus.component.jfr.RuntimeCamelJfrConfig;
import org.apache.camel.quarkus.core.deployment.main.spi.CamelMainEnabled;
import org.apache.camel.quarkus.core.deployment.spi.CamelServiceDestination;
import org.apache.camel.quarkus.core.deployment.spi.CamelServicePatternBuildItem;
-import org.apache.camel.quarkus.core.deployment.spi.CamelStartupStepRecorderBuildItem;
+import org.apache.camel.quarkus.core.deployment.spi.RuntimeCamelContextCustomizerBuildItem;
class JfrProcessor {
@@ -44,15 +43,9 @@ class JfrProcessor {
"META-INF/services/org/apache/camel/startup-step-recorder");
}
+ @Record(value = ExecutionTime.RUNTIME_INIT)
@BuildStep
- @Record(value = ExecutionTime.STATIC_INIT, optional = true)
- CamelStartupStepRecorderBuildItem customizeCamelContext(CamelJfrConfig config, CamelJfrRecorder recorder) {
- return new CamelStartupStepRecorderBuildItem(recorder.createStartupStepRecorder(config));
- }
-
- @BuildStep(onlyIf = NativeBuild.class)
- void nativeUnsupported() {
- throw new RuntimeException("The " + FEATURE + " extension is not supported in native mode "
- + "as JFR APIs are not fully supported on GraalVM");
+ RuntimeCamelContextCustomizerBuildItem customizeCamelContext(RuntimeCamelJfrConfig config, CamelJfrRecorder recorder) {
+ return new RuntimeCamelContextCustomizerBuildItem(recorder.createStartupStepRecorder(config));
}
}
diff --git a/extensions-jvm/jfr/deployment/src/test/java/org/apache/camel/quarkus/component/jfr/deployment/JfrConfigInterceptorTest.java b/extensions/jfr/deployment/src/test/java/org/apache/camel/quarkus/component/jfr/deployment/JfrConfigInterceptorTest.java
similarity index 100%
rename from extensions-jvm/jfr/deployment/src/test/java/org/apache/camel/quarkus/component/jfr/deployment/JfrConfigInterceptorTest.java
rename to extensions/jfr/deployment/src/test/java/org/apache/camel/quarkus/component/jfr/deployment/JfrConfigInterceptorTest.java
diff --git a/extensions-jvm/jfr/pom.xml b/extensions/jfr/pom.xml
similarity index 96%
rename from extensions-jvm/jfr/pom.xml
rename to extensions/jfr/pom.xml
index 468facc..2d0ca9c 100644
--- a/extensions-jvm/jfr/pom.xml
+++ b/extensions/jfr/pom.xml
@@ -21,7 +21,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-jvm</artifactId>
+ <artifactId>camel-quarkus-extensions</artifactId>
<version>2.6.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
diff --git a/extensions-jvm/jfr/runtime/pom.xml b/extensions/jfr/runtime/pom.xml
similarity index 98%
rename from extensions-jvm/jfr/runtime/pom.xml
rename to extensions/jfr/runtime/pom.xml
index 5586f29..396c01b 100644
--- a/extensions-jvm/jfr/runtime/pom.xml
+++ b/extensions/jfr/runtime/pom.xml
@@ -32,6 +32,7 @@
<properties>
<camel.quarkus.jvmSince>1.7.0</camel.quarkus.jvmSince>
+ <camel.quarkus.nativeSince>2.6.0</camel.quarkus.nativeSince>
</properties>
<dependencyManagement>
diff --git a/extensions/jfr/runtime/src/main/doc/usage.adoc b/extensions/jfr/runtime/src/main/doc/usage.adoc
new file mode 100644
index 0000000..d4e75f8
--- /dev/null
+++ b/extensions/jfr/runtime/src/main/doc/usage.adoc
@@ -0,0 +1,33 @@
+### Starting flight recording
+
+To enable Java Flight Recorder to start a recording and automatically dump the recording to disk after Camel startup is complete, use the following configuration in `application.properties`.
+
+[source,properties]
+----
+quarkus.camel.jfr.startup-recorder-recording=true
+----
+
+Alternatively you can pass some Java options to the runnable application JAR or the native executable to enable flight recording at application startup.
+
+In JVM mode the application runnable JAR can be executed as follows.
+
+[source,shell]
+----
+$ java -XX:+FlightRecorder -XX:StartFlightRecording=filename=recording.jfr -jar quarkus-run.jar
+----
+
+In native mode, the native executable can be executed as follows.
+
+[source,shell]
+----
+$ ./my-application-runner -XX:+FlightRecorder -XX:StartFlightRecording=filename=recording.jfr
+----
+
+### Flight recording in native mode
+
+To build a native image with Java Flight Recorder support, it is mandatory to enable VM inspection via the following configuration property in `application.properties`.
+
+[source,properties]
+----
+quarkus.native.enable-vm-inspection=true
+----
diff --git a/extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfigSourceInterceptorFactory.java b/extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfigSourceInterceptorFactory.java
similarity index 96%
rename from extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfigSourceInterceptorFactory.java
rename to extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfigSourceInterceptorFactory.java
index 082e6c2..5b56763 100644
--- a/extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfigSourceInterceptorFactory.java
+++ b/extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfigSourceInterceptorFactory.java
@@ -25,7 +25,7 @@ import io.smallrye.config.ConfigValue;
import io.smallrye.config.Priorities;
/**
- * Map {@link CamelJfrConfig} startupRecorder properties to their equivalents in camel main.
+ * Map {@link RuntimeCamelJfrConfig} startupRecorder properties to their equivalents in camel main.
*/
public class CamelJfrConfigSourceInterceptorFactory implements ConfigSourceInterceptorFactory {
diff --git a/extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrRecorder.java b/extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrRecorder.java
new file mode 100644
index 0000000..56b4a9b
--- /dev/null
+++ b/extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrRecorder.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.quarkus.component.jfr;
+
+import io.quarkus.runtime.RuntimeValue;
+import io.quarkus.runtime.annotations.Recorder;
+import org.apache.camel.CamelContext;
+import org.apache.camel.ExtendedCamelContext;
+import org.apache.camel.spi.CamelContextCustomizer;
+import org.apache.camel.startup.jfr.FlightRecorderStartupStepRecorder;
+
+@Recorder
+public class CamelJfrRecorder {
+
+ public RuntimeValue<CamelContextCustomizer> createStartupStepRecorder(RuntimeCamelJfrConfig config) {
+ CamelContextCustomizer flightRecorderCustomizer = new CamelContextCustomizer() {
+ @Override
+ public void configure(CamelContext camelContext) {
+ FlightRecorderStartupStepRecorder flightRecorder = new FlightRecorderStartupStepRecorder();
+
+ if (config.startupRecorderRecording.isPresent()) {
+ flightRecorder.setRecording(config.startupRecorderRecording.get());
+ }
+
+ if (config.startupRecorderProfile.isPresent()) {
+ flightRecorder.setRecordingProfile(config.startupRecorderProfile.get());
+ }
+
+ if (config.startupRecorderMaxDepth.isPresent()) {
+ flightRecorder.setMaxDepth(config.startupRecorderMaxDepth.get());
+ }
+
+ if (config.startupRecorderDuration.isPresent()) {
+ flightRecorder.setStartupRecorderDuration(config.startupRecorderDuration.get());
+ }
+
+ if (config.startupRecorderDir.isPresent()) {
+ flightRecorder.setRecordingDir(config.startupRecorderDir.get());
+ }
+
+ camelContext.getExtension(ExtendedCamelContext.class).setStartupStepRecorder(flightRecorder);
+ flightRecorder.setEnabled(true);
+ flightRecorder.start();
+ }
+ };
+ return new RuntimeValue<>(flightRecorderCustomizer);
+ }
+}
diff --git a/extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfig.java b/extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/RuntimeCamelJfrConfig.java
similarity index 95%
rename from extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfig.java
rename to extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/RuntimeCamelJfrConfig.java
index 2e27c9e..625b553 100644
--- a/extensions-jvm/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/CamelJfrConfig.java
+++ b/extensions/jfr/runtime/src/main/java/org/apache/camel/quarkus/component/jfr/RuntimeCamelJfrConfig.java
@@ -22,8 +22,8 @@ import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigPhase;
import io.quarkus.runtime.annotations.ConfigRoot;
-@ConfigRoot(name = "camel.jfr", phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
-public class CamelJfrConfig {
+@ConfigRoot(name = "camel.jfr", phase = ConfigPhase.RUN_TIME)
+public class RuntimeCamelJfrConfig {
/**
* Directory to store the recording. By default the current directory will be used. Use false to turn off saving the
diff --git a/extensions-jvm/jfr/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/jfr/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 100%
rename from extensions-jvm/jfr/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to extensions/jfr/runtime/src/main/resources/META-INF/quarkus-extension.yaml
diff --git a/extensions-jvm/jfr/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory b/extensions/jfr/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory
similarity index 100%
rename from extensions-jvm/jfr/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory
rename to extensions/jfr/runtime/src/main/resources/META-INF/services/io.smallrye.config.ConfigSourceInterceptorFactory
diff --git a/extensions/pom.xml b/extensions/pom.xml
index af13fe4..7804bcf 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -132,6 +132,7 @@
<module>jacksonxml</module>
<module>jaxb</module>
<module>jdbc</module>
+ <module>jfr</module>
<module>jing</module>
<module>jira</module>
<module>jms</module>
diff --git a/integration-tests-jvm/pom.xml b/integration-tests-jvm/pom.xml
index 2242cfe..3abd6b8 100644
--- a/integration-tests-jvm/pom.xml
+++ b/integration-tests-jvm/pom.xml
@@ -81,7 +81,6 @@
<module>jcache</module>
<module>jclouds</module>
<module>jcr</module>
- <module>jfr</module>
<module>jgroups</module>
<module>jgroups-raft</module>
<module>jooq</module>
diff --git a/integration-tests-jvm/jfr/pom.xml b/integration-tests/jfr/pom.xml
similarity index 83%
rename from integration-tests-jvm/jfr/pom.xml
rename to integration-tests/jfr/pom.xml
index 37d195c..882c0aa 100644
--- a/integration-tests-jvm/jfr/pom.xml
+++ b/integration-tests/jfr/pom.xml
@@ -112,5 +112,32 @@
</dependency>
</dependencies>
</profile>
+ <profile>
+ <id>native</id>
+ <activation>
+ <property>
+ <name>native</name>
+ </property>
+ </activation>
+ <properties>
+ <quarkus.package.type>native</quarkus.package.type>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
</profiles>
</project>
diff --git a/integration-tests-jvm/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrResource.java b/integration-tests/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrResource.java
similarity index 100%
rename from integration-tests-jvm/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrResource.java
rename to integration-tests/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrResource.java
diff --git a/integration-tests-jvm/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrRoutes.java b/integration-tests/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrRoutes.java
similarity index 100%
copy from integration-tests-jvm/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrRoutes.java
copy to integration-tests/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrRoutes.java
diff --git a/integration-tests/jfr/src/main/resources/application.properties b/integration-tests/jfr/src/main/resources/application.properties
new file mode 100644
index 0000000..715da7f
--- /dev/null
+++ b/integration-tests/jfr/src/main/resources/application.properties
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## Licensed to the Apache Software Foundation (ASF) under one or more
+## contributor license agreements. See the NOTICE file distributed with
+## this work for additional information regarding copyright ownership.
+## The ASF licenses this file to You under the Apache License, Version 2.0
+## (the "License"); you may not use this file except in compliance with
+## the License. You may obtain a copy of the License at
+##
+## http://www.apache.org/licenses/LICENSE-2.0
+##
+## Unless required by applicable law or agreed to in writing, software
+## distributed under the License is distributed on an "AS IS" BASIS,
+## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+## See the License for the specific language governing permissions and
+## limitations under the License.
+## ---------------------------------------------------------------------------
+
+# Must enable VM inspection for JFR in native mode
+quarkus.native.enable-vm-inspection=true
diff --git a/integration-tests-jvm/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrRoutes.java b/integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrIT.java
similarity index 77%
rename from integration-tests-jvm/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrRoutes.java
rename to integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrIT.java
index 5b8aa6d..418aa68 100644
--- a/integration-tests-jvm/jfr/src/main/java/org/apache/camel/quarkus/component/jfr/it/JfrRoutes.java
+++ b/integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrIT.java
@@ -16,13 +16,9 @@
*/
package org.apache.camel.quarkus.component.jfr.it;
-import org.apache.camel.builder.RouteBuilder;
+import io.quarkus.test.junit.NativeImageTest;
-public class JfrRoutes extends RouteBuilder {
+@NativeImageTest
+class JfrIT extends JfrTest {
- @Override
- public void configure() throws Exception {
- from("timer:tick?repeatCount=1&delay=-1")
- .log("Timer tick...");
- }
}
diff --git a/integration-tests-jvm/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTest.java b/integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTest.java
similarity index 100%
rename from integration-tests-jvm/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTest.java
rename to integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTest.java
diff --git a/integration-tests-jvm/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTestResource.java b/integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTestResource.java
similarity index 89%
rename from integration-tests-jvm/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTestResource.java
rename to integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTestResource.java
index 7f6e601..0a7eeaf 100644
--- a/integration-tests-jvm/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTestResource.java
+++ b/integration-tests/jfr/src/test/java/org/apache/camel/quarkus/component/jfr/it/JfrTestResource.java
@@ -23,6 +23,7 @@ import java.util.Map;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
import org.apache.camel.util.CollectionHelper;
+import org.apache.commons.io.FileUtils;
public class JfrTestResource implements QuarkusTestResourceLifecycleManager {
@@ -45,5 +46,10 @@ public class JfrTestResource implements QuarkusTestResourceLifecycleManager {
@Override
public void stop() {
+ try {
+ FileUtils.deleteDirectory(JFR_RECORDINGS_DIR.toFile());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 1c71420..0c80c69 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -115,6 +115,7 @@
<module>jackson-protobuf</module>
<module>jaxb</module>
<module>jdbc</module>
+ <module>jfr</module>
<module>jing</module>
<module>jira</module>
<module>jms-artemis-client</module>
diff --git a/tooling/scripts/test-categories.yaml b/tooling/scripts/test-categories.yaml
index 0533f29..9811bba 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -38,6 +38,7 @@ group-02:
- grpc
- jackson-avro
- jackson-protobuf
+ - jfr
- oaipmh
- pubnub
- protobuf