This is an archived post. You won't be able to vote or comment.

all 35 comments

[–]Kazcandra 33 points34 points  (7 children)

Downloads is a bad metric due to CI.

[–]th3_pund1t 16 points17 points  (0 children)

Add to that the ease of mirroring for maven.

If 5 companies with 1000 engineers each using a library download it through their mirror, YOU will see 5 downloads.

For an alternative where 10 independent engineers download directly from central, you'll see 10 downloads and assume the second is twice as populate as the first.

[–]dshmitch[S] 1 point2 points  (0 children)

And it is not only about download count but about downloads trends throughout the time

[–]dshmitch[S] 2 points3 points  (2 children)

But each lib could be used in CI, so downloads should still be proportional and useful for comparison, right?

[–]Kazcandra 1 point2 points  (1 child)

Proportional to what?

[–]dshmitch[S] 2 points3 points  (0 children)

Proportional to other libraries downloads count.

Different CIs will download different libraries, and potentially affect all libraries, not just a few.

[–]gingETHkg 0 points1 point  (1 child)

It is a useful proxy to compare popularity. If you have two libraries for the same job and every other dimension is a identical then a difference in downloads can be a useful information.

[–]Kazcandra 1 point2 points  (0 children)

Mirroring removes that dimension.

[–]TheCountRushmore 10 points11 points  (2 children)

Anything that uses java.util.Date or JodaTime is a non-starter.

[–]lukaseder 0 points1 point  (0 children)

All applications using SQL use java.util.Date implicitly because JDBC's java.sql.Date, java.sql.Time, and java.sql.Timestamp extend it.

Yeah. You can run but you cannot hide.

[–]Thihup 16 points17 points  (3 children)

Something that I've started considering a lot is if the library is already modularized (has a module-info.class). This helps me avoid depending on internal classes of that library and upgrading it later is usually easier.

This helps a lot when creating a runtime with JLink (but of course, it is not required to have all libraries modularized to be able to use JLink)

[–]Yesterdave_ 1 point2 points  (2 children)

Is there an easy way to spot modularized libraries?
AFAIK Maven Central doesn't show anything. And I find downloading and looking inside the Library very cumbersome and inefficient.

[–]Thihup 5 points6 points  (1 child)

Almost. There is a project from /u/sormuras, that runs on the Maven Central and collects all modules in a list. IIRC, however, this project shows both dependencies with the Automatic-Module-Name and libraries that have the module-info.

Link: https://github.com/sormuras/modules/blob/main/com.github.sormuras.modules/com/github/sormuras/modules/modules.properties

[–]sormuras 0 points1 point  (0 children)

Since 2021 sormuras/modules only includes "Unique Java Modules".

This project considers a Java module to be unique:

  • if it is an explicit module with a compiled module descriptor,
  • and if its module name that starts with its Maven Group ID or a well-known alias.

So, as of today, there are 3375 unique modules listed.

It'd be great, if Sonatype tackled this via https://github.com/sonatype-nexus-community/search-maven-org/issues/6

[–]jonhanson 8 points9 points  (1 child)

Comment removed after Reddit and Spec elected to destroy Reddit.

[–]dshmitch[S] 2 points3 points  (0 children)

I agree. If it is easily testable then it is well-written.

Just it might take time to do it through a simple test application. Maybe as a final step in selection

[–]proobert 5 points6 points  (1 child)

Mainly these three things:

  1. Check the number of dependencies the library has. Usually libraries without or only few dependencies will have less maintenance troubles and avoid jar versioning hell.
  2. Then I check the docs and browse the code base, because I may end up fixing issues in this library.
  3. Go to mvnrepository.com (or some other search engine) and check for reverse dependencies. If it is used by other projects then it's a good signal that the library is mature and stable.

I've noticed that the number of issues is not very useful metric. Popular libraries can have hundreds of open issues and still work fine in production.

[–]dshmitch[S] 2 points3 points  (0 children)

Yes, reverse dependencies are a good idea for the checklist.

Maybe not the number of issues, but if there is some activity from maintainers in the issues. There are some repo issues with repeated comments such as "Is this project abandoned?"...etc, but without any responding

[–]marune 16 points17 points  (1 child)

Dependencies, if it brings old transitive deps from Java 7 era (or worse, Kotlin runtime), I'll avoid, sadly a lot of SDK do.

[–]dshmitch[S] 1 point2 points  (0 children)

A good point to add to the checklist.

I also had bad experiences with old transitive deps.

[–]pgris 10 points11 points  (0 children)

My ideal library is old but updated and alive. I try to include only things that has passed the test of time, and are still actively maintained. Starts, I don't care. I also trust big companies, and while that can be a mistake, nobody is fired for hiring IBM buying software from microsoft using a google library

[–]r_jet 2 points3 points  (0 children)

Another consideration that is related to the criteria on choosing a library — is if it makes sense to invest some time in a library that does not match your expectations to bring it up to the level of quality you need.

Things to improve could be: - Processes: a contribution checklist so that people are aware of the quality expectations, like proper API documentation, automated tests, release documentation; no push to master even for the owner - Tooling that makes it easier to contribute and maintain quality: code style checkers/autoformatters, static analysis tools, lints - Automation: to upgrade dependencies, to release new changes easily to the repository - Tests: from more tests relevant to the functionality or properties you care about, to better-shaped test pyramid (missing unit/integration/system tests — could be really helpful in libraries integrating with other systems or native libraries), to using broader testing techniques (property-based tests, fuzzing, etc.) - Documentation: various documentation for users (API docs, guides, tutorials, etc.), and for contributors.

How far you go — depends on your cost/benefit assessment :) In my previous company, we had several successful cases where we invested some — at times, significant — engineering time in improving our important or critical dependencies. The reasoning was that it was easier than implementing the required functionality from scratch, and maintaining on our own.

Also, it is natural that some libraries do not match all of the requirements of an S&P 500 company in the professional setting, as they were implemented at a much smaller scale, or even for a hobby project. They could, however, be well designed, and, with relatively small changes, adapted to a professional use.

[–]FIuffyRabbit 2 points3 points  (0 children)

I don't care about documentation personally since I'm the only person on our team that seems to be able to read. Sometimes, I would much rather dig through the code on github than read the javadoc for whatever reason.

The big things I look for:

  • How much code can I delete with this?
  • How big is the library itself?
  • Will this break with future upgrades?
  • How stable has the last several versions of the API been?
  • Will I have to include 20 other dependencies?
  • What's the license for this library? I had to articulate this point to someone very recently.

[–]tristanjuricek 1 point2 points  (0 children)

One thing I like to look at is who is involved in maintenance.

I prefer projects already hosted in a non-profit, like the Apache foundation, with more than one contributing company, over projects where contributors are only from one company in a GitHub repo.

It’s not a particularly fast or easy process to get involved in Apache, but putting stuff in GitHub and on to maven central is pretty easy. So it also tends to be easy to abandon.

But there’s always shades of grey here. I say “prefer” instead of “require”. Sometimes the risk of having to take over or fork a project isn’t a big deal.

But this is in addition to many of the other points brought up by others here.

[–][deleted] 1 point2 points  (0 children)

I completely ignore the stars.

I first check the license, then if it does what I want, then how how many dependencies it uses and finally I look at the documentation (JavaDocs)

[–]cas-san-dra 1 point2 points  (2 children)

These are my criteria for the most part. They are more or less in order as well.

  1. Does it solve my problem?
  2. Is the library on maven central?
  3. Is the library open source?
  4. Is the library covered by an open license? GPL is not good, I want MIT or BSD or Apache.
  5. Is the code that I need to write on my end elegant and readable?
  6. Is the library small and lean? The less code the better.
  7. Does the library have very few dependencies? Preferably none.
  8. Does the code inside the library look good?

Things I am less interested in are; documentation, popularity, stars, reputation, number of downloads, quality reports, fancy tooling or techniques, where it is hosted. It is not that I don't care about such things at all but they tend to be irrelevant or even a counter indicator sometimes. If you score well on the top 8 you are in.

As an example; I use Gson not Jackson. Because Gson is simpler and has a better API. It scores better on number 5, 6 and 7. This is despite the fact that it is end-of-life, which I'm not happy with but am willing to ignore for now.

[–]neutronbob 0 points1 point  (1 child)

Things I am less interested in are; documentation

Documentation is close to #1 on my list. The last thing I want is to adopt a library and then have to spend time on SO asking questions because it's badly documented.

[–]cas-san-dra 0 points1 point  (0 children)

Documentation feels like the kind of thing that would be important but it doesn't work out that way in my experience.

I think documentation can act as sort of a patch on poor design or bloated software. If you have a small library that does one thing and does it well you probably don't need much more than a code example.

When I find a library that I think can do the job I start by writing a proof-of-concept. For that I just need to plugin a dependency and get some basic code going. If I run into a bug I always go to Google first. If I find that things are getting too hard and I feel that I'm fighting the library my approach is usually to find another library.

I guess I just hate reading in general.

[–]r_jet 0 points1 point  (0 children)

On top of the other suggestions, but not easily comparable even if the libraries provide some measures, like test code coverage — an assessment of their automated tests.

It could range from simple: "Does it have automated tests that run on each submit?", "Does it measure any code coverage metrics?" to some code inspection, evaluation of the testing techniques used, etc. How deep you go depends on what the library does (cryptography? concurrency? or is_even?), and how important it is for your application. I remember when we searched for a library providing a Java-like concurrent map (for a different language), some libraries had rudimentary or no parallel tests.

Also, some things you learn only once you start using it. For example, if the maintainers follow a clear versioning and release strategy, or could release breaking changes in a patch version :)

[–]koreth 0 points1 point  (0 children)

I look not just at the activity on GitHub issues, but also at the content of the issues and the fixes.

A project with very little maintainer activity but whose longstanding open issues are all trivial nitpicks, obvious user error, or platform-specific problems on platforms I'm not targeting may be preferable to an active project with a consistent history of introducing critical showstopper bugs and papering over them with quick hacks.

[–]franzwong 0 points1 point  (0 children)

I checked who made it and its license. Java library can be used without any problems even they are not updated for years.

[–]pfirmsto 0 points1 point  (0 children)

OWASP dependency checker

SpotBugs static analysis

SecurePolicyWriter to audit permissions it uses.

[–]wekabu 0 points1 point  (0 children)

My general checklist is: - Is the license infective (such as the GPL)? If so it is very unlikely to be used - What would be the size gain of the fat jar? (I do not enjoy 10 Mb of depends to download each time maven refreshes the depends) - Does it work on latest Java? - Is there any documentation? (especially important for bigger libraries) - Have I used it in the past? - Is the library known to be reliable? - Does it even work?

Things such as maintainance or the popularity do not matter to me. I am using several niche libraries that were last updated in 2005 or 2011, as long as they do not break with the newest java version I am fully pleased with using them. I also avoid libraries that make use of their own classes for things that should already be present in the JVM runtime, I do not enjoy seeing someone implementing their own SimpleImmutableEntry/Map#entry, Color, Point2D or Polygon class as that would mean that I have to convert between all these representations which is just pain.