How to properly kill the child Java process when AvaloniaUI app is exiting?

63 views Asked by At

In my AvaloniaUI app, I'm running an Java application as a Process.

private static Process _process;

string command = $"-jar \"{jar}\"";

ProcessStartInfo startInfo = new("java", command)
{
    RedirectStandardOutput = true,
    RedirectStandardInput = true,
    UseShellExecute = false,
    CreateNoWindow = true,
};

((IClassicDesktopStyleApplicationLifetime)Application.Current.ApplicationLifetime).Exit += (s, e) =>
{
    try { _process?.Kill(); } catch { }
};

_process = new()
{
    StartInfo = startInfo
};



_process.OutputDataReceived += OnDataReceived;
_process.Start();

In MainWindow's Closing event I have Process?.Kill(); too.

But, sometimes it doesn't work, e.g. when my app is killed from the Task Manager.

How can I fix it? I found a few solutions here, but they are requring Windows - I need support for Linux and macOS too.

I would prefer not to edit the Java application code.

1

There are 1 answers

0
David Weber On BEST ANSWER

What you are trying to archive is a kind of dynamic communication between different applications during runtime.

You have two applications one in c#, and one in Java. The Java app depends in the c# app, and in ANY case the c# app dies, the Java app shall die too.

There is no solution, that comes just with the framework.

Solution 1:

Implement a polling scheduler in the Java app which executes a simple health check to the c# app every 30 seconds e.g. If the health check is negative, Stop the Java app.

Solution 2:

Try to create a standalone thread in your c# application, which "survives" the process kill of the application itself. This thread shall schedule a simple health check to the c# app every 30 seconds.

Solution 3:

Create a script that is started in your c# App which does the health check job.

Solution 4:

Create a third application in your infrastructure that does the healthchecks.

Solution 5:

Use a third party tool for doing this. There are tools out tere to handle microservices which is the same principle.

Example given Docker with docker-compose:

docker-compose up --abort-on-container-exit

This will stop all running containers if only Just one of the containers stops. No polling implememtation needed.

Downside: Works only if you can apply this somehow to the fact, that the Java app is started from the c# App