Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 1fv4

Quarkus – Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster

In my previous article, I shared with you the steps I took, to further automate setting up my demo environment, and implementing a Service with service type LoadBalancer.
[Quarkus – Kubernetes extension (reinvestigated, part 5), implementing a Service of service type LoadBalancer with K3s]

Some years ago, I also wrote articles about the Quarkus Kubernetes Extension.

This time I wanted to have a look at some others aspects of the Quarkus Kubernetes Extension, that I came across.

Part of the “Developer Joy” is the so called “Remote Development”.
Run dev mode remotely with changes to local files immediately available in a containerize environment.
Read the Remote Development Mode guide
[https://quarkus.io/developer-joy/]

But first I wanted to have a look at remote debugging.

To remotely debug applications that are running on a Kubernetes environment, we need to deploy the application in a particular way.
[https://quarkus.io/guides/deploying-to-kubernetes#remote-debugging]

In this article, you can read more about the steps I took to remotely debug a Java application that is running in a container on a Kubernetes cluster in my already existing Linux demo environment, including Quarkus and K3s (a lightweight certified Kubernetes distribution) and setup via Vagrant.

In a next article, you can read more about using development mode remotely, so that you can run Quarkus in a container environment and have changes made to your local files become immediately visible.

Remote JVM debugging a Java application directly on my Windows laptop

In order to learn more about the remote JVM debugging part, I had a look at: IntelliJ IDEA tutorial: Remote debug

Below you see the overview of this tutorial (that uses a class named Alphabet):

Remote debugging lets you control and inspect a Java program running on another machine as if it were local.

To do this, you first start the application on the remote computer and configure it to accept debugger connections by adding a special VM option. This option makes the remote JVM wait for incoming connections from a debugger.

Once the remote app is up and listening, you use your local machine to start a debugger in “attach” mode. This connects the IntelliJ IDEA’s debugger to the remote application over the network, allowing you to debug it.

For simplicity, we will launch the debugger and the host application on the same computer. The steps, however, are identical for debugging that is actually remote, so you will be able to use the same procedure for both scenarios.
[https://www.jetbrains.com/help/idea/tutorial-remote-debug.html]

I first wanted to try out the example from that tutorial directly on my Windows laptop using the IntelliJ IDEA (with the Java 25 JDK).

Following the tutorial, I set some breakpoints in the source code of the Alphabet class.

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 2
Below you can see the source code of the Alphabet class:

public class Alphabet {
    public static void main(String[] args) {
        System.out.println("Starting");
        for (char c = 'A'; c < 'Z'; c++) {
            try {
                Thread.sleep(2500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(c);
        }
        System.out.println("Complete");
    }
}

As you can see, the application will output the characters A to Y, each with a 2,5 second delay.

Setting up the debugger

Via the menu in IntelliJ IDEA, I navigated to Run | Edit Configurations…| (+) Add New Configuration | Remote JVM Debug.

I created the following Remote JVM Debug configuration (named: localhost5005), for “JDK 9 or later” with the following command line arguments for remote JVM:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 3

Setting up the application

Via the menu in IntelliJ IDEA, I navigated to Run | Edit Configurations…| (+) Add New Configuration | Application.

I created the following run configuration (named: Alphabet), with the following VM options, copied from the Remote JVM Debug configuration:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 4

Running the application

Then I proceeded with running the application.
From the Alphabet class, via the menu I navigated to Run | Run… (Alt+Shift+F10) | Alphabet:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 5

With the following output:

C:\My\App\Oracle\Java\jdk-25\bin\java.exe "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" "-javaagent:C:\My\App\Tools\JetBrains\IntelliJ IDEA Community Edition 2025.2.3\lib\idea_rt.jar=60989" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\My\Temp\remote-debug\target\classes Alphabet
Listening for transport dt_socket at address: 5005
Starting
A
B

In the output you can see, the following:

Listening for transport dt_socket at address: 5005

This indicates that we have enabled the debug agent and our program is ready to accept incoming debugger connections.

Then as soon as possible, from the Alphabet class, via the menu I navigated to Run | Debug… (Alt+Shift+F9) | localhost5005:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 6

As a result, the program is suspended at a breakpoint, and you can perform any debugging actions like steppingexpression evaluation, and so on.

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 7

As you can see the program was at the breakpoint on line 10. This breakpoint is within a for loop. Next, I removed that breakpoint and chose “Resume Program”.

Remark:
Because it took a short some time to start the debugger, the program was already past the breakpoint on line 3.
After a while the program was at the breakpoint on line 12.

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 8

Next, I had a look at the tab Console:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 9

The following output was visible in the debugger console:

Connected to the target VM, address: 'localhost:5005', transport: 'socket'

Next, I chose “Resume Program”.
With the following output in the debugger console:

Disconnected from the target VM, address: 'localhost:5005', transport: 'socket'

Next, I closed the tab “localhost5005”.

So, remote JVM debugging a Java application directly on my Windows laptop worked.
By the way, the normal output when you run the application is:

C:\My\App\Oracle\Java\jdk-25\bin\java.exe "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005" "-javaagent:C:\My\App\Tools\JetBrains\IntelliJ IDEA Community Edition 2025.2.3\lib\idea_rt.jar=62062" -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.stderr.encoding=UTF-8 -classpath C:\My\Temp\remote-debug\target\classes Alphabet
Listening for transport dt_socket at address: 5005
Starting
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Complete

Process finished with exit code 0

Remark:
If you start the remote JVM debugger, without starting the application first, you get the following error:

Error running 'localhost5005'
Unable to open debugger port (localhost:5005): java.net.ConnectException "Connection refused: connect

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 10

Remote JVM debugging a Java application from my Linux demo environment

So, next I wanted to try out remote JVM debugging, by running the “kubernetes-quickstart” application on my Linux demo environment and debugging it on my Windows laptop where I had the source code available in the IntelliJ IDEA.

The base for all of this was my already existing Linux demo environment, including Quarkus and K3s (a lightweight certified Kubernetes distribution) and setup via Vagrant, as described in a previous article.
[Quarkus – Kubernetes extension (reinvestigated, part 5), implementing a Service of service type LoadBalancer with K3s]

For the Linux demo environment to start, from the Oracle VM VirtualBox Manager on my Windows laptop, I started the appliance (in “Headless Start” mode). 

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 11

Once the VM was running, for executing later manual steps, I used vagrant ssh to connect into the running VM.

In order to get the Java version, I used the following command on the Linux Command Prompt:

java -version

With the following output:

openjdk version "24.0.1" 2025-04-15
OpenJDK Runtime Environment (build 24.0.1+9-30)
OpenJDK 64-Bit Server VM (build 24.0.1+9-30, mixed mode, sharing)

On my Windows laptop in the IntelliJ IDEA I opened the source code of the GreetingResource class and set a breakpoint. As you may remember from a previous article, I had a shared folder available.
[Quarkus – Supersonic Subatomic Java – Get Started (reinvestigated)]

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 12

Below you can see the source code of the GreetingResource class:

package org.acme;import jakarta.ws.rs.GET;import jakarta.ws.rs.Path;import jakarta.ws.rs.Produces;import jakarta.ws.rs.core.MediaType;@Path("/hello")public class GreetingResource {    @GET    @Produces(MediaType.TEXT_PLAIN)    public String hello() {        return "Hello from Quarkus REST";    }}

Via the menu in IntelliJ IDEA, I navigated to File | Project Structure… | Project and imported and used the correct SDK: Java OpenJDK 24.0.1.

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 13

In order to learn more about the remote JVM debugging part, I had a look at: IntelliJ IDEA tutorial: Remote debug

Setting up the debugger

In the same way as before, via the menu in IntelliJ IDEA, I navigated to Run | Edit Configurations…| (+) Add New Configuration | Remote JVM Debug.

I created the following Remote JVM Debug configuration (named: localhost5005), for “JDK 9 or later” with the following command line arguments for remote JVM:

-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 14

Running the application

For running the application I opted, on my Linux demo environment, for the Quarkus development mode.

For this, I also had a look at: Quarkus and Maven

By the way, in a previous article “Quarkus – Supersonic Subatomic Java – Get Started (reinvestigated)“, I already described how I used the Quarkus development mode, with the Getting Started Application.

Development mode

Quarkus comes with a built-in development mode. Run your application (for example via Maven) with:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 15

You can then update the application sources, resources and configurations. The changes are automatically reflected in your running application. This is great to do development spanning UI and database as you see changes reflected immediately.
Dev mode enables hot deployment with background compilation, which means that when you modify your Java files or your resource files and refresh your browser these changes will automatically take effect. This works too for resource files like the configuration property file. The act of refreshing the browser triggers a scan of the workspace, and if any changes are detected the Java files are compiled, and the application is redeployed, then your request is serviced by the redeployed application. If there are any issues with compilation or deployment an error page will let you know.

Hit CTRL+C to stop the application.

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 16
[https://quarkus.io/guides/maven-tooling#dev-mode]

Debugging

In development mode, Quarkus starts by default with debug mode enabled, listening to port 5005 without suspending the JVM.

This behavior can be changed by giving the debug system property one of the following values:

  • false - the JVM will start with debug mode disabled
  • true - The JVM is started in debug mode and will be listening on port 5005
  • client - the JVM will start in client mode and attempt to connect to localhost:5005
  • {port} - The JVM is started in debug mode and will be listening on {port}

An additional system property suspend can be used to suspend the JVM, when launched in debug mode. suspend supports the following values:

  • y or true - The debug mode JVM launch is suspended
  • n or false - The debug mode JVM is started without suspending

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 17
[https://quarkus.io/guides/maven-tooling#debugging]

As you may remember from a previous article, this Quarkus application is running at localhost:8080. In development mode, Quarkus starts by default with debug mode enabled, listening to port 5005 without suspending the JVM.
[Quarkus – Supersonic Subatomic Java – Get Started (reinvestigated)]

So, the first thing I needed was a port 8080 and 5005 forward from my Windows laptop to my VirtualBox Appliance with Ubuntu 22.04.

In the Oracle VM VirtualBox Manager on my Windows laptop, I navigated to the appliance | Details | Network | Advanced | Port Forwarding. Next, I added the two extra port forwarding rules:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 18

Remark:
For now I didn’t add them also to my Vagrantfile.

In order to run the application in development mode, I used the following commands on the Linux Command Prompt:

cd /mnt/mysharedfolder/kubernetes-quickstart/

mvn quarkus:dev

With the following output:

WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::staticFieldBase has been called by com.google.inject.internal.aop.HiddenClassDefiner (file:/opt/apache-maven-3.9.11/lib/guice-5.1.0-classes.jar)
WARNING: Please consider reporting this to the maintainers of class com.google.inject.internal.aop.HiddenClassDefiner
WARNING: sun.misc.Unsafe::staticFieldBase will be removed in a future release
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< org.acme:kubernetes-quickstart >-------------------
[INFO] Building kubernetes-quickstart 1.0.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- quarkus:3.25.2:dev (default-cli) @ kubernetes-quickstart ---
[INFO] Invoking resources:3.3.1:resources (default-resources) @ kubernetes-quickstart
[INFO] Copying 1 resource from src/main/resources to target/classes
[INFO] Invoking quarkus:3.25.2:generate-code (default) @ kubernetes-quickstart
[INFO] Invoking compiler:3.14.0:compile (default-compile) @ kubernetes-quickstart
[INFO] Nothing to compile - all classes are up to date.
[INFO] Invoking resources:3.3.1:testResources (default-testResources) @ kubernetes-quickstart
[INFO] skip non existing resourceDirectory /mnt/mysharedfolder/kubernetes-quickstart/src/test/resources
[INFO] Invoking quarkus:3.25.2:generate-code-tests (default) @ kubernetes-quickstart
[INFO] Invoking compiler:3.14.0:testCompile (default-testCompile) @ kubernetes-quickstart
[INFO] Nothing to compile - all classes are up to date.
Listening for transport dt_socket at address: 5005
2025-10-16 17:55:16,080 INFO  [io.qua.kub.dep.PropertyUtil] (build-10) Kubernetes manifests are generated with 'The container port http' having default value '8080'. The app and manifests will get out of sync if the property 'quarkus.http.port' is changed at runtime.
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2025-10-16 17:55:17,910 INFO  [io.quarkus] (Quarkus Main Thread) kubernetes-quickstart 1.0.0-SNAPSHOT on JVM (powered by2025-10-16 17:55:17,913 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2025-10-16 17:55:17,915 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, compose, kubernetes, rest, smallrye-context-propagation, vertx]


--
Tests paused
Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>

Next, I pressed r to resume testing.

With the following output:

All 1 test is passing (0 skipped), 1 test was run in 4260ms. Tests completed at 17:55:36.
Press [e] to edit command line args (currently ''), [r] to re-run, [o] Toggle test output, [:] for the terminal, [h] for more options>

In the output you can see, the following:

Listening for transport dt_socket at address: 5005

This indicates that we have enabled the debug agent and our program is ready to accept incoming debugger connections.

In IntelliJ IDEA on my Windows laptop, from the GreetingResource class, via the menu I navigated to Run | Debug… (Alt+Shift+F9) | localhost5005:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 19

So, now I got the following error:

Unable to open debugger port (localhost:5005): java.net.SocketException "Connection reset"

Then, in the Web Browser on my Windows laptop, I entered the URL:

http://localhost:8080/hello

And I got the following result:

This site can’t be reached

This looked all familiar to me. I remember from a previous article I wrote, that I had to make Quarkus listen on all network interfaces to resolve this.
[Quarkus – Supersonic Subatomic Java – Get Started (reinvestigated)]

In that article I described that I added the following setting in file application.properties:
[https://stackoverflow.com/questions/55043764/how-to-make-quarkus-to-listen-on-all-network-interfaces-instead-of-localhost]

quarkus.http.host=0.0.0.0

This time however, I was going to use a command line parameter.
Also remember the “Development mode” paragraph from the Quarkus and Maven documentation:
By default, quarkus:dev sets the debug host to localhost (for security reasons). If you need to change this, for example to enable debugging on all hosts, you can use the -DdebugHost option like so:

./mvnw quarkus:dev -DdebugHost=0.0.0.0

[https://quarkus.io/guides/maven-tooling#dev-mode]

So, in the still running session, I pressed q to quit the application.

With the following output:

2025-10-16 18:09:24,281 INFO  [io.quarkus] (Quarkus Main Thread) code-with-quarkus stopped in 0.005s

--

                                                                                                                        [INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  14:07 min
[INFO] Finished at: 2025-10-16T18:09:24Z
[INFO] ------------------------------------------------------------------------

In order to run the application in development mode (and listening on all network interfaces), I used the following commands on the Linux Command Prompt:

cd /mnt/mysharedfolder/kubernetes-quickstart/

mvn quarkus:dev -Dquarkus.http.host=0.0.0.0 -DdebugHost=0.0.0.0 -Dsuspend

Remark about suspend:
Whether the JVM launch, in debug mode, should be suspended. This parameter is only relevant when the JVM is launched in debug mode. This parameter supports the following values (all the allowed values are case-insensitive):

Value Effect
y or true The debug mode JVM launch is suspended
n or false The debug mode JVM is started without suspending

[https://quarkus.io/guides/quarkus-maven-plugin]

With the following output:


WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::staticFieldBase has been called by com.google.inject.internal.aop.HiddenClassDefiner (file:/opt/apache-maven-3.9.11/lib/guice-5.1.0-classes.jar)
WARNING: Please consider reporting this to the maintainers of class com.google.inject.internal.aop.HiddenClassDefiner
WARNING: sun.misc.Unsafe::staticFieldBase will be removed in a future release
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< org.acme:kubernetes-quickstart >-------------------
[INFO] Building kubernetes-quickstart 1.0.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- quarkus:3.25.2:dev (default-cli) @ kubernetes-quickstart ---
[INFO] Invoking resources:3.3.1:resources (default-resources) @ kubernetes-quickstart
[INFO] Copying 1 resource from src/main/resources to target/classes
[INFO] Invoking quarkus:3.25.2:generate-code (default) @ kubernetes-quickstart
[INFO] Invoking compiler:3.14.0:compile (default-compile) @ kubernetes-quickstart
[INFO] Nothing to compile - all classes are up to date.
[INFO] Invoking resources:3.3.1:testResources (default-testResources) @ kubernetes-quickstart
[INFO] skip non existing resourceDirectory /mnt/mysharedfolder/kubernetes-quickstart/src/test/resources
[INFO] Invoking quarkus:3.25.2:generate-code-tests (default) @ kubernetes-quickstart
[INFO] Invoking compiler:3.14.0:testCompile (default-testCompile) @ kubernetes-quickstart
[INFO] Nothing to compile - all classes are up to date.
Listening for transport dt_socket at address: 5005

In IntelliJ IDEA on my Windows laptop, from the GreetingResource class, via the menu I navigated to Run | Debug… (Alt+Shift+F9) | localhost5005:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 20

The following output was visible in the debugger console:

Connected to the target VM, address: 'localhost:5005', transport: 'socket'

This triggered the application to continue with running:

2025-10-17 10:56:31,910 INFO  [io.qua.kub.dep.PropertyUtil] (build-4) Kubernetes manifests are generated with 'The container port http' having default value '8080'. The app and manifests will get out of sync if the property 'quarkus.http.port' is changed at runtime.
__  ____  __  _____   ___  __ ____  ______
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2025-10-17 10:56:34,963 INFO  [io.quarkus] (Quarkus Main Thread) kubernetes-quickstart 1.0.0-SNAPSHOT on JVM (powered by2025-10-17 10:56:34,974 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2025-10-17 10:56:34,975 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, compose, kubernetes, rest, smallrye-context-propagation, vertx]

--
Tests paused
Press [e] to edit command line args (currently ''), [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>

Then, in the Web Browser on my Windows laptop, I entered the URL:

http://localhost:8080/hello

This triggered the debugger:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 21

As you can see the program was at the breakpoint on line 14. Next, I chose “Resume Program”.

And, then I got the following expected result:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 22

Next, I pressed r to resume testing.

With the following output:

--
Running 1/1. Running: org.acme.GreetingResourceTest#testHelloEndpoint()
Press [e] to edit command line args (currently ''), [o] Toggle test output, [:] for the terminal, [h] for more options>

Again, this triggered the debugger. So again in IntelliJ IDEA, I chose “Resume Program”.

With the following output:

2025-10-17 11:10:35,383 ERROR [io.qua.test] (Test runner thread) ==================== TEST REPORT #1 ====================
2025-10-17 11:10:35,384 ERROR [io.qua.test] (Test runner thread) Test GreetingResourceTest#testHelloEndpoint() failed
: java.net.SocketTimeoutException: Read timed out
        at io.restassured.internal.RequestSpecificationImpl.get(RequestSpecificationImpl.groovy)
        at org.acme.GreetingResourceTest.testHelloEndpoint(GreetingResourceTest.java:14)


2025-10-17 11:10:35,386 ERROR [io.qua.test] (Test runner thread) >>>>>>>>>>>>>>>>>>>> Summary: <<<<<<<<<<<<<<<<<<<<
org.acme.GreetingResourceTest#testHelloEndpoint(GreetingResourceTest.java:14) GreetingResourceTest#testHelloEndpoint() Read timed out
2025-10-17 11:10:35,387 ERROR [io.qua.test] (Test runner thread) >>>>>>>>>>>>>>>>>>>> 1 TEST FAILED <<<<<<<<<<<<<<<<<<<<


--
1 test failed (0 passing, 0 skipped), 1 test was run in 132400ms. Tests completed at 11:10:35.
Press [e] to edit command line args (currently ''), [r] to re-run, [o] Toggle test output, [:] for the terminal, [h] for more options>

Because of a read time out the test failed, as one might expect.

So, in the still running session, I pressed q to quit the application.

With the following output:

--

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  17:25 min
[INFO] Finished at: 2025-10-17T11:12:20Z
[INFO] ------------------------------------------------------------------------

Next, in IntelliJ IDEA, I closed the tab “localhost5005”.

So, remote JVM debugging a Java application from my Linux demo environment also worked 😊.

Remote JVM debugging a Java application from a Kubernetes cluster running in my Linux demo environment

From the Quarkus Kubernetes Extension documentation, I had a look at the “Remote Debugging" paragraph.
[https://quarkus.io/guides/deploying-to-kubernetes]

Remote debugging

To remotely debug applications that are running on a kubernetes environment, we need to deploy the application as described in the previous section and add as new property: quarkus.kubernetes.remote-debug.enabled=true. This property will automatically configure the Java application to append the java agent configuration (for example: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005) and also the service resource to listen using the java agent port.
[https://quarkus.io/guides/deploying-to-kubernetes#remote-debugging]

Next, on my Windows laptop, in my shared folder, I navigated to kubernetes-quickstart\src\main\resources and changed the content of file application.properties to:
[in bold, I highlighted the changes]

quarkus.container-image.registry=localhost:8443
quarkus.container-image.username=mylocregusername
quarkus.container-image.password=mylocregpassword
quarkus.container-image.group=quarkus
quarkus.kubernetes.namespace=nl-amis-development
quarkus.kubernetes.ports."ports".container-port=8080
quarkus.kubernetes.ports."ports".host-port=8180
quarkus.kubernetes.ports."ports".node-port=30010
quarkus.kubernetes.replicas=3
quarkus.kubernetes.service-type=node-port
quarkus.kubernetes.remote-debug.enabled=true
quarkus.kubernetes.remote-debug.address-port=5005

As, you can see I also opted for returning to using a service of service type NodePort.
[Quarkus – Kubernetes extension (reinvestigated, part 4), implementing a Service of service type NodePort]

Remark about quarkus.kubernetes.remote-debug.enabled:

Kubernetes property Type Default
quarkus.kubernetes.remote-debug.enabled If true, the debug mode in pods will be enabled. Environment variable: QUARKUS_KUBERNETES_REMOTE_DEBUG_ENABLED boolean false

[https://quarkus.io/guides/all-config]

Remark about quarkus.kubernetes.remote-debug.address-port:

Kubernetes property Type Default
quarkus.kubernetes.remote-debug.address-port It specifies the address at which the debug socket will listen. Environment variable: QUARKUS_KUBERNETES_REMOTE_DEBUG_ADDRESS_PORT int 5005

[https://quarkus.io/guides/all-config]

So, although I used the default value, I still opted for adding quarkus.kubernetes.remote-debug.address-port to the application.properties.

In order to recreate the Kubernetes manifests, I used the following commands on the Linux Command Prompt:

cd /mnt/mysharedfolder/kubernetes-quickstart

mvn clean install

Below, you can see the content of the target/kubernetes/kubernetes.yml Kubernetes manifests, provided by the Quarkus project packaging:
[in bold, I highlighted the changes with regard to remote debugging]

---
apiVersion: v1
kind: Service
metadata:
  annotations:
    app.quarkus.io/quarkus-version: 3.25.2
    app.quarkus.io/build-timestamp: 2025-10-17 - 17:04:59 +0000
  labels:
    app.kubernetes.io/name: kubernetes-quickstart
    app.kubernetes.io/version: 1.0.0-SNAPSHOT
    app.kubernetes.io/managed-by: quarkus
  name: kubernetes-quickstart
  namespace: nl-amis-development
spec:
  ports:
    - name: debug
      port: 5005
      protocol: TCP
      targetPort: 5005
    - name: ports
      nodePort: 30010
      port: 8180
      protocol: TCP
      targetPort: 8080
  selector:
    app.kubernetes.io/name: kubernetes-quickstart
    app.kubernetes.io/version: 1.0.0-SNAPSHOT
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    app.quarkus.io/quarkus-version: 3.25.2
    app.quarkus.io/build-timestamp: 2025-10-17 - 17:04:59 +0000
  labels:
    app.kubernetes.io/name: kubernetes-quickstart
    app.kubernetes.io/version: 1.0.0-SNAPSHOT
    app.kubernetes.io/managed-by: quarkus
  name: kubernetes-quickstart
  namespace: nl-amis-development
spec:
  replicas: 3
  selector:
    matchLabels:                                         
      app.kubernetes.io/version: 1.0.0-SNAPSHOT
      app.kubernetes.io/name: kubernetes-quickstart
  template:
    metadata:
      annotations:
        app.quarkus.io/quarkus-version: 3.25.2
        app.quarkus.io/build-timestamp: 2025-10-17 - 17:04:59 +0000
      labels:
        app.kubernetes.io/managed-by: quarkus                                
        app.kubernetes.io/version: 1.0.0-SNAPSHOT
        app.kubernetes.io/name: kubernetes-quickstart
    spec:
      containers:
        - env:
            - name: KUBERNETES_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: JAVA_TOOL_OPTIONS
              value: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"
          image: localhost:8443/quarkus/kubernetes-quickstart:1.0.0-SNAPSHOT
          imagePullPolicy: Always
          name: kubernetes-quickstart
          ports:
            - containerPort: 5005
              name: debug
              protocol: TCP
            - containerPort: 8080
              name: ports
              protocol: TCP

Next, in order to build and push a container image for my project, I used the following commands on the Linux Command Prompt:

cd /mnt/mysharedfolder/kubernetes-quickstart

mvn clean install -Dquarkus.container-image.build=true -Dquarkus.container-image.push=true

With the following output:

WARNING: A terminally deprecated method in sun.misc.Unsafe has been called
WARNING: sun.misc.Unsafe::staticFieldBase has been called by com.google.inject.internal.aop.HiddenClassDefiner (file:/opt/apache-maven-3.9.11/lib/guice-5.1.0-classes.jar)
WARNING: Please consider reporting this to the maintainers of class com.google.inject.internal.aop.HiddenClassDefiner
WARNING: sun.misc.Unsafe::staticFieldBase will be removed in a future release
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------< org.acme:kubernetes-quickstart >-------------------
[INFO] Building kubernetes-quickstart 1.0.0-SNAPSHOT
[INFO]   from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ kubernetes-quickstart ---
[INFO] Deleting /mnt/mysharedfolder/kubernetes-quickstart/target
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ kubernetes-quickstart ---
[INFO] Copying 1 resource from src/main/resources to target/classes
[INFO]
[INFO] --- quarkus:3.25.2:generate-code (default) @ kubernetes-quickstart ---
[INFO]
[INFO] --- compiler:3.14.0:compile (default-compile) @ kubernetes-quickstart ---
[INFO] Recompiling the module because of changed source code.
[INFO] Compiling 1 source file with javac [debug parameters release 21] to target/classes
[INFO]
[INFO] --- quarkus:3.25.2:generate-code-tests (default) @ kubernetes-quickstart ---
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ kubernetes-quickstart ---
[INFO] skip non existing resourceDirectory /mnt/mysharedfolder/kubernetes-quickstart/src/test/resources
[INFO]
[INFO] --- compiler:3.14.0:testCompile (default-testCompile) @ kubernetes-quickstart ---
[INFO] Recompiling the module because of changed dependency.
[INFO] Compiling 2 source files with javac [debug parameters release 21] to target/test-classes
[INFO]
[INFO] --- surefire:3.5.3:test (default-test) @ kubernetes-quickstart ---
[INFO] Using auto detected provider org.apache.maven.surefire.junitplatform.JUnitPlatformProvider
[INFO]
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running org.acme.GreetingResourceTest
2025-10-17 17:13:27,337 INFO  [io.quarkus] (main) kubernetes-quickstart 1.0.0-SNAPSHOT on JVM (powered by Quarkus 3.25.2) started in 5.909s. Listening on: http://localhost:8081
2025-10-17 17:13:27,343 INFO  [io.quarkus] (main) Profile test activated.
2025-10-17 17:13:27,343 INFO  [io.quarkus] (main) Installed features: [cdi, compose, kubernetes, rest, smallrye-context-propagation, vertx]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 2.861 s -- in org.acme.GreetingResourceTest
Exception in thread "vert.x-internal-blocking-1" java.lang.IllegalAccessError: module java.base does not open java.lang to unnamed module @e91af20; to use the thread-local-reset capability on Java 24 or later, use this JVM option: --add-opens java.base/java.lang=ALL-UNNAMED
        at org.jboss.threads.JDKSpecific$ThreadAccess.<clinit>(JDKSpecific.java:32)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:13)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1447)
Exception in thread "executor-thread-1" java.lang.NoClassDefFoundError: Could not initialize class org.jboss.threads.JDKSpecific$ThreadAccess
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:13)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1447)
Caused by: java.lang.ExceptionInInitializerError: Exception java.lang.IllegalAccessError: module java.base does not open java.lang to unnamed module @e91af20; to use the thread-local-reset capability on Java 24 or later, use this JVM option: --add-opens java.base/java.lang=ALL-UNNAMED [in thread "vert.x-internal-blocking-1"]
        at org.jboss.threads.JDKSpecific$ThreadAccess.<clinit>(JDKSpecific.java:32)
        ... 3 more
2025-10-17 17:13:29,597 INFO  [io.quarkus] (main) kubernetes-quickstart stopped in 0.085s
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- jar:3.4.1:jar (default-jar) @ kubernetes-quickstart ---
[INFO] Building jar: /mnt/mysharedfolder/kubernetes-quickstart/target/kubernetes-quickstart-1.0.0-SNAPSHOT.jar
[INFO]
[INFO] --- quarkus:3.25.2:build (default) @ kubernetes-quickstart ---
[INFO] [io.quarkus.kubernetes.deployment.PropertyUtil] Kubernetes manifests are generated with 'The container port http' having default value '8080'. The app and manifests will get out of sync if the property 'quarkus.http.port' is changed at runtime.
[INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Starting (local) container image build for jar using jib.
[WARNING] [io.quarkus.container.image.jib.deployment.JibProcessor] Base image 'registry.access.redhat.com/ubi9/openjdk-21-runtime:1.21' does not use a specific image digest - build may not be reproducible
[INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Using base image with digest: sha256:360822c35c5741f542ab78fe123e6c4d9b68e0113a88d6e0250bb1f377b17f29
[INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Container entrypoint set to [/opt/jboss/container/java/run/run-java.sh]
[INFO] [io.quarkus.container.image.jib.deployment.JibProcessor] Pushed container image localhost:8443/quarkus/kubernetes-quickstart:1.0.0-SNAPSHOT (sha256:8406a011b49a42ffb3f4c73c694644afb56c10e740c3c65a83fa9fbb0c8350a5)

[INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 17046ms
[INFO]
[INFO] --- failsafe:3.5.3:integration-test (default) @ kubernetes-quickstart ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- quarkus:3.25.2:native-image-agent (default) @ kubernetes-quickstart ---
[INFO] Missing native-image-agent-base-config directory with native image agent configuration to transform
[INFO]
[INFO] --- failsafe:3.5.3:verify (default) @ kubernetes-quickstart ---
[INFO] Tests are skipped.
[INFO]
[INFO] --- install:3.1.2:install (default-install) @ kubernetes-quickstart ---
[INFO] Installing /mnt/mysharedfolder/kubernetes-quickstart/pom.xml to /home/vagrant/.m2/repository/org/acme/kubernetes-quickstart/1.0.0-SNAPSHOT/kubernetes-quickstart-1.0.0-SNAPSHOT.pom
[INFO] Installing /mnt/mysharedfolder/kubernetes-quickstart/target/kubernetes-quickstart-1.0.0-SNAPSHOT.jar to /home/vagrant/.m2/repository/org/acme/kubernetes-quickstart/1.0.0-SNAPSHOT/kubernetes-quickstart-1.0.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  40.013 s
[INFO] Finished at: 2025-10-17T17:13:47Z
[INFO] ------------------------------------------------------------------------

Removing the created Kubernetes objects

So, as I mentioned in my previous article, the Quarkus generated manifest kubernetes.yml, was applied to the Kubernetes cluster and created the following Kubernetes objects (in my custom nl-amis-development namespace):

  • Service
  • Deployment
  • Replica Set
  • Pod

Because I wanted to create the Kubernetes objects again, first I had to delete the existing ones. I repeated some of the steps I already described in a previous article.
[Quarkus – Kubernetes extension (reinvestigated, part 4), implementing a Service of service type NodePort]

In order to delete the Replica Set and all of the dependent Pods (in the nl-amis-development namespace), I used the following command on the Linux Command Prompt:

kubectl delete -n nl-amis-development replicaset $(kubectl get replicasets -n nl-amis-development -o=jsonpath='{range .items..metadata}{.name}{"\n"}{end}' | grep kubernetes-quickstart- | awk '{print $1}')

With the following output:

replicaset.apps "kubernetes-quickstart-6d8f86d78f" deleted

To delete a ReplicaSet and all of its Pods, use kubectl delete. The Garbage collector automatically deletes all of the dependent Pods by default.
[https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/#deleting-a-replicaset-and-its-pods]

In order to delete the Deployment, I used the following command on the Linux Command Prompt:

kubectl delete -n nl-amis-development deployment kubernetes-quickstart

With the following output:

deployment.apps "kubernetes-quickstart" deleted

In order to delete the Service, I used the following command on the Linux Command Prompt:

kubectl delete -n nl-amis-development service kubernetes-quickstart

With the following output:

service "kubernetes-quickstart" deleted

Recreating the Kubernetes objects in the nl-amis-development namespace, including a service with service type NodePort

Next, in order to recreate the Kubernetes manifests (in the nl-amis-development namespace), I used the following commands on the Linux Command Prompt:

cd /mnt/mysharedfolder/kubernetes-quickstart

kubectl apply -f target/kubernetes/kubernetes.yml

With the following output:

service/kubernetes-quickstart created
deployment.apps/kubernetes-quickstart created

Remark:
Be aware that I already created the nl-amis-development namespace object.

Then, I quickly checked whether the Pods were running successfully, via a series of commands on the Linux Command Prompt.

kubectl get services --all-namespaces

With the following output:

NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 65d
kube-system kube-dns ClusterIP 10.43.0.10 <none> 53/UDP,53/TCP,9153/TCP 65d
kube-system metrics-server ClusterIP 10.43.45.122 <none> 443/TCP 65d
kube-system traefik LoadBalancer 10.43.141.14 10.0.2.15 80:30268/TCP,443:32611/TCP 65d
kubernetes-dashboard dashboard-metrics-scraper ClusterIP 10.43.18.175 <none> 8000/TCP 65d
kubernetes-dashboard kubernetes-dashboard ClusterIP 10.43.77.188 <none> 443/TCP 65d
nl-amis-development kubernetes-quickstart NodePort 10.43.208.251 <none> 8180:30010/TCP,5005:31906/TCP 9s

kubectl get replicasets --all-namespaces

With the following output:

NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system coredns-5688667fd4 1 1 1 65d
kube-system local-path-provisioner-774c6665dc 1 1 1 65d
kube-system metrics-server-6f4c6675d5 1 1 1 65d
kube-system traefik-c98fdf6fb 1 1 1 65d
kubernetes-dashboard dashboard-metrics-scraper-749c668b7f 1 1 1 65d
kubernetes-dashboard kubernetes-dashboard-76b75d676c 1 1 1 65d
nl-amis-development kubernetes-quickstart-dcd557cfd 3 3 3 32s

kubectl get daemonset --all-namespaces

With the following output:

NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system svclb-traefik-dee09411 1 1 1 1 1 <none> 65d

kubectl get pods --all-namespaces

With the following output:

NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-5688667fd4-2hqfj 1/1 Running 14 (8h ago) 65d
kube-system helm-install-traefik-crd-kp2hl 0/1 Completed 0 65d
kube-system helm-install-traefik-vl7x8 0/1 Completed 2 65d
kube-system local-path-provisioner-774c6665dc-2b9pq 1/1 Running 14 (8h ago) 65d
kube-system metrics-server-6f4c6675d5-lljlv 1/1 Running 14 (8h ago) 65d
kube-system svclb-traefik-dee09411-c7lzh 2/2 Running 28 (8h ago) 65d
kube-system traefik-c98fdf6fb-stkt7 1/1 Running 14 (8h ago) 65d
kubernetes-dashboard dashboard-metrics-scraper-749c668b7f-s7rjt 1/1 Running 14 (8h ago) 65d
kubernetes-dashboard kubernetes-dashboard-76b75d676c-tq8fk 1/1 Running 14 (25m ago) 65d
nl-amis-development kubernetes-quickstart-dcd557cfd-9bmd6 1/1 Running 0 72s
nl-amis-development kubernetes-quickstart-dcd557cfd-f5vhj 1/1 Running 0 72s
nl-amis-development kubernetes-quickstart-dcd557cfd-zrwbt 1/1 Running 0 72s

kubectl get endpoints --all-namespaces

With the following output:

Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAMESPACE              NAME                        ENDPOINTS                                                        AGE
default                kubernetes                  10.0.2.15:6443                                                   65d
kube-system            kube-dns                    10.42.0.162:53,10.42.0.162:53,10.42.0.162:9153                   65d
kube-system            metrics-server              10.42.0.165:10250                                                65d
kube-system            traefik                     10.42.0.158:8000,10.42.0.158:8443                                65d
kubernetes-dashboard   dashboard-metrics-scraper   10.42.0.167:8000                                                 65d
kubernetes-dashboard   kubernetes-dashboard        10.42.0.160:8443                                                 65d
nl-amis-development    kubernetes-quickstart       10.42.0.178:5005,10.42.0.179:5005,10.42.0.180:5005 + 3 more...   109s
kubectl get endpoints -n nl-amis-development --output json

With the following output:


Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
{
    "apiVersion": "v1",
    "items": [
        {
            "apiVersion": "v1",
            "kind": "Endpoints",
            "metadata": {
                "annotations": {
                    "endpoints.kubernetes.io/last-change-trigger-time": "2025-10-17T17:16:39Z"
                },
                "creationTimestamp": "2025-10-17T17:16:37Z",
                "labels": {
                    "app.kubernetes.io/managed-by": "quarkus",
                    "app.kubernetes.io/name": "kubernetes-quickstart",
                    "app.kubernetes.io/version": "1.0.0-SNAPSHOT",
                    "endpoints.kubernetes.io/managed-by": "endpoint-controller"
                },
                "name": "kubernetes-quickstart",
                "namespace": "nl-amis-development",
                "resourceVersion": "23654",
                "uid": "4893e38f-5e3d-4268-bc30-3a7461cff845"
            },
            "subsets": [
                {
                    "addresses": [
                        {
                            "ip": "10.42.0.178",
                            "nodeName": "ubuntu2204.localdomain",
                            "targetRef": {
                                "kind": "Pod",
                                "name": "kubernetes-quickstart-dcd557cfd-f5vhj",
                                "namespace": "nl-amis-development",
                                "uid": "e1a02732-a8c8-4916-802f-c515ba18fed4"
                            }
                        },
                        {
                            "ip": "10.42.0.179",
                            "nodeName": "ubuntu2204.localdomain",
                            "targetRef": {
                                "kind": "Pod",
                                "name": "kubernetes-quickstart-dcd557cfd-zrwbt",
                                "namespace": "nl-amis-development",
                                "uid": "9b8faaea-0687-4f56-b19a-c2db21e8d1b2"
                            }
                        },
                        {
                            "ip": "10.42.0.180",
                            "nodeName": "ubuntu2204.localdomain",
                            "targetRef": {
                                "kind": "Pod",
                                "name": "kubernetes-quickstart-dcd557cfd-9bmd6",
                                "namespace": "nl-amis-development",
                                "uid": "05ca798b-47f9-465f-8854-8add14cfbca5"
                            }
                        }
                    ],
                    "ports": [
                        {
                            "name": "debug",
                            "port": 5005,
                            "protocol": "TCP"
                        },
                        {
                            "name": "ports",
                            "port": 8080,
                            "protocol": "TCP"
                        }
                    ]
                }
            ]
        }
    ],
    "kind": "List",
    "metadata": {
        "resourceVersion": ""
    }
}
kubectl get nodes

With the following output:

NAME STATUS ROLES AGE VERSION
ubuntu2204.localdomain Ready control-plane,master 65d v1.33.3+k3s1

In order to determine the IP of the K3s node, I used the following commands on the Linux Command Prompt, as I described in a previous article:
[Creating a re-usable Vagrant Box from an existing VM with Ubuntu and k3s (with the Kubernetes Dashboard) and adding mysql, using Vagrant and Oracle VirtualBox]

nodeIP=$(kubectl get node ubuntu2204.localdomain -o yaml | grep address: | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}")
echo "---$nodeIP---"

With the following output:

---10.0.2.15---

Below, you see an overview of my Kubernetes cluster at this moment:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 23

From the Quarkus Kubernetes Extension documentation, I had a further look at the “Remote Debugging" paragraph.
[https://quarkus.io/guides/deploying-to-kubernetes]

Remote debugging

After your application has been deployed with the debug enabled, next you need to tunnel the traffic from your local host machine to the specified port of the java agent:

kubectl port-forward svc/<application name> 5005:5005

Using this command, you’ll forward the traffic from the "localhost:5005" to the kubernetes service running the java agent using the port "5005" which is the one that the java agent uses by default for remote debugging. You can also configure another java agent port using the property quarkus.kubernetes.remote-debug.address-port.

Finally, all you need to do is to configure your favorite IDE to attach the java agent process that is forwarded to localhost:5005 and start to debug your application. For example, in IntelliJ IDEA, you can follow this tutorial to debug remote applications.
[https://quarkus.io/guides/deploying-to-kubernetes#remote-debugging]

In order to forward the traffic, I used the following command on the Linux Command Prompt:

kubectl port-forward -n nl-amis-development service/kubernetes-quickstart 5005:5005

With the following output:

Forwarding from 127.0.0.1:5005 -> 5005

In IntelliJ IDEA on my Windows laptop, from the GreetingResource class, via the menu I navigated to Run | Debug… (Alt+Shift+F9) | localhost5005:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 24

So, now I got the following error:

Unable to open debugger port (localhost:5005): java.net.SocketException "Connection reset"

In order to forward the traffic (on all addresses) , I used the following command on the Linux Command Prompt:

kubectl port-forward -n nl-amis-development --address 0.0.0.0 service/kubernetes-quickstart 5005:5005

With the following output:

Forwarding from 0.0.0.0:5005 -> 5005

By the way, below you see another port forward example:

  # Listen on port 8888 on all addresses, forwarding to 5000 in the pod
  kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000

[https://kubernetes.io/docs/reference/kubectl/generated/kubectl_port-forward/]

Remark about the option –address:
--address strings Default: "localhost"
Addresses to listen on (comma separated). Only accepts IP addresses or localhost as a value. When localhost is supplied, kubectl will try to bind on both 127.0.0.1 and ::1 and will fail if neither of these addresses are available to bind.
[https://kubernetes.io/docs/reference/kubectl/generated/kubectl_port-forward/]

Again, in IntelliJ IDEA on my Windows laptop, from the GreetingResource class, via the menu I navigated to Run | Debug… (Alt+Shift+F9) | localhost5005:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 25

The following output was visible in the debugger console:

Connected to the target VM, address: 'localhost:5005', transport: 'socket'

And the following output was visible on the Linux Command Prompt:

Handling connection for 5005

In order to forward local port 8090 to port 30100 on the K3s node ($nodeIP), I used the following command on the Linux Command Prompt, as I described in a previous article:
[Creating a re-usable Vagrant Box from an existing VM with Ubuntu and k3s (with the Kubernetes Dashboard) and adding mysql, using Vagrant and Oracle VirtualBox]

socat tcp-listen:8090,fork tcp:10.0.2.15:30010 &

With the following output:

[1] 33602

Then, in the Web Browser on my Windows laptop, I entered the URL:

http://localhost:8090/hello

This triggered the debugger:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 26

As you can see the program was at the breakpoint on line 14. Next, I chose “Resume Program”.

And, then I got the following expected result:

Quarkus - Kubernetes extension (reinvestigated, part 6), Remote debugging a Java application that is running in a container on a Kubernetes cluster lameriks 2025 10 27

Next, in IntelliJ IDEA, I in the tab “localhost5005”, I clicked on “ Stop localhost5005’ ”.
With the following output in the debugger console:

Disconnected from the target VM, address: 'localhost:5005', transport: 'socket'

Next, I closed the tab “localhost5005”.

So, remote JVM debugging a Java application from a Kubernetes cluster running in my Linux demo environment also worked 😊.

I conclude this article.

In this article, you can read more about the steps I took to remotely debug a Java application that is running in a container on a Kubernetes cluster in my already existing Linux demo environment, including Quarkus and K3s (a lightweight certified Kubernetes distribution) and setup via Vagrant.

I went about this, step by step via:

  • Remote JVM debugging a Java application directly on my Windows laptop
  • Remote JVM debugging a Java application from my Linux demo environment
  • Remote JVM debugging a Java application from a Kubernetes cluster running in my Linux demo environment

In a next article, you can read more about using development mode remotely, so that you can run Quarkus in a container environment and have changes made to your local files become immediately visible.

Feel free, among my other articles on this subject, to read:

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.