rcasia / neotest-java

Neotest adapter for Java.
MIT License
42 stars 23 forks source link

Correctly detect the project runtime based on the active language server #124

Closed asmodeus812 closed 3 weeks ago

asmodeus812 commented 3 months ago

The goal of this pr is to correctly resolve the runtime home directory of the jdk that a specific project is using, after that the JAVA_HOME env variable is set to that, and the appropriate maven or gradle commands can be run.

This has to be done when we call maven or gradle. The reason this is needed is pretty simple, noone has just one single runtime installed on their system, and most people work with multiple java projects configured/developed to work with different runtime versions.

For example say a user has installed the latest jdk & setup his JAVA_HOME and PATH to point to jdk21, however the user would like to run/compile the tests for an older java 8, 11 or 17 spring project.

The JAVA_HOME variable has to be set to the correct runtime for the project before any relevant maven or gradle commands are run otherwise, for more simple projects you might get by and compile it, but for more complex projects which might be using deprecated or straight up removed features between major jdk versions, you will either fail to compile the code or you will encounter a runtime exception while running the code.

By default maven always picks up JAVA_HOME, you can also configure this in the pom itself, (by adding additional toolchain and compiler plugins) by setting the path to the runtime in the compiler plugin (for your local machine) gradle is more versatile it still reads JAVA_HOME, however you can start it with -D argument or you can configure the path to the runtime in build.gradle.

Both maven and gradle have toolchain plugins which allow them to specify the java version/runtime for the project separate from the java stack on user's PATH, manually, proivde absolute path to the desired runtime on your local machine, that the project has to be run with, however in practice noone does this, locally, since most projects are microservices, they rely on pod's env.

You can see why this is kind of needed, while it is possible to provide the path to the runtime for a project, and have it be separate from JAVA_HOME (i.e the java stack which is on your PATH)

The solution in this plugin is to provide the runtimes just once, either as env variables JAVA_HOME_XX, or in your lua config, not having to modify the pom for each project, locally, separately, having to add additional maven/gradle plugins to the project just to be able to specify this etc, and you would certainly forget to do that.

TL;DR - Nothing guarantees you that the java stack on user's PATH is the one a specific project requires to be compiled / depends on.

asmodeus812 commented 3 months ago

@rcasia could you take a look again, there are a few standing questions, regarding piping, extracting the bufnr and what do we do with gradle's runtime

rcasia commented 3 months ago

With those changes it looks alright and ready to merge.

asmodeus812 commented 3 months ago

With those changes it looks alright and ready to merge.

Not yet, almost. There are a few things to iron out.

rcasia commented 3 weeks ago

I will close this PR as #153 will fix the issue.

Thanks, this PR actually helped to get close to a solution.

asmodeus812 commented 3 weeks ago

@rcasia what about porting this to support coc, as the original pr ?

rcasia commented 3 weeks ago

Responded in https://github.com/rcasia/neotest-java/issues/75#issuecomment-2397574152