This is an automated email from the ASF dual-hosted git repository.

pcongiusti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit 8a82e3fda8b213dbb47c90d7f6cf9123cc2e403a
Author: Pasquale Congiusti <[email protected]>
AuthorDate: Thu May 23 12:13:40 2024 +0200

    feat(trait): jvm refactoring
    
    * add more unit test
    * enable the trait for synthetic Kits
    * add documentation on the jvm trait usage
    
    Closes #5476
---
 docs/modules/ROOT/partials/apis/camel-k-crds.adoc  |  11 +-
 docs/modules/traits/pages/builder.adoc             |   3 +-
 docs/modules/traits/pages/jvm.adoc                 |  18 +-
 e2e/common/runtimes/runtimes_test.go               |   6 +-
 e2e/common/traits/builder_test.go                  |  13 +
 e2e/support/test_support.go                        |  10 +
 helm/camel-k/crds/crd-integration-kit.yaml         |   4 +-
 helm/camel-k/crds/crd-integration-platform.yaml    |  26 +-
 helm/camel-k/crds/crd-integration-profile.yaml     |  26 +-
 helm/camel-k/crds/crd-integration.yaml             |  13 +-
 helm/camel-k/crds/crd-kamelet-binding.yaml         |  14 +-
 helm/camel-k/crds/crd-pipe.yaml                    |  14 +-
 pkg/apis/camel/v1/trait/builder.go                 |   3 +-
 pkg/apis/camel/v1/trait/jvm.go                     |   3 +
 pkg/cmd/run_test.go                                |   4 +-
 .../bases/camel.apache.org_integrationkits.yaml    |   4 +-
 .../camel.apache.org_integrationplatforms.yaml     |  26 +-
 .../camel.apache.org_integrationprofiles.yaml      |  26 +-
 .../crd/bases/camel.apache.org_integrations.yaml   |  13 +-
 .../bases/camel.apache.org_kameletbindings.yaml    |  14 +-
 .../config/crd/bases/camel.apache.org_pipes.yaml   |  14 +-
 pkg/trait/jvm.go                                   | 213 +++++++------
 pkg/trait/jvm_test.go                              | 355 ++++++++++++++++++---
 23 files changed, 634 insertions(+), 199 deletions(-)

diff --git a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc 
b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
index b795ce1df..65d6a742a 100644
--- a/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
+++ b/docs/modules/ROOT/partials/apis/camel-k-crds.adoc
@@ -6234,7 +6234,8 @@ string
 |
 
 
-Specify a base image
+Specify a base image. In order to have the application working properly it 
must be a container image which has a Java JDK
+installed and ready to use on path (ie `/usr/bin/java`).
 
 |`incrementalImageBuild` +
 bool
@@ -7306,6 +7307,7 @@ bool
 
 
 Prints the command used the start the JVM in the container logs (default 
`true`)
+Deprecated: no longer in use.
 
 |`debugAddress` +
 string
@@ -7328,6 +7330,13 @@ string
 
 Additional JVM classpath (use `Linux` classpath separator)
 
+|`jar` +
+string
+|
+
+
+The Jar dependency which will run the application. Leave it empty for managed 
Integrations.
+
 
 |===
 
diff --git a/docs/modules/traits/pages/builder.adoc 
b/docs/modules/traits/pages/builder.adoc
index 7f3c280f3..221539ab4 100755
--- a/docs/modules/traits/pages/builder.adoc
+++ b/docs/modules/traits/pages/builder.adoc
@@ -45,7 +45,8 @@ Deprecated no longer in use
 
 | builder.base-image
 | string
-| Specify a base image
+| Specify a base image. In order to have the application working properly it 
must be a container image which has a Java JDK
+installed and ready to use on path (ie `/usr/bin/java`).
 
 | builder.incremental-image-build
 | bool
diff --git a/docs/modules/traits/pages/jvm.adoc 
b/docs/modules/traits/pages/jvm.adoc
index a9b1ed480..20f7b2c63 100755
--- a/docs/modules/traits/pages/jvm.adoc
+++ b/docs/modules/traits/pages/jvm.adoc
@@ -40,6 +40,7 @@ The following configuration options are available:
 | jvm.print-command
 | bool
 | Prints the command used the start the JVM in the container logs (default 
`true`)
+Deprecated: no longer in use.
 
 | jvm.debug-address
 | string
@@ -53,11 +54,26 @@ The following configuration options are available:
 | string
 | Additional JVM classpath (use `Linux` classpath separator)
 
+| jvm.jar
+| string
+| The Jar dependency which will run the application. Leave it empty for 
managed Integrations.
+
 |===
 
 // End of autogenerated code - DO NOT EDIT! (configuration)
 
-== Examples
+== Usage of jar parameters
+
+The `jar` parameter is something the user should not worry about, unless that, 
for any reason, he wants to specify which is the executable dependency to use. 
Mind that, in order to do that, the base image used to build the container 
require a java binary executable from path (ie, `/usr/bin/java`).
+
+This parameters enables also the possibility to use the trait when running a 
synthetic IntegrationKit (ie, "sourceless" Integrations). In such 
circumstances, the user can run a Camel application built externally and make 
use of the trait configuration as well as for example:
+
+[source,console]
+$ kamel run --image docker.io/squakez/my-camel-sb:1.0.0 -t 
jvm.jar=/deployments/my-camel-app.jar -t jvm.options=-Xmx1024M
+
+The above command would allow the execution of the JVM trait given that the 
user specify the path to the jar to execute.
+
+== Other examples
 
 * Include an additional classpath to the `Integration`:
 +
diff --git a/e2e/common/runtimes/runtimes_test.go 
b/e2e/common/runtimes/runtimes_test.go
index dee3ae100..b6e2a3a34 100644
--- a/e2e/common/runtimes/runtimes_test.go
+++ b/e2e/common/runtimes/runtimes_test.go
@@ -54,7 +54,7 @@ func TestSourceLessIntegrations(t *testing.T) {
                        g.Expect(KamelRunWithID(t, ctx, operatorID, ns, 
"--image", "docker.io/squakez/my-camel-main:1.0.0", "--resource", 
"configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed())
                        g.Eventually(IntegrationPodPhase(t, ctx, ns, itName), 
TestTimeoutShort).Should(Equal(corev1.PodRunning))
                        g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
itName, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-                       g.Eventually(IntegrationCondition(t, ctx, ns, itName, 
v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(Equal("explicitly
 disabled by the platform: integration kit was not created via Camel K 
operator"))
+                       g.Eventually(IntegrationCondition(t, ctx, ns, itName, 
v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(ContainSubstring("explicitly
 disabled by the platform"))
                        g.Eventually(IntegrationLogs(t, ctx, ns, itName), 
TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"]))
                        g.Eventually(IntegrationLogs(t, ctx, ns, itName), 
TestTimeoutShort).Should(ContainSubstring("Apache Camel (Main)"))
                })
@@ -64,7 +64,7 @@ func TestSourceLessIntegrations(t *testing.T) {
                        g.Expect(KamelRunWithID(t, ctx, operatorID, ns, 
"--image", "docker.io/squakez/my-camel-sb:1.0.0", "--resource", 
"configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed())
                        g.Eventually(IntegrationPodPhase(t, ctx, ns, itName), 
TestTimeoutShort).Should(Equal(corev1.PodRunning))
                        g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
itName, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-                       g.Eventually(IntegrationCondition(t, ctx, ns, itName, 
v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(Equal("explicitly
 disabled by the platform: integration kit was not created via Camel K 
operator"))
+                       g.Eventually(IntegrationCondition(t, ctx, ns, itName, 
v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(ContainSubstring("explicitly
 disabled by the platform"))
                        g.Eventually(IntegrationLogs(t, ctx, ns, itName), 
TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"]))
                        g.Eventually(IntegrationLogs(t, ctx, ns, itName), 
TestTimeoutShort).Should(ContainSubstring("Spring Boot"))
                })
@@ -74,7 +74,7 @@ func TestSourceLessIntegrations(t *testing.T) {
                        g.Expect(KamelRunWithID(t, ctx, operatorID, ns, 
"--image", "docker.io/squakez/my-camel-quarkus:1.0.0", "--resource", 
"configmap:my-cm-sourceless@/tmp/app/data").Execute()).To(Succeed())
                        g.Eventually(IntegrationPodPhase(t, ctx, ns, itName), 
TestTimeoutShort).Should(Equal(corev1.PodRunning))
                        g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
itName, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
-                       g.Eventually(IntegrationCondition(t, ctx, ns, itName, 
v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(Equal("explicitly
 disabled by the platform: integration kit was not created via Camel K 
operator"))
+                       g.Eventually(IntegrationCondition(t, ctx, ns, itName, 
v1.IntegrationConditionType("JVMTraitInfo"))().Message).Should(ContainSubstring("explicitly
 disabled by the platform"))
                        g.Eventually(IntegrationLogs(t, ctx, ns, itName), 
TestTimeoutShort).Should(ContainSubstring(cmData["my-file.txt"]))
                        g.Eventually(IntegrationLogs(t, ctx, ns, itName), 
TestTimeoutShort).Should(ContainSubstring("powered by Quarkus"))
                })
diff --git a/e2e/common/traits/builder_test.go 
b/e2e/common/traits/builder_test.go
index b329f5c2d..db8d42a00 100644
--- a/e2e/common/traits/builder_test.go
+++ b/e2e/common/traits/builder_test.go
@@ -266,6 +266,19 @@ func TestBuilderTrait(t *testing.T) {
                        g.Expect(TestClient(t).Delete(ctx, 
mavenProfile1Cm)).To(Succeed())
                        g.Expect(TestClient(t).Delete(ctx, 
mavenProfile2Cm)).To(Succeed())
                })
+
+               t.Run("Run distroless container image", func(t *testing.T) {
+                       name := RandomizedSuffixName("java")
+                       g.Expect(KamelRunWithID(t, ctx, operatorID, ns, 
"files/Java.java", "--name", name, "-t", 
"builder.base-image=gcr.io/distroless/java17-debian12").Execute()).To(Succeed())
+
+                       g.Eventually(IntegrationPodPhase(t, ctx, ns, name), 
TestTimeoutLong).Should(Equal(corev1.PodRunning))
+                       g.Eventually(IntegrationConditionStatus(t, ctx, ns, 
name, v1.IntegrationConditionReady), 
TestTimeoutShort).Should(Equal(corev1.ConditionTrue))
+                       g.Eventually(IntegrationLogs(t, ctx, ns, name), 
TestTimeoutShort).Should(ContainSubstring("Magicstring!"))
+                       integrationKitName := IntegrationKit(t, ctx, ns, name)()
+                       g.Eventually(KitRootImage(t, ctx, ns, 
integrationKitName), 
TestTimeoutShort).Should(Equal("gcr.io/distroless/java17-debian12"))
+
+                       g.Expect(Kamel(t, ctx, "delete", "--all", "-n", 
ns).Execute()).To(Succeed())
+               })
        })
 }
 
diff --git a/e2e/support/test_support.go b/e2e/support/test_support.go
index 16a7d2046..4f7d950b0 100644
--- a/e2e/support/test_support.go
+++ b/e2e/support/test_support.go
@@ -1184,6 +1184,16 @@ func KitImage(t *testing.T, ctx context.Context, ns, 
name string) func() string
        }
 }
 
+func KitRootImage(t *testing.T, ctx context.Context, ns, name string) func() 
string {
+       return func() string {
+               kit := Kit(t, ctx, ns, name)()
+               if kit == nil {
+                       return ""
+               }
+               return kit.Status.RootImage
+       }
+}
+
 func KitCondition(t *testing.T, ctx context.Context, ns string, name string, 
conditionType v1.IntegrationKitConditionType) func() 
*v1.IntegrationKitCondition {
        return func() *v1.IntegrationKitCondition {
                kt := Kit(t, ctx, ns, name)()
diff --git a/helm/camel-k/crds/crd-integration-kit.yaml 
b/helm/camel-k/crds/crd-integration-kit.yaml
index 82f31750c..f21dfc47f 100644
--- a/helm/camel-k/crds/crd-integration-kit.yaml
+++ b/helm/camel-k/crds/crd-integration-kit.yaml
@@ -213,7 +213,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
diff --git a/helm/camel-k/crds/crd-integration-platform.yaml 
b/helm/camel-k/crds/crd-integration-platform.yaml
index ed67e6cd8..eeeec4364 100644
--- a/helm/camel-k/crds/crd-integration-platform.yaml
+++ b/helm/camel-k/crds/crd-integration-platform.yaml
@@ -528,7 +528,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -1285,14 +1287,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
@@ -2518,7 +2525,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -3275,14 +3284,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
diff --git a/helm/camel-k/crds/crd-integration-profile.yaml 
b/helm/camel-k/crds/crd-integration-profile.yaml
index 8374b1ed0..c827dbd52 100644
--- a/helm/camel-k/crds/crd-integration-profile.yaml
+++ b/helm/camel-k/crds/crd-integration-profile.yaml
@@ -405,7 +405,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -1162,14 +1164,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
@@ -2278,7 +2285,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -3035,14 +3044,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
diff --git a/helm/camel-k/crds/crd-integration.yaml 
b/helm/camel-k/crds/crd-integration.yaml
index 2be45505b..808ad117f 100644
--- a/helm/camel-k/crds/crd-integration.yaml
+++ b/helm/camel-k/crds/crd-integration.yaml
@@ -6466,7 +6466,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -7223,14 +7225,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
diff --git a/helm/camel-k/crds/crd-kamelet-binding.yaml 
b/helm/camel-k/crds/crd-kamelet-binding.yaml
index 9c5bb4500..40f60e223 100644
--- a/helm/camel-k/crds/crd-kamelet-binding.yaml
+++ b/helm/camel-k/crds/crd-kamelet-binding.yaml
@@ -6742,7 +6742,10 @@ spec:
                               use for the builder pod.
                             type: object
                           baseImage:
-                            description: Specify a base image
+                            description: Specify a base image. In order to 
have the
+                              application working properly it must be a 
container
+                              image which has a Java JDK installed and ready 
to use
+                              on path (ie `/usr/bin/java`).
                             type: string
                           configuration:
                             description: 'Legacy trait configuration 
parameters. Deprecated:
@@ -7507,14 +7510,19 @@ spec:
                             description: Can be used to enable or disable a 
trait.
                               All traits share this common property.
                             type: boolean
+                          jar:
+                            description: The Jar dependency which will run the 
application.
+                              Leave it empty for managed Integrations.
+                            type: string
                           options:
                             description: A list of JVM options
                             items:
                               type: string
                             type: array
                           printCommand:
-                            description: Prints the command used the start the 
JVM
-                              in the container logs (default `true`)
+                            description: 'Prints the command used the start 
the JVM
+                              in the container logs (default `true`) 
Deprecated: no
+                              longer in use.'
                             type: boolean
                         type: object
                       kamelets:
diff --git a/helm/camel-k/crds/crd-pipe.yaml b/helm/camel-k/crds/crd-pipe.yaml
index b0ffe4f17..e1d2f7fd2 100644
--- a/helm/camel-k/crds/crd-pipe.yaml
+++ b/helm/camel-k/crds/crd-pipe.yaml
@@ -6740,7 +6740,10 @@ spec:
                               use for the builder pod.
                             type: object
                           baseImage:
-                            description: Specify a base image
+                            description: Specify a base image. In order to 
have the
+                              application working properly it must be a 
container
+                              image which has a Java JDK installed and ready 
to use
+                              on path (ie `/usr/bin/java`).
                             type: string
                           configuration:
                             description: 'Legacy trait configuration 
parameters. Deprecated:
@@ -7505,14 +7508,19 @@ spec:
                             description: Can be used to enable or disable a 
trait.
                               All traits share this common property.
                             type: boolean
+                          jar:
+                            description: The Jar dependency which will run the 
application.
+                              Leave it empty for managed Integrations.
+                            type: string
                           options:
                             description: A list of JVM options
                             items:
                               type: string
                             type: array
                           printCommand:
-                            description: Prints the command used the start the 
JVM
-                              in the container logs (default `true`)
+                            description: 'Prints the command used the start 
the JVM
+                              in the container logs (default `true`) 
Deprecated: no
+                              longer in use.'
                             type: boolean
                         type: object
                       kamelets:
diff --git a/pkg/apis/camel/v1/trait/builder.go 
b/pkg/apis/camel/v1/trait/builder.go
index 0eab4cf8c..12054f95d 100644
--- a/pkg/apis/camel/v1/trait/builder.go
+++ b/pkg/apis/camel/v1/trait/builder.go
@@ -31,7 +31,8 @@ type BuilderTrait struct {
        // The strategy to use, either `pod` or `routine` (default `routine`)
        // +kubebuilder:validation:Enum=pod;routine
        Strategy string `property:"strategy" json:"strategy,omitempty"`
-       // Specify a base image
+       // Specify a base image. In order to have the application working 
properly it must be a container image which has a Java JDK
+       // installed and ready to use on path (ie `/usr/bin/java`).
        BaseImage string `property:"base-image" json:"baseImage,omitempty"`
        // Use the incremental image build option, to reuse existing containers 
(default `true`)
        IncrementalImageBuild *bool `property:"incremental-image-build" 
json:"incrementalImageBuild,omitempty"`
diff --git a/pkg/apis/camel/v1/trait/jvm.go b/pkg/apis/camel/v1/trait/jvm.go
index abe1e1185..4cc5b8c1a 100644
--- a/pkg/apis/camel/v1/trait/jvm.go
+++ b/pkg/apis/camel/v1/trait/jvm.go
@@ -29,6 +29,7 @@ type JVMTrait struct {
        // Suspends the target JVM immediately before the main class is loaded
        DebugSuspend *bool `property:"debug-suspend" 
json:"debugSuspend,omitempty"`
        // Prints the command used the start the JVM in the container logs 
(default `true`)
+       // Deprecated: no longer in use.
        PrintCommand *bool `property:"print-command" 
json:"printCommand,omitempty"`
        // Transport address at which to listen for the newly launched JVM 
(default `*:5005`)
        DebugAddress string `property:"debug-address" 
json:"debugAddress,omitempty"`
@@ -36,4 +37,6 @@ type JVMTrait struct {
        Options []string `property:"options" json:"options,omitempty"`
        // Additional JVM classpath (use `Linux` classpath separator)
        Classpath string `property:"classpath" json:"classpath,omitempty"`
+       // The Jar dependency which will run the application. Leave it empty 
for managed Integrations.
+       Jar string `property:"jar" json:"jar,omitempty"`
 }
diff --git a/pkg/cmd/run_test.go b/pkg/cmd/run_test.go
index 625a850d4..8ba5399b8 100644
--- a/pkg/cmd/run_test.go
+++ b/pkg/cmd/run_test.go
@@ -437,7 +437,6 @@ func TestConfigureTraits(t *testing.T) {
        _, err := test.ExecuteCommand(rootCmd, "run",
                "--trait", "affinity.pod-affinity=false",
                "--trait", "environment.container-meta=false",
-               "--trait", "jvm.print-command=false",
                "--trait", "prometheus.pod-monitor=false",
                "example.js")
        if err != nil {
@@ -455,10 +454,9 @@ func TestConfigureTraits(t *testing.T) {
        require.NoError(t, err)
        traitMap, err := trait.ToTraitMap(traits)
        require.NoError(t, err)
-       assert.Len(t, traitMap, 4)
+       assert.Len(t, traitMap, 3)
        assertTraitConfiguration(t, traits.Affinity, 
&traitv1.AffinityTrait{PodAffinity: pointer.Bool(false)})
        assertTraitConfiguration(t, traits.Environment, 
&traitv1.EnvironmentTrait{ContainerMeta: pointer.Bool(false)})
-       assertTraitConfiguration(t, traits.JVM, &traitv1.JVMTrait{PrintCommand: 
pointer.Bool(false)})
        assertTraitConfiguration(t, traits.Prometheus, 
&traitv1.PrometheusTrait{PodMonitor: pointer.Bool(false)})
 }
 
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml
index 82f31750c..f21dfc47f 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationkits.yaml
@@ -213,7 +213,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
index ed67e6cd8..eeeec4364 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationplatforms.yaml
@@ -528,7 +528,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -1285,14 +1287,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
@@ -2518,7 +2525,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -3275,14 +3284,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
index 8374b1ed0..c827dbd52 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrationprofiles.yaml
@@ -405,7 +405,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -1162,14 +1164,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
@@ -2278,7 +2285,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -3035,14 +3044,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
diff --git a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
index 2be45505b..808ad117f 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_integrations.yaml
@@ -6466,7 +6466,9 @@ spec:
                           for the builder pod.
                         type: object
                       baseImage:
-                        description: Specify a base image
+                        description: Specify a base image. In order to have 
the application
+                          working properly it must be a container image which 
has
+                          a Java JDK installed and ready to use on path (ie 
`/usr/bin/java`).
                         type: string
                       configuration:
                         description: 'Legacy trait configuration parameters. 
Deprecated:
@@ -7223,14 +7225,19 @@ spec:
                         description: Can be used to enable or disable a trait. 
All
                           traits share this common property.
                         type: boolean
+                      jar:
+                        description: The Jar dependency which will run the 
application.
+                          Leave it empty for managed Integrations.
+                        type: string
                       options:
                         description: A list of JVM options
                         items:
                           type: string
                         type: array
                       printCommand:
-                        description: Prints the command used the start the JVM 
in
-                          the container logs (default `true`)
+                        description: 'Prints the command used the start the 
JVM in
+                          the container logs (default `true`) Deprecated: no 
longer
+                          in use.'
                         type: boolean
                     type: object
                   kamelets:
diff --git 
a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml
index 9c5bb4500..40f60e223 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_kameletbindings.yaml
@@ -6742,7 +6742,10 @@ spec:
                               use for the builder pod.
                             type: object
                           baseImage:
-                            description: Specify a base image
+                            description: Specify a base image. In order to 
have the
+                              application working properly it must be a 
container
+                              image which has a Java JDK installed and ready 
to use
+                              on path (ie `/usr/bin/java`).
                             type: string
                           configuration:
                             description: 'Legacy trait configuration 
parameters. Deprecated:
@@ -7507,14 +7510,19 @@ spec:
                             description: Can be used to enable or disable a 
trait.
                               All traits share this common property.
                             type: boolean
+                          jar:
+                            description: The Jar dependency which will run the 
application.
+                              Leave it empty for managed Integrations.
+                            type: string
                           options:
                             description: A list of JVM options
                             items:
                               type: string
                             type: array
                           printCommand:
-                            description: Prints the command used the start the 
JVM
-                              in the container logs (default `true`)
+                            description: 'Prints the command used the start 
the JVM
+                              in the container logs (default `true`) 
Deprecated: no
+                              longer in use.'
                             type: boolean
                         type: object
                       kamelets:
diff --git a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml 
b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
index b0ffe4f17..e1d2f7fd2 100644
--- a/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
+++ b/pkg/resources/config/crd/bases/camel.apache.org_pipes.yaml
@@ -6740,7 +6740,10 @@ spec:
                               use for the builder pod.
                             type: object
                           baseImage:
-                            description: Specify a base image
+                            description: Specify a base image. In order to 
have the
+                              application working properly it must be a 
container
+                              image which has a Java JDK installed and ready 
to use
+                              on path (ie `/usr/bin/java`).
                             type: string
                           configuration:
                             description: 'Legacy trait configuration 
parameters. Deprecated:
@@ -7505,14 +7508,19 @@ spec:
                             description: Can be used to enable or disable a 
trait.
                               All traits share this common property.
                             type: boolean
+                          jar:
+                            description: The Jar dependency which will run the 
application.
+                              Leave it empty for managed Integrations.
+                            type: string
                           options:
                             description: A list of JVM options
                             items:
                               type: string
                             type: array
                           printCommand:
-                            description: Prints the command used the start the 
JVM
-                              in the container logs (default `true`)
+                            description: 'Prints the command used the start 
the JVM
+                              in the container logs (default `true`) 
Deprecated: no
+                              longer in use.'
                             type: boolean
                         type: object
                       kamelets:
diff --git a/pkg/trait/jvm.go b/pkg/trait/jvm.go
index bef632904..87f3da133 100644
--- a/pkg/trait/jvm.go
+++ b/pkg/trait/jvm.go
@@ -24,8 +24,6 @@ import (
        "sort"
        "strings"
 
-       "github.com/apache/camel-k/v2/pkg/util/boolean"
-
        corev1 "k8s.io/api/core/v1"
        "k8s.io/apimachinery/pkg/api/resource"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -62,14 +60,15 @@ func newJvmTrait() Trait {
                BaseTrait: NewBaseTrait(jvmTraitID, jvmTraitOrder),
                JVMTrait: traitv1.JVMTrait{
                        DebugAddress: "*:5005",
-                       PrintCommand: pointer.Bool(true),
                },
        }
 }
 
 func (t *jvmTrait) Configure(e *Environment) (bool, *TraitCondition, error) {
+       // Deprecated: the JVM has to be a platform trait and the user should 
not be able to disable it
        if !pointer.BoolDeref(t.Enabled, true) {
-               return false, NewIntegrationConditionUserDisabled("JVM"), nil
+               notice := userDisabledMessage + "; this configuration is 
deprecated and may be removed within next releases"
+               return false, NewIntegrationCondition("JVM", 
v1.IntegrationConditionTraitInfo, corev1.ConditionTrue, 
traitConfigurationReason, notice), nil
        }
        if !e.IntegrationKitInPhase(v1.IntegrationKitPhaseReady) || 
!e.IntegrationInRunningPhases() {
                return false, nil, nil
@@ -82,19 +81,18 @@ func (t *jvmTrait) Configure(e *Environment) (bool, 
*TraitCondition, error) {
                }
        }
 
-       if e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic() {
-               return false, 
NewIntegrationConditionPlatformDisabledWithMessage("JVM", "integration kit was 
not created via Camel K operator"), nil
+       if e.IntegrationKit != nil && e.IntegrationKit.IsSynthetic() && t.Jar 
== "" {
+               // We skip this trait since we cannot make any assumption on 
the container Java tooling running
+               // for the synthetic IntegrationKit
+               return false, 
NewIntegrationConditionPlatformDisabledWithMessage(
+                       "JVM",
+                       "integration kit was not created via Camel K operator 
and the user did not provide the jar to execute",
+               ), nil
        }
 
-       if e.CamelCatalog == nil {
-               return false, 
NewIntegrationConditionPlatformDisabledCatalogMissing(), nil
-       }
        return true, nil, nil
 }
 
-// TODO: refactor the code
-//
-//nolint:maintidx
 func (t *jvmTrait) Apply(e *Environment) error {
        kit := e.IntegrationKit
 
@@ -115,75 +113,120 @@ func (t *jvmTrait) Apply(e *Environment) error {
                return fmt.Errorf("unable to find integration kit for 
integration %s", e.Integration.Name)
        }
 
-       classpath := sets.NewSet()
-
-       classpath.Add("./resources")
-       classpath.Add(filepath.ToSlash(camel.ConfigResourcesMountPath))
-       classpath.Add(filepath.ToSlash(camel.ResourcesDefaultMountPath))
-       if t.Classpath != "" {
-               classpath.Add(strings.Split(t.Classpath, ":")...)
-       }
-
-       for _, artifact := range kit.Status.Artifacts {
-               classpath.Add(artifact.Target)
-       }
-
-       if kit.IsExternal() {
-               // In case of an external created kit, we do not have any 
information about
-               // the classpath, so we assume the all jars in 
/deployments/dependencies/ have
-               // to be taken into account.
-               dependencies := filepath.Join(builder.DeploymentDir, 
builder.DependenciesDir)
-               classpath.Add(
-                       dependencies+"/*",
-                       dependencies+"/app/*",
-                       dependencies+"/lib/boot/*",
-                       dependencies+"/lib/main/*",
-                       dependencies+"/quarkus/*",
-               )
-       }
-
        container := e.GetIntegrationContainer()
        if container == nil {
-               return fmt.Errorf("unable to find integration container: %s", 
e.Integration.Name)
+               return fmt.Errorf("unable to find a container for %s 
Integration", e.Integration.Name)
        }
 
        // Build the container command
        // Other traits may have already contributed some arguments
        args := container.Args
 
-       // Remote debugging
        if pointer.BoolDeref(t.Debug, false) {
-               suspend := "n"
-               if pointer.BoolDeref(t.DebugSuspend, false) {
-                       suspend = "y"
-               }
-               args = append(args,
-                       
fmt.Sprintf("-agentlib:jdwp=transport=dt_socket,server=y,suspend=%s,address=%s",
-                               suspend, t.DebugAddress))
-
-               // Add label to mark the pods with debug enabled
-               e.Resources.VisitPodTemplateMeta(func(meta *metav1.ObjectMeta) {
-                       if meta.Labels == nil {
-                               meta.Labels = make(map[string]string)
-                       }
-                       meta.Labels["camel.apache.org/debug"] = 
boolean.TrueString
-               })
+               debugArgs := t.enableDebug(e)
+               args = append(args, debugArgs)
        }
 
        hasHeapSizeOption := false
        // Add JVM options
        if len(t.Options) > 0 {
                hasHeapSizeOption = util.StringSliceContainsAnyOf(t.Options, 
"-Xmx", "-XX:MaxHeapSize", "-XX:MinRAMPercentage", "-XX:MaxRAMPercentage")
-
                args = append(args, t.Options...)
        }
 
-       // Translate HTTP proxy environment variables, that are set by the 
environment trait,
-       // into corresponding JVM system properties.
+       // Tune JVM maximum heap size based on the container memory limit, if 
any.
+       // This is configured off-container, thus is limited to explicit user 
configuration.
+       // We may want to inject a wrapper script into the container image, so 
that it can
+       // be performed in-container, based on CGroups memory resource control 
files.
+       if memory, hasLimit := 
container.Resources.Limits[corev1.ResourceMemory]; !hasHeapSizeOption && 
hasLimit {
+               // Simple heuristic that caps the maximum heap size to 50% of 
the memory limit
+               percentage := defaultMaxMemoryPercentage
+               // Unless the memory limit is lower than 300M, in which case we 
leave more room for the non-heap memory
+               if resource.NewScaledQuantity(lowMemoryThreshold, 
defaultMaxMemoryScale).Cmp(memory) > 0 {
+                       percentage = lowMemoryMAxMemoryDefaultPercentage
+               }
+               //nolint:mnd
+               memScaled := memory.ScaledValue(resource.Mega) * percentage / 
100
+               args = append(args, fmt.Sprintf("-Xmx%dM", memScaled))
+       }
+
+       httpProxyArgs, err := t.prepareHTTPProxy(container)
+       if err != nil {
+               return err
+       }
+       if httpProxyArgs != nil {
+               args = append(args, httpProxyArgs...)
+       }
+
+       // If user provided the jar, we will execute on the container something 
like
+       // java -Dxyx ... -cp ... -jar my-app.jar
+       // For this reason it's imporant that the container is a java based 
container able to run a Camel (hence Java) application
+       container.WorkingDir = builder.DeploymentDir
+       container.Command = []string{"java"}
+       classpathItems := t.prepareClasspathItems(container)
+       if t.Jar != "" {
+               // User is providing the Jar to execute explicitly
+               args = append(args, "-cp", strings.Join(classpathItems, ":"))
+               args = append(args, "-jar", t.Jar)
+       } else {
+               if e.CamelCatalog == nil {
+                       return fmt.Errorf("cannot execute trait: missing Camel 
catalog")
+               }
+               kitDepsDirs := getKitDependenciesDirectories(kit)
+               classpathItems = append(classpathItems, kitDepsDirs...)
+               args = append(args, "-cp", strings.Join(classpathItems, ":"))
+               args = append(args, e.CamelCatalog.Runtime.ApplicationClass)
+       }
+       container.Args = args
+
+       return nil
+}
+
+func (t *jvmTrait) enableDebug(e *Environment) string {
+       suspend := "n"
+       if pointer.BoolDeref(t.DebugSuspend, false) {
+               suspend = "y"
+       }
+       // Add label to mark the pods with debug enabled
+       e.Resources.VisitPodTemplateMeta(func(meta *metav1.ObjectMeta) {
+               if meta.Labels == nil {
+                       meta.Labels = make(map[string]string)
+               }
+               meta.Labels["camel.apache.org/debug"] = "true"
+       })
+
+       return 
fmt.Sprintf("-agentlib:jdwp=transport=dt_socket,server=y,suspend=%s,address=%s",
+               suspend, t.DebugAddress)
+}
+
+func (t *jvmTrait) prepareClasspathItems(container *corev1.Container) []string 
{
+       classpath := sets.NewSet()
+       classpath.Add("./resources")
+       classpath.Add(filepath.ToSlash(camel.ConfigResourcesMountPath))
+       classpath.Add(filepath.ToSlash(camel.ResourcesDefaultMountPath))
+       if t.Classpath != "" {
+               classpath.Add(strings.Split(t.Classpath, ":")...)
+       }
+       // Add mounted resources to the class path
+       for _, m := range container.VolumeMounts {
+               classpath.Add(m.MountPath)
+       }
+       items := classpath.List()
+       // Keep class path sorted so that it's consistent over reconciliation 
cycles
+       sort.Strings(items)
+
+       return items
+}
+
+// Translate HTTP proxy environment variables, that are set by the environment 
trait,
+// into corresponding JVM system properties.
+func (t *jvmTrait) prepareHTTPProxy(container *corev1.Container) ([]string, 
error) {
+       var args []string
+
        if HTTPProxy := envvar.Get(container.Env, "HTTP_PROXY"); HTTPProxy != 
nil {
                u, err := url.Parse(HTTPProxy.Value)
                if err != nil {
-                       return err
+                       return args, err
                }
                if !util.StringSliceContainsAnyOf(t.Options, "http.proxyHost") {
                        args = append(args, fmt.Sprintf("-Dhttp.proxyHost=%q", 
u.Hostname()))
@@ -202,7 +245,7 @@ func (t *jvmTrait) Apply(e *Environment) error {
        if HTTPSProxy := envvar.Get(container.Env, "HTTPS_PROXY"); HTTPSProxy 
!= nil {
                u, err := url.Parse(HTTPSProxy.Value)
                if err != nil {
-                       return err
+                       return args, err
                }
                if !util.StringSliceContainsAnyOf(t.Options, "https.proxyHost") 
{
                        args = append(args, fmt.Sprintf("-Dhttps.proxyHost=%q", 
u.Hostname()))
@@ -231,44 +274,18 @@ func (t *jvmTrait) Apply(e *Environment) error {
                }
        }
 
-       // Tune JVM maximum heap size based on the container memory limit, if 
any.
-       // This is configured off-container, thus is limited to explicit user 
configuration.
-       // We may want to inject a wrapper script into the container image, so 
that it can
-       // be performed in-container, based on CGroups memory resource control 
files.
-       if memory, hasLimit := 
container.Resources.Limits[corev1.ResourceMemory]; !hasHeapSizeOption && 
hasLimit {
-               // Simple heuristic that caps the maximum heap size to 50% of 
the memory limit
-               percentage := defaultMaxMemoryPercentage
-               // Unless the memory limit is lower than 300M, in which case we 
leave more room for the non-heap memory
-               if resource.NewScaledQuantity(lowMemoryThreshold, 
defaultMaxMemoryScale).Cmp(memory) > 0 {
-                       percentage = lowMemoryMAxMemoryDefaultPercentage
-               }
-               //nolint:mnd
-               memScaled := memory.ScaledValue(resource.Mega) * percentage / 
100
-               args = append(args, fmt.Sprintf("-Xmx%dM", memScaled))
-       }
-
-       // Add mounted resources to the class path
-       for _, m := range container.VolumeMounts {
-               classpath.Add(m.MountPath)
-       }
-       items := classpath.List()
-       // Keep class path sorted so that it's consistent over reconciliation 
cycles
-       sort.Strings(items)
-       args = append(args, "-cp", strings.Join(items, ":"))
-
-       args = append(args, e.CamelCatalog.Runtime.ApplicationClass)
+       return args, nil
+}
 
-       if pointer.BoolDeref(t.PrintCommand, false) {
-               args = append([]string{"exec", "java"}, args...)
-               container.Command = []string{"/bin/sh", "-c"}
-               cmd := strings.Join(args, " ")
-               container.Args = []string{"echo " + cmd + " && " + cmd}
-       } else {
-               container.Command = []string{"java"}
-               container.Args = args
+// getKitDependenciesDirectories returns the list of directories, scanning the 
dependencies list.
+func getKitDependenciesDirectories(kit *v1.IntegrationKit) []string {
+       s := sets.NewSet()
+       for _, dep := range kit.Status.Artifacts {
+               path := filepath.Dir(dep.Target)
+               s.Add(fmt.Sprintf("%s/*", path))
        }
+       values := s.List()
+       sort.Strings(values)
 
-       container.WorkingDir = builder.DeploymentDir
-
-       return nil
+       return values
 }
diff --git a/pkg/trait/jvm_test.go b/pkg/trait/jvm_test.go
index 3e3906d13..6f04f549e 100644
--- a/pkg/trait/jvm_test.go
+++ b/pkg/trait/jvm_test.go
@@ -20,26 +20,20 @@ package trait
 import (
        "fmt"
        "path/filepath"
-       "sort"
        "strings"
        "testing"
 
+       v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
+       "github.com/apache/camel-k/v2/pkg/util/camel"
+       "github.com/apache/camel-k/v2/pkg/util/kubernetes"
+       "github.com/apache/camel-k/v2/pkg/util/test"
        "github.com/stretchr/testify/assert"
        "github.com/stretchr/testify/require"
-
        appsv1 "k8s.io/api/apps/v1"
        corev1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/utils/pointer"
-
        serving "knative.dev/serving/pkg/apis/serving/v1"
-
-       v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1"
-       "github.com/apache/camel-k/v2/pkg/builder"
-       "github.com/apache/camel-k/v2/pkg/util/camel"
-       "github.com/apache/camel-k/v2/pkg/util/kubernetes"
-       "github.com/apache/camel-k/v2/pkg/util/sets"
-       "github.com/apache/camel-k/v2/pkg/util/test"
 )
 
 var (
@@ -85,7 +79,7 @@ func TestConfigureJvmTraitInWrongJvmDisabled(t *testing.T) {
                v1.IntegrationConditionTraitInfo,
                corev1.ConditionTrue,
                "TraitConfiguration",
-               "explicitly disabled by the user",
+               "explicitly disabled by the user; this configuration is 
deprecated and may be removed within next releases",
        )
        configured, condition, err := trait.Configure(environment)
        require.NoError(t, err)
@@ -94,6 +88,169 @@ func TestConfigureJvmTraitInWrongJvmDisabled(t *testing.T) {
        assert.Equal(t, expectedCondition, condition)
 }
 
+func TestConfigureJvmTraitExecutableSourcelessContainer(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       environment.IntegrationKit.Labels[v1.IntegrationKitTypeLabel] = 
v1.IntegrationKitTypeSynthetic
+
+       configured, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.False(t, configured)
+       assert.Equal(t,
+               "explicitly disabled by the platform: integration kit was not 
created via Camel K operator and the user did not provide the jar to execute",
+               condition.message,
+       )
+}
+
+func TestConfigureJvmTraitExecutableSourcelessContainerWithJar(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       environment.IntegrationKit.Labels[v1.IntegrationKitTypeLabel] = 
v1.IntegrationKitTypeSynthetic
+       trait.Jar = "my-path/to/my-app.jar"
+
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       environment.Resources.Add(&d)
+       configured, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configured)
+       assert.Nil(t, condition)
+
+       err = trait.Apply(environment)
+
+       require.NoError(t, err)
+       assert.Equal(t, []string{
+               "-cp",
+               fmt.Sprintf("./resources:%s:%s", crMountPath, rdMountPath),
+               "-jar", "my-path/to/my-app.jar",
+       }, d.Spec.Template.Spec.Containers[0].Args)
+}
+
+func TestConfigureJvmTraitExecutableSourcelessContainerWithJarAndOptions(t 
*testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       environment.IntegrationKit.Labels[v1.IntegrationKitTypeLabel] = 
v1.IntegrationKitTypeSynthetic
+       trait.Jar = "my-path/to/my-app.jar"
+       // Add some additional JVM configurations
+       trait.Classpath = "deps/a.jar:deps/b.jar"
+       trait.Options = []string{
+               "-Xmx1234M",
+               "-Dmy-prop=abc",
+       }
+
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       environment.Resources.Add(&d)
+       configured, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configured)
+       assert.Nil(t, condition)
+
+       err = trait.Apply(environment)
+
+       require.NoError(t, err)
+       assert.Equal(t, []string{
+               "-Xmx1234M", "-Dmy-prop=abc",
+               "-cp", 
"./resources:/etc/camel/conf.d/_resources:/etc/camel/resources:deps/a.jar:deps/b.jar",
+               "-jar", "my-path/to/my-app.jar",
+       }, d.Spec.Template.Spec.Containers[0].Args)
+}
+
+func TestConfigureJvmTraitWithJar(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       trait.Jar = "my-path/to/my-app.jar"
+
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       environment.Resources.Add(&d)
+       configured, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configured)
+       assert.Nil(t, condition)
+
+       err = trait.Apply(environment)
+
+       require.NoError(t, err)
+       assert.Equal(t, []string{
+               "-cp",
+               fmt.Sprintf("./resources:%s:%s", crMountPath, rdMountPath),
+               "-jar", "my-path/to/my-app.jar",
+       }, d.Spec.Template.Spec.Containers[0].Args)
+}
+
+func TestConfigureJvmTraitWithJarAndConfigs(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       trait.Jar = "my-path/to/my-app.jar"
+       // Add some additional JVM configurations
+       trait.Classpath = "deps/a.jar:deps/b.jar"
+       trait.Options = []string{
+               "-Xmx1234M",
+               "-Dmy-prop=abc",
+       }
+
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+       environment.Resources.Add(&d)
+       configured, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configured)
+       assert.Nil(t, condition)
+
+       err = trait.Apply(environment)
+
+       require.NoError(t, err)
+       assert.Equal(t, []string{
+               "-Xmx1234M", "-Dmy-prop=abc",
+               "-cp", 
"./resources:/etc/camel/conf.d/_resources:/etc/camel/resources:deps/a.jar:deps/b.jar",
+               "-jar", "my-path/to/my-app.jar",
+       }, d.Spec.Template.Spec.Containers[0].Args)
+}
+
 func TestConfigureJvmTraitInWrongIntegrationKitPhaseExternal(t *testing.T) {
        trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypeSynthetic)
 
@@ -102,7 +259,7 @@ func 
TestConfigureJvmTraitInWrongIntegrationKitPhaseExternal(t *testing.T) {
                v1.IntegrationConditionTraitInfo,
                corev1.ConditionTrue,
                "TraitConfiguration",
-               "explicitly disabled by the platform: integration kit was not 
created via Camel K operator",
+               "explicitly disabled by the platform: integration kit was not 
created via Camel K operator and the user did not provide the jar to execute",
        )
        configured, condition, err := trait.Configure(environment)
        require.NoError(t, err)
@@ -134,16 +291,13 @@ func TestApplyJvmTraitWithDeploymentResource(t 
*testing.T) {
        }
 
        environment.Resources.Add(&d)
-
-       err := trait.Apply(environment)
-
+       configure, condition, err := trait.Configure(environment)
        require.NoError(t, err)
+       assert.True(t, configure)
+       assert.Nil(t, condition)
+       err = trait.Apply(environment)
 
-       s := sets.NewSet()
-       s.Add("./resources", crMountPath, rdMountPath, "/mount/path")
-       cp := s.List()
-       sort.Strings(cp)
-
+       require.NoError(t, err)
        assert.Equal(t, []string{
                "-cp",
                fmt.Sprintf("./resources:%s:%s:/mount/path", crMountPath, 
rdMountPath),
@@ -168,16 +322,13 @@ func TestApplyJvmTraitWithKNativeResource(t *testing.T) {
        }
 
        environment.Resources.Add(&s)
-
-       err := trait.Apply(environment)
-
+       configure, condition, err := trait.Configure(environment)
        require.NoError(t, err)
+       assert.True(t, configure)
+       assert.Nil(t, condition)
+       err = trait.Apply(environment)
 
-       st := sets.NewSet()
-       st.Add("./resources", crMountPath, rdMountPath, "/mount/path")
-       cp := st.List()
-       sort.Strings(cp)
-
+       require.NoError(t, err)
        assert.Equal(t, []string{
                "-cp",
                fmt.Sprintf("./resources:%s:%s:/mount/path", crMountPath, 
rdMountPath),
@@ -210,11 +361,9 @@ func TestApplyJvmTraitWithDebugEnabled(t *testing.T) {
        }
 
        environment.Resources.Add(&d)
-
        err := trait.Apply(environment)
 
        require.NoError(t, err)
-
        assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args,
                
"-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:5005",
        )
@@ -239,22 +388,19 @@ func TestApplyJvmTraitWithExternalKitType(t *testing.T) {
 
        environment.Resources.Add(&d)
 
-       err := trait.Apply(environment)
+       environment.Resources.Add(&d)
+       configure, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configure)
+       assert.Nil(t, condition)
+       err = trait.Apply(environment)
        require.NoError(t, err)
 
-       container := environment.GetIntegrationContainer()
-
-       assert.Equal(t, 3, len(container.Args))
-       assert.Equal(t, "-cp", container.Args[0])
-
-       // classpath JAR location segments must be wildcarded for an external 
kit
-       for _, cp := range strings.Split(container.Args[1], ":") {
-               if strings.HasPrefix(cp, builder.DeploymentDir) {
-                       assert.True(t, strings.HasSuffix(cp, "/*"))
-               }
-       }
-
-       assert.Equal(t, "io.quarkus.bootstrap.runner.QuarkusEntryPoint", 
container.Args[2])
+       assert.Equal(t, []string{
+               "-cp",
+               fmt.Sprintf("./resources:%s:%s", crMountPath, rdMountPath),
+               "io.quarkus.bootstrap.runner.QuarkusEntryPoint",
+       }, d.Spec.Template.Spec.Containers[0].Args)
 }
 
 func TestApplyJvmTraitWithClasspath(t *testing.T) {
@@ -278,17 +424,109 @@ func TestApplyJvmTraitWithClasspath(t *testing.T) {
                        },
                },
        }
+
        environment.Resources.Add(&d)
-       err := trait.Apply(environment)
+       configure, condition, err := trait.Configure(environment)
+       require.NoError(t, err)
+       assert.True(t, configure)
+       assert.Nil(t, condition)
+       err = trait.Apply(environment)
 
        require.NoError(t, err)
        assert.Equal(t, []string{
                "-cp",
-               fmt.Sprintf("./resources:%s:%s:/mount/path:%s:%s", crMountPath, 
rdMountPath,
-                       "/path/to/another/dep.jar", "/path/to/my-dep.jar"),
+               fmt.Sprintf("./resources:%s:%s:/mount/path:%s:%s", crMountPath, 
rdMountPath, "/path/to/another/dep.jar", "/path/to/my-dep.jar"),
                "io.quarkus.bootstrap.runner.QuarkusEntryPoint",
        }, d.Spec.Template.Spec.Containers[0].Args)
 }
+func TestApplyJvmTraitKitMissing(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       environment.IntegrationKit = nil
+
+       err := trait.Apply(environment)
+
+       require.Error(t, err)
+       assert.True(t, strings.HasPrefix(err.Error(), "unable to find 
integration kit"))
+}
+
+func TestApplyJvmTraitContainerResourceArgs(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       memoryLimit := make(corev1.ResourceList)
+       memoryLimit, err := kubernetes.ConfigureResource("4Gi", memoryLimit, 
corev1.ResourceMemory)
+       require.NoError(t, err)
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                                       Resources: 
corev1.ResourceRequirements{
+                                                               Limits: 
memoryLimit,
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+       environment.Resources.Add(&d)
+       err = trait.Apply(environment)
+
+       require.NoError(t, err)
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, "-Xmx2147M")
+
+       // User specified Xmx option
+       trait.Options = []string{"-Xmx1111M"}
+       err = trait.Apply(environment)
+
+       require.NoError(t, err)
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, "-Xmx1111M")
+}
+
+func TestApplyJvmTraitHttpProxyArgs(t *testing.T) {
+       trait, environment := 
createNominalJvmTest(v1.IntegrationKitTypePlatform)
+       d := appsv1.Deployment{
+               Spec: appsv1.DeploymentSpec{
+                       Template: corev1.PodTemplateSpec{
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name: 
defaultContainerName,
+                                                       Env: []corev1.EnvVar{
+                                                               {
+                                                                       Name:  
"HTTP_PROXY",
+                                                                       Value: 
"http://my-user:my-password@my-proxy:1234";,
+                                                               },
+                                                               {
+                                                                       Name:  
"HTTPS_PROXY",
+                                                                       Value: 
"https://my-secure-user:my-secure-password@my-secure-proxy:6789";,
+                                                               },
+                                                               {
+                                                                       Name:  
"NO_PROXY",
+                                                                       Value: 
"https://my-non-proxied-host,1.2.3.4";,
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+       environment.Resources.Add(&d)
+       err := trait.Apply(environment)
+
+       require.NoError(t, err)
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttp.proxyHost=\"my-proxy\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttp.proxyPort=\"1234\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttp.proxyUser=\"my-user\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttp.proxyPassword=\"my-password\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttps.proxyHost=\"my-secure-proxy\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttps.proxyPort=\"6789\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttps.proxyUser=\"my-secure-user\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttps.proxyPassword=\"my-secure-password\"")
+       assert.Contains(t, d.Spec.Template.Spec.Containers[0].Args, 
"-Dhttp.nonProxyHosts=\"https://my-non-proxied-host|1.2.3.4\"")
+}
 
 func createNominalJvmTest(kitType string) (*jvmTrait, *Environment) {
        catalog, _ := camel.DefaultCatalog()
@@ -326,3 +564,26 @@ func createNominalJvmTest(kitType string) (*jvmTrait, 
*Environment) {
 
        return trait, environment
 }
+
+func TestGetKitDependenciesDirectories(t *testing.T) {
+       kit := &v1.IntegrationKit{
+               Status: v1.IntegrationKitStatus{
+                       Artifacts: []v1.Artifact{
+                               {Target: "my-dir1/lib/mytest.jar"},
+                               {Target: "my-dir1/lib/mytest2.jar"},
+                               {Target: "my-dir1/lib/mytest3.jar"},
+                               {Target: "my-dir2/lib/mytest4.jar"},
+                               {Target: "my-dir1/lib2/mytest5.jar"},
+                               {Target: "my-dir/mytest6.jar"},
+                               {Target: "my-dir/mytest7.jar"},
+                       },
+                       Phase: v1.IntegrationKitPhaseReady,
+               },
+       }
+       paths := getKitDependenciesDirectories(kit)
+       assert.Len(t, paths, 4)
+       assert.Equal(t, "my-dir/*", paths[0])
+       assert.Equal(t, "my-dir1/lib/*", paths[1])
+       assert.Equal(t, "my-dir1/lib2/*", paths[2])
+       assert.Equal(t, "my-dir2/lib/*", paths[3])
+}

Reply via email to