eclipse-jdtls / eclipse.jdt.ls

Java language server
1.81k stars 404 forks source link

Generic user configurable project/class path discovery interface #956

Open oakad opened 5 years ago

oakad commented 5 years ago

Presently (and please correct me if I'm wrong) JDT.LS can obtain information about the project source sets and their dependencies via 3 possible channels:

  1. Eclipse .project/.classpath files which are not properly documented and are not really useful for anything outside of Eclipse ecosystem (and even when using Eclipse various plugins offer better choices for project organization)
  2. Maven integration
  3. Gradle integration, which in my personal experience breaks more often than not. Fortunately, Gradle can produce the Eclipse files as well, returning us to p.1 above.

However, there are quite a few situation where one of the above options is not available. For example, Bazel (#543) is becoming rather common, and there are also other new build systems like Buck gaining prominence or outright custom build setups (which are sometimes absolutely necessary).

So it feels, that JDT.LS as well as the wider developer community may benefit from a properly documented external source set and dependency discovery mechanism, and even more so, if such a mechanism would not require modifications of the actual JDT.LS code or installation.

A far fetched idea: project level plugins

JDT.LS relies on an embedded Java compiler to do its job, thus it should have no problem loading some custom code from a predefined directory within the user's workspace.

An user may, then, provide a set of java files (in source form, for usability and better long term JVM compatibility) whereupon one of the specially named classes in this package (e.g. "JdtLsPlugin") implements or conforms dynamically (for Groovy style of operation) to ...jdt.core.IClasspathContainer or similar suitable interface.

This will enable users to efficiently connect the JDT.LS to their build system of choice - in many cases it will be enough to simply run the build tool with appropriate parameters and parse its standard output properly in a single custom Java file.

fbricon commented 5 years ago

JDT doesn't allow loading user classes into its own internal build process, so what you suggest is most likely not doable. We should definitely decouple jdt.ls core from maven and gradle and expose more extension points, to make integration with other build tools easier but, eventually, you'll need to provide Bazel or Buck or whatever build system support as an OSGi bundle, hooking into JDT.

oakad commented 5 years ago

I have looked into OSGi bundles but the whole process of making and deploying them made me immediately upset. :-)

Plan B, in this case, is to turn the ".project/.classpath" files into something like "javaLangServ.xml" with properly maintained and explicit schema + semantics and make it possible to put such files elsewhere, not within the source tree itself (kind of copying the way C++ language server is configured).

To give one example for the above: Bazel, by design (which I personally approve of), would not write any target files into the source directories. On the other hand, JDT expects to find ".project" files co-located with the source dirs, which may be deeply nested within the project.

That means, that it is impossible to write a proper rule for Bazel to produce configs for current JDT.LS. Some hacky scripts exists to achieve the outcome, but they are literally "not here, not there" when either Bazel or JDT are concerned (also, the heuristics used to write the .classpath files are usually pretty off the mark).

filippor commented 11 months ago

for a generic solution look at Build Server Protocol? https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/2984 https://github.com/eclipse-jdtls/eclipse.jdt.ls/issues/1907