javavscode icon indicating copy to clipboard operation
javavscode copied to clipboard

How to tell the extension about dependencies that do not come from Maven or Gradle?

Open bowbahdoe opened this issue 1 year ago • 17 comments

This is one part a question and one part, I assume, a feature request.

How can I teach the extension about dependencies that I am going to put on the classpath/modulepath which do not come from a pom.xml or build.gradle definition?

My situation is that I am generating files which have the path I intend to use and supplying those to java/javac via an argfile.

Example:

jresolve --output-file deps pkg:maven/com.fasterxml.jackson.core/[email protected]

deps:

/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.15.2/jackson-annotations-2.15.2.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.15.2/jackson-core-2.15.2.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.15.2/jackson-databind-2.15.2.jar
java --class-path @deps src/Main.java

Though I can easily imagine someone else wanting to just use a jar they have on their filesystem or something similar.

bowbahdoe avatar Nov 09 '23 21:11 bowbahdoe

You need to add these to the gradle file.

robaho avatar Nov 17 '23 02:11 robaho

@robaho There is no gradle file

bowbahdoe avatar Nov 17 '23 18:11 bowbahdoe

The oracle plugin requires using gradle or maven.

robaho avatar Nov 17 '23 23:11 robaho

@robaho That's...thats what this issue is about...

bowbahdoe avatar Nov 18 '23 04:11 bowbahdoe

Then I would rephrase your question as a feature request to have the extension support non managed projects.

robaho avatar Nov 18 '23 04:11 robaho

Though I can easily imagine someone else wanting to just use a jar they have on their filesystem or something similar.

This. I'd like to put a project-local lib/ directory on the module path, for example. Which should result in arguments like

  • javac --module-path lib at compile-time and
  • java --module-path lib run-time respectively.

sormuras avatar May 09 '24 04:05 sormuras

@bowbahdoe you can add "VM Options" in the "Run Configuration". For example: -cp lib/junit-4.13.2.jarthis would enable JUnit lib in a standalone non-managed project. After this all the autocomplete features and other features would start working for your project.

Achal1607 avatar May 13 '24 10:05 Achal1607

@Achal1607 Okay, I tried editing a settings.json and the run configurations options. No dice.

image

bowbahdoe avatar May 13 '24 13:05 bowbahdoe

FWIW, I would suggest to use absolute paths.

lahodaj avatar May 13 '24 13:05 lahodaj

@lahodaj That makes a run configuration pretty darn non-portable. I guess fine if its generated by a tool, but not if i'm doing it manually.

It does work though with an absolute path. Go to definition doesn't and it doesn't work reading args from an argfile, but i guess its a start?

so that works with a module path and a class path

--add-modules dev.mccue.json --module-path /Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/dev/mccue/json/2023.12.23/json-2023.12.23.jar
image
--class-path /Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/dev/mccue/json/2023.12.23/json-2023.12.23.jar

bowbahdoe avatar May 13 '24 17:05 bowbahdoe

Regarding "Go to definition doesn't" - could you please elaborate? I have some sample source using multi-source launcher. I can navigate (Ctrl-click or F12) across various source files that refer to each other. When I try to use GSon, I can navigate to the GSon class - if there are no sources, then it will "decompile". If there is a source bundle (I use gson-2.10.1.jar as the binary, and next to it, I have the source bundle: gson-2.10.1-sources.jar), then it navigates to the sources from the bundle. (Plus other things work better when the source bundle is available.)

lahodaj avatar May 13 '24 19:05 lahodaj

if there are no sources, then it will "decompile". If there is a source bundle (I use gson-2.10.1.jar as the binary, and next to it, I have the source bundle: gson-2.10.1-sources.jar)

I mean it does not do the first behavior. I haven't downloaded a sources jar to check the 2nd behavior but i can in a bit.


If you want to work with the same clay I am, the tool I made to resolve dependencies is here

https://github.com/bowbahdoe/jresolve-cli/releases/download/v2024.05.10/jresolve.jar

You can run it with java -jar jresolve.jar and give it a series of "package urls" like you find on the sonatype site

So example incantations:

$ java -jar jresolve.jar pkg:maven/com.google.code.gson/[email protected]
/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar
$ java -jar jresolve.jar --print-tree pkg:maven/com.google.code.gson/[email protected]
com.google.code.gson/gson 2.10.1
$ java -jar jresolve.jar --output-directory libs pkg:maven/com.google.code.gson/[email protected]
$ ls libs
gson-2.10.1.jar
$ java -jar jresolve.jar --print-tree pkg:maven/com.fasterxml.jackson.core/[email protected]
com.fasterxml.jackson.core/jackson-databind 2.17.1
  . com.fasterxml.jackson.core/jackson-annotations 2.17.1
  . com.fasterxml.jackson.core/jackson-core 2.17.1
$ java -jar jresolve.jar pkg:maven/com.fasterxml.jackson.core/[email protected]
/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-databind/2.17.1/jackson-databind-2.17.1.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-core/2.17.1/jackson-core-2.17.1.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/fasterxml/jackson/core/jackson-annotations/2.17.1/jackson-annotations-2.17.1.jar
$ java -jar jresolve.jar --print-tree pkg:maven/com.fasterxml.jackson.core/[email protected] pkg:maven/com.google.code.gson/[email protected]
com.fasterxml.jackson.core/jackson-databind 2.17.1
  . com.fasterxml.jackson.core/jackson-annotations 2.17.1
  . com.fasterxml.jackson.core/jackson-core 2.17.1

(if package urls in a file)

$ java -jar jresolve.jar --print-tree @libs.txt
pkg:maven/com.google.code.gson/[email protected]
com.fasterxml.jackson.core/jackson-databind 2.17.1
  . com.fasterxml.jackson.core/jackson-annotations 2.17.1
  . com.fasterxml.jackson.core/jackson-core 2.17.1

You get the idea.

My goal, which overlaps with the "I just downloaded a jar" folks, is to make that "work" here

bowbahdoe avatar May 13 '24 22:05 bowbahdoe

Hm, I've done something like this:

java -jar jresolve-cli-2024.05.10-uber.jar pkg:maven/com.google.code.gson/[email protected]
.../.jresolve/cache/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar

In the VS Code, I've specified VM Options as:

--module-path .../.jresolve/cache/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar --add-modules com.google.gson

and have a source like:

package test;

import com.google.gson.Gson;

public class TryGson {

    Gson g = new Gson();

}

Pressing F12 on any instance of Gson takes me to the decompiled source. If I copy the gson-2.10.1-sources.jar to the .../.jresolve/cache/https/repo1.maven.org/maven2/com/google/code/gson/gson/2.10.1/ directory, then F12 jumps to the sources.

Could you please provide reliable reproducible steps? Thanks!

lahodaj avatar May 14 '24 08:05 lahodaj

@lahodaj Okay, so it worked with GSON on my end too. My guess is something in the decompiler silently fails with some byte code level 8 < x <= 21. Thats workable.

Now the question is how can tools/users who just download deps directly best inform vscode of those paths. Relative paths and argfiles both not working is a bummer + editing json is unideal (but probably workable; at least for a tool. For a human...)

bowbahdoe avatar May 15 '24 04:05 bowbahdoe

I am looking into supporting relative paths(*) and argfiles. It is a bit tricky, but probably doable. Note that there are limits on sharing the configuration - the path separator is different between Windows and Linux/Mac, so sharing the configuration across platforms is not very easy.

(*) there is the obvious question "relative to what". There are many possible answers, but I think I'll try to go with "the enclosing workspace folder", if I can.

(As a side note, I would say the lack of source (or at least javadoc) bundles is likely to have a detrimental ongoing effect on the usability of the setup. But, it is difficult for the extension to download the source bundle in this setup, where there is no project description/metadata, and where all there is is a collection of jars with indeterminable origin.)

lahodaj avatar May 15 '24 08:05 lahodaj

As a side note, I would say the lack of source (or at least javadoc) bundles is likely to have a detrimental ongoing effect on the usability of the setup.

Well, for the use cases we are talking about

  • People manually downloading jars could manually download sources+javadoc jars too. They probably won't, but they could.
  • Tools could be told to dump source + javadoc jars into the same / related directories. You got it working with gson
  • If you really wanted to be clever, jars often have a pom.xml in them that you could use to infer where to get that stuff.

So i'd say thats a workable tradeoff.

there is the obvious question "relative to what".

Not too insane to maybe make people write $WORKSPACE_ROOT/libs or something similar, though that one damn slash is annoying since otherwise just libs would be portable as a cli arg.

Note that there are limits on sharing the configuration - the path separator is different between Windows and Linux/Mac, so sharing the configuration across platforms is not very easy.

Known and noted.

bowbahdoe avatar May 15 '24 13:05 bowbahdoe

As a side note, I would say the lack of source (or at least javadoc) bundles is likely to have a detrimental ongoing effect on the usability of the setup.

Well, for the use cases we are talking about

* People manually downloading jars could manually download sources+javadoc jars too. They probably won't, but they could.

* Tools could be told to dump source + javadoc jars into the same / related directories. You got it working with gson

* If you really wanted to be clever, jars often have a pom.xml in them that you could use to infer where to get that stuff.

So i'd say thats a workable tradeoff.

I have no doubt it is a workable tradeoff. What I am trying to say is that if you are serious about developing using this mode, someone needs to work that out. And, given there is (per my understanding) no "standardized" configuration in tools like jresolve, but rather just free-form command line invocations (mostly analogous to wget), the tool doing the download is probably the only place which can ensure the source bundle is available with sufficient reliability.

(Looking for pom.xml is nice, as long as the only place one wants to support is the one well-known repository. Note this is different for Maven - the extension can read the Maven configuration, as that is declarative and defined, and can do what is needed based on that.)

lahodaj avatar May 15 '24 13:05 lahodaj

Merged https://github.com/oracle/javavscode/pull/173. So closing this issue. If you have any other queries or issues please feel free to open an issue.

Achal1607 avatar Jun 17 '24 12:06 Achal1607