IntelliJ and WSL 2 configuration
So we have an IntelliJ plugin.
In the plugin.xml we have a programRunner and java.programPatcher for patching the JVM arguments that actually go to the launched program.
It works on normal intelliJ for java/maven/server run's.
I work under Windows. Now I added a WSL 2 setup with Ubuntu.
I got an example project copyed from windows into WSL user directory and installed a JDK with IntelliJ there (note: IntelliJ did not allow to select an already installed JDK as the path did not start with C:/..)
Now if I have a maven project without WSL and run the program in IntelliJ maven I can see in console that the java starts with my changed parameters. If I run the same program in WSL I can see that maven start without my plugin changed parameters.
So the first question here would be why does the maven program command locally start with java and on WSL with maven (without the java arguments change)? And why do the arguments changed in JavaParameters by patcher not apply to WSL (I can see from logs that patcher runs)?
Now okei, maven is complex. Let's tray plain java.
So I run the main class on plain windows and I see that java runs and it has my changed arguments.
But now when I run the same project on WLS with java I can see that java runs. I can even see that my patcher runs from logs, but once the java start in WLS my added parameters are missing.
So the question here would be that do the arguments patchers not work for WLS or I am doing something wrong?
Please sign in to leave a comment.
Based on the "planned" tag I presume this will be fixed in a future release?
But as I have made some more experimenting I will share the results here.
I was on CE when I made the first tests.
Now I got myself the latest UE. For there I got the java arguments passed once, but after an IDE restart they were gone again..
As CE did not have servers (tomcat) I could not try out if arguments to it are passed correctly before.
Now I am experimenting with Tomcat on UE, to run the server in WLS on windows. And I saw a warning in the logs. maybe this can also be easily fixed:
2024-11-28 10:57:46,669 [1852635] WARN - #c.i.j.o.s.WslSupportUtil - Failed to execute a command on WSL: cat /home/myuser/apache-tomcat-9.0.97/bin/catalina.sh/bin/setenv.sh. An error occurred: cat: /home/myuser/apache-tomcat-9.0.97/bin/catalina.sh/bin/setenv.sh: Not a directory
It seems to search for setenv.sh in a weird place.
As startup complained about missing setenv.sh I did add it next to catalina.sh: /home/myuser/apache-tomcat-9.0.97/bin/setenv.sh
Currently it seem's to me that the patch arguments at least works for the Tomcat server on most of the cases.
Unless you add too many arguments into javaParameters.getVMParametersList(). In that case the end of the JAVA_OPTS is replaced with a "Disconnected from server" string and the tomcat in WLS will fail to start with invalid java command.
As the path changes from windows to unix C:/ vs /mnt/c/ I have a question. Does intelliJ have some public API that we should use in plugins to convert the paths?
Currently in the callsite I have access to JavaParameters and RunProfile.
I saw that javaParameters.getJdk().getHomePath().startsWith("//wsl$/") could be a dump check for wsl presents, but maybe there are some cleaner options?
Hi,
The Planned tag means that the question is being processed. It was forwarded to a person responsible for WSL implementation. Please be patient.
Hi,
This part looks interesting. I'd like to see either a simple reproducer or debug logs of the IDE (Debug Log Settings → `com.intellij.platform.ijent`) after reproducing the bug on your setup. The logs will contain sensitive data, so it's better to upload the log file at https://uploads.jetbrains.com , so the file won't be publicly accessible.
There's a method `com.intellij.execution.wsl.WSLDistribution#getWslPath(java.nio.file.Path)`, it's better to check if its result is not null.
So I added the logs. Got the uploade id: 2024_12_05_21mxY7HyUpMkwaroUdebL2
I added readme there with some extra content. I can produce more logs if needed.
Coming back here for the WSL paths.
I saw that WSLDistribution#getWslPath(java.nio.file.Path) is a non-static method so to use it I must get an instance of WSLDistribution somewhere?
If I could get an instance it would solve the path conversion part of the issue, but it would not solve the issue of knowing if I should convert or not?
Ie it does not say if the run is WSL on normal local java run. Can I get this information somehow from JavaParameters or RunProfile?
Yes. I don't know your context and needs, but when we do anything on WSL, we always know on what particular WSL we are doing that, and the corresponding WSLDistribution is always somewhere close. Anyway, you can get the list of all available instances by calling `WslDistributionManager.getInstance().getInstalledDistributionsFuture()`
Yes, really, it converts `C:\` to `/mnt/c`, and that's not what you need.
Then, take a look at `com.intellij.execution.wsl.WslPath.Companion#parseWindowsUncPath`. It returns a nullable `WslPath`. So, if the result is not null, it belongs to some WSL distribution. By the way, `WslPath` has a property `distribution` with the type `WSLDistribution`.
We don't need WSL, but there can be WSL in IntelliJ configuration. We need to know if WSL is used or not.
In short our plugin needs to know if the jvm started is on WSL or not to add the right (path) parameters to the program.
As I have access to javaParameters.getJdk().getHomePath().startsWith("//wsl$/") I thought it can be used to know if JavaParameters or RunProfile goes to WSL or not. But looking at the javaParameters.getJdk().getHomePath() seems a little wrong to me, maybe there should be an attribute on javaParameters or RunProfile that tells you if or what remote system is used?
(I noticed also that intelliJ can run stuff on docker and ssh. I have not looked into more details on those jet, but they will have the same issue, that we should know somehow that the machine java is running is not local, but wsl/docker/ssh and path startsWith will probably not work on those..)
Well, it's the way how you can determine if some Run Configuration aims to WSL or not.
There is also Run Targets API, but please don't use it if you can. We're going to deprecate that API.
We're actively working on that API right now. When it's ready for public usage, we'll mark the whole WSLDistribution as deprecated and provide docs for migration. You can take a glance at how our new API looks today. Beware, it'll likely change many times. It's so experimental that it doesn't deserve the annotation `@experimental` yet.
And that new API relies on looking at paths like `javaParameters.getJdk().getHomePath()` as well.
Heh. Ok.
I did not expect javaParameters.getJdk().getHomePath() to be the recommended way to make the differentiation.
For now I think we will not do any integration with WSLDistribution, but will wait for the new APIs in the future (hopefully not far future).
I hope you can reproduce/fix the jvm args passing issues found or tell me what I did wrong on that part!