Coder Social home page Coder Social logo

jresolve-cli's Introduction

jresolve-cli

Command line tool for resolving dependencies on the JVM.

NOTE: This is a very early draft of this tool. The social contract is that if you use it and find it useful, I will be available to help you adapt to any changes. But I will still make breaking changes if I have to. Expect rough edges.

Installation

There are packages generated in CI which can be added to your path. Click on the latest workflow run and there should be downloads at the bottom of the page.

For M1 Macs, GitHub does not provide an executor with a compatible CPU, so I'm building those locally for now. Shoot me a message and I can send you an exe or you can build locally if you have maven, just, and native-image on your machine.

For Mac and Linux you can install a version that depends on having Java 21+ installed with the following command.

bash < <(curl -s  https://raw.githubusercontent.com/bowbahdoe/jresolve-cli/main/install)

Very much a work in progress.

Usage

The concept is that you provide a "package url" for every dependency you want to have at runtime. The tool will then output a path containing those dependencies as well as any transitive dependencies.

Simple Dependencies

For a simple dependency like commons-collections4, you will get a path to its jar.

jresolve pkg:maven/org.apache.commons/[email protected]
/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar

Transitive Dependencies

For dependencies like jdbi3-postgres, which have dependencies of their own, you will get a path containing the jars of the entire dependency tree.

jresolve pkg:maven/org.jdbi/[email protected]
/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/com/google/errorprone/error_prone_annotations/2.22.0/error_prone_annotations-2.22.0.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/checkerframework/checker-qual/3.38.0/checker-qual-3.38.0.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/io/leangen/geantyref/geantyref/1.3.14/geantyref-1.3.14.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/jdbi/jdbi3-core/3.41.3/jdbi3-core-3.41.3.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/jdbi/jdbi3-postgres/3.41.3/jdbi3-postgres-3.41.3.jar

Multiple dependencies

If you have more than one dependency, you can provide them one after another on the command line.

jresolve pkg:maven/org.apache.commons/[email protected] \
         pkg:maven/org.junit.jupiter/[email protected]
/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/junit/platform/junit-platform-commons/1.10.1/junit-platform-commons-1.10.1.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/apiguardian/apiguardian-api/1.1.2/apiguardian-api-1.1.2.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/opentest4j/opentest4j/1.3.0/opentest4j-1.3.0.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar:/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/junit/jupiter/junit-jupiter-api/5.10.1/junit-jupiter-api-5.10.1.jar

Or you can put them all into a file separated by newlines.

deps:

pkg:maven/org.apache.commons/[email protected]
pkg:maven/org.junit.jupiter/[email protected]

Then you can use that as an argfile. Put @ before the filename and the args will expand out.

jresolve @deps

Multiple sets of dependencies

If you have sets of dependencies which are available at different points in your project's lifecycle, you can use multiple argfiles for them.

Compile Time

jresolve @deps/compile

Run Time

(includes both compile and runtime dependencies)

jresolve @deps/compile @deps/runtime

Usage from JVM Tools

If you want to pass the result of a dependency resolution to tools like javac you have a few options

The first is that, if your shell supports it, you can use the output of the tool inline with an invocation.

java --class-path $(jresolve @deps) src/Main.java

The more portable option is to run the tool and put the results into a file.

jresolve --output-file build/argfiles/runtime @deps/compile @deps/runtime

And then use the argfile when invoking the tool.

java --class-path @build/argfiles/runtime src/Main.java

Most tools in the JVM support expanding arguments from argfiles with @, but there are some exceptions. A notable one is jshell, for some reason.

Including file paths

If you need to include a path to a specific file or folder in your final --class-path or --module-path you can do that in one of two ways.

The first is to include it as-is. Anything that cannot be parsed as a URL will be forwarded directly to the final path.

jresolve pkg:maven/org.apache.commons/[email protected] some/other/path
/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar:some/other/path

The second is to supply it as an argument with a file:/// url. Keep in mind that such urls are always absolute paths and as such likely won't be portable to other machines.

jresolve pkg:maven/org.apache.commons/[email protected] file:///an/absolute/path
/Users/emccue/.jresolve/cache/https/repo1.maven.org/maven2/org/apache/commons/commons-collections4/4.4/commons-collections4-4.4.jar:/an/absolute/path

Including remote files

If you need to include files hosted on some remote source, there is limited support for that. If you provide an https:// url, that file will be downloaded and put onto the final path.

There is no support for, and no plans to support, files hosted via other protocols like tcp or http or to support getting files behind urls which require authentication.

jresolve https://piston-data.mojang.com/v1/objects/5b868151bd02b41319f54c8d4061b8cae84e665c/server.jar

Usage to make a project

If you are curious what it would look like to make an actual project using this and other JVM tools instead of a full build system, there is a demo of that here.

Getting IDEs to recognize what dependencies are made available is unsolved, but definitely solvable.

Custom maven repositories

If you make a json file like this

{
  "jitpack": {
    "url": "https://jitpack.io"
  }
}

You can supply it to the tool

jresolve --maven-repositories-file repositories.json @deps

And include the repository to use on a specific coordinate.

pkg:maven/com.github.thegatesdev/[email protected]?repository=jitpack

Custom maven repositories with authentication

To use a repository that requires username + password authentication, include an object with those credentials in your json file.

{
  "jitpack": {
    "url": "https://jitpack.io",
    "authentication": {
      "username": "bob",
      "password": "123"
    }
  }
}

Anticipated Questions

Why package urls?

It is annoying to write pkg:maven in front of everything. It also makes the syntax for overriding properties of dependencies a bit wonky - ?repository=jitpack and such.

Those are the downsides. The upside is that it is possible to support other kinds of dependency declarations. The underlying resolver is based on tools.deps and is agnostic to maven. It should be relatively straightforward to add support for git dependencies (without going through jitpack), local dependencies (not just files, but locally developed projects with their own dependency manifests), and whatever else is relevant.

Why not just use maven/gradle/ivy

Short answer

  • Maven lags behind in its support for JVM tools, this approach is more generically composable. Tons of pros and cons to that.
  • Gradle is similar, but also ties itself to Groovy and Kotlin. I'm pretty sick of having to tell people to learn two languages in order to learn Java.
  • Ivy is technically very generic, but it suffers greatly from being made in the days of XML and Ant.
  • I wanted to make something which is directly usable with the upcoming Multi-File Source-Code Programs
  • I want to make the "command line flow" actually practical instead of a strange joke we play on early students before saying "sike!" and giving them maven or gradle.

Elaboration available upon request.

jresolve-cli's People

Contributors

bowbahdoe avatar

Stargazers

Taketoday avatar Stephan Renatus avatar Adam Gent avatar Oliver Jan Krylow avatar Christofer Sjögren avatar David Alayachew avatar  avatar Suresh avatar Ron Pressler avatar Harald avatar Erlend Bleken avatar Rafael Dias avatar Jean-Christophe Gay avatar Franck Arnulfo avatar robb avatar Volker Gronau avatar Nikos Vaggalis avatar Nam V. Do avatar Serkan ÖZAL avatar chan avatar Shantanu Kumar avatar Alfonso² Peterssen avatar Mike Hearn avatar Adriano Machado avatar Darren Bell avatar

Watchers

Volker Gronau avatar  avatar  avatar

jresolve-cli's Issues

Cannot run downloaded binary on Ubuntu 20.04

I ran into the following after I tried the first binary download on AMD64 Ubuntu 20.04:

$ jresolve pkg:maven/org.apache.commons/[email protected]
jresolve: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by jresolve)
jresolve: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by jresolve)

However, when I built it locally with just exe (GraalVM-ce-21) it worked fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.