ipfs-shipyard / java-ipfs-http-client

A Java implementation of the HTTP IPFS API
MIT License
536 stars 244 forks source link

Dual build definitions #215

Open odisseus opened 1 year ago

odisseus commented 1 year ago

I wonder what is the purpose of having two build systems (Ant and Maven) configured in the project? Maven is certainly more modern, and it offers automatic dependency management. However, the Github CI seems to be configured to use the Ant build.

Which system is actually used to build the release artifacts?

ianopolous commented 1 year ago

We prefer vendoring dependencies, and then building using ant as this means that even if all artifact servers go down or out of business, you can still build any historical commits. It also protects you against supply chain attacks on dependencies that are automatically updated. However we know others like maven so that's why we support it.

The release artifacts are built automatically by jitpack for those who use maven, and I think it uses the maven build.

odisseus commented 1 year ago

If you just want to keep the JARs in the repository for the purpose of vendoring, you don't have to stick to Ant. Maven actually can do it in a managed way (and makes it easy to switch back and forth between local and remote JAR repositories). By the way, lack of dependency management is not the only reason why Ant is considered obsolete.

As for vendoring the dependencies, your concerns are valid, but I don't see the point of doing that for this particular project. It only depends on libraries that are maintained by yourself and the IPFS crowd (such as multiaddr), and two really common libraries that are used for testing (which can be easily substituted if something bad happens). Besides, if you want to ensure that the build can be reproduced independently of any third-party servers, you need to vendor the build tool as well.

From the security point of view, sticking to the old versions of dependencies only makes sense if you actually analyse those dependencies before including them, and if you keep an eye on the security news in case somebody else discovers a critical vulnerability in them (e. g. the recent discovery in Log4J.)

ianopolous commented 1 year ago

In my opinion, automatic dependency management is an anti-pattern, because it encourages a proliferation of dependencies by making it too easy to add one. The endgame of this is the npm ecosystem which is horrendous. Manually adding jars means that, you have to think more and evaluate if you really need this dependency.

Log4j, for example, never affected any of my projects because I refused to include it after evaluation.

Maven is also slow, builds take much longer than ant on my machine. I'm ok with including maven here because others want to use it, and in that case it probably makes sense to use it in a conventional way.

odisseus commented 1 year ago

The sorry state of the NPM ecosystem was not caused by automatic dependency management. I believe the two main causes were the lack of a good standard library in Javascript, and massive compatibility issues between distributions by different vendors. Java has never had either of these problems.

For what it's worth, I fully agree that one should think before adding a new dependency, but this has nothing to do with the way existing dependencies are managed.

Maven might be slower than Ant, but it barely matters for small projects such as this one. I, for one, haven't noticed any difference.

ianopolous commented 1 year ago

That's an excellent point on the lack of a good standard library.

We're starting to get into psychology here, but people respond to incentives. And if something is harder to do, then I am more likely to think about whether it is worth doing or not.

Is the presence of ant causing issues for your bazel work?

odisseus commented 1 year ago

I think the psychology shouldn't matter at all. When I decide whether to add a new dependency to my project, I consider the objective benefits of having it (ready-made functionality, reducing own codebase, ...) against the potential drawbacks (additional bloat, possible bugs, having to adjust my existing code, ...) The (trivial) difficulty of making the necessary changes to the build does not come into consideration at all.

Also, as a maintainer, you have the power to veto any new dependency. This fact is not affected by the choice of the build system.

As a matter of fact, Ant doesn't make it harder to add a dependency. Just download the JAR and put it into the lib directory, and you're done. However, this approach complicates many actions related to managing the dependency, such as finding out its version or comparing the current version with a fresh one.

As for the Bazel build definition I'm working on (#216), it is completely unrelated to this discussion. I have created it mostly for my own purposes (for testing Bazel support in an IDE), and I wouldn't seriously suggest to adopt Bazel in this project (for one thing, Bazel build definitions are more cumbersome than either Ant or Maven).

However, Bazel has a couple of features I thought you might find interesting: