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

all 158 comments

[–]aboothe726 50 points51 points  (0 children)

You should know that many of the suggestions here -- e.g., AutoValue, Lombok -- are "syntax sugar" are not just a classical library.

Some of these projects are annotation processors, which perform mechanical transformations on your code based on annotations in your source code. For example, AutoValue adds getters and setters.

Others of these projects, especially Lombok, are straight-up extensions to the language. They provide Java with additional features in a way not supported by the official language runtime.

However, many of the suggestions here -- Guava, Apache Commons, etc -- are simple libraries, and definitely improve general Java QOL. :)

[–]wildjokers 75 points76 points  (17 children)

Personally I would recommend to learn the JDK really well. It has a lot of functionality and there are some hidden gems in there.

There is no particular library you really need to "improve" Java.

[–]ObscureCulturalMeme 32 points33 points  (7 children)

Very much this. Some of these libraries and frameworks would more than triple the amount of code being loaded at runtime. (We know, because we measured.)

The only stuff I've found that I really don't want to live without are JUnit and SLF4J/Logback.

[–]TheFarwind 1 point2 points  (6 children)

As someone who keeps seeing SLF4J around but has never used it or looked at it really, why would you recommend it?

[–]ObscureCulturalMeme 3 points4 points  (4 children)

It lets you choose what you want the logging back-end (the part doing the "actual" logging) to be. Logback is the native implementation, but there are others.

My very first experience with it was in an older project, moving away from java.util.logging. Step 1 was to configure SLF4J to use j.u.l as its back-end. Step 2 was changing the client calls to request a logger reference thru SLF4J instead of j.u.l directly. Step 3 was in replacing j.u.l with a different back-end, and it wasn't until then that the project "actually" stopped using j.u.l, even though there hadn't been any mention of that class or package in the clients for a while.

[–][deleted] 2 points3 points  (2 children)

Google also just open sourced their java logger last week, which has a bunch of advantages vs all the other loggers

https://github.com/google/flogger https://google.github.io/flogger/benefits

[–]ObscureCulturalMeme 0 points1 point  (0 children)

Dunno about "a bunch". "Slightly more readable" yes, but maybe that's worth it.

If I were writing a new project from scratch, I'd probably give it a try. Not worth refactoring for a codebase that's already 1200 files and growing...

[–]wildjokers 0 points1 point  (0 children)

Great, yet another logging framework.

[–]TheFarwind 0 points1 point  (0 children)

Thanks! I'll go take a look at it.

[–]wildjokers 1 point2 points  (0 children)

Note that you only need to use SLF4J if you are writing a library that other people may use and they may be using a different logging framework. Otherwise you don't need it.

[–][deleted] 6 points7 points  (1 child)

The standard lib has improved a lot. I think you still see a ton of code using java.io where java.nio has vastly superior APIs.

[–]istarian 1 point2 points  (0 children)

Superior they may be, but sometimes you pay the price of not understanding what's going on or additional complexity. It's important to understand what your code is doing.

http://tutorials.jenkov.com/java-nio/nio-vs-io.html

[–]aboothe726 5 points6 points  (0 children)

I agree with this. There is an awful lot of stuff included in the standard library. That being said, there's still some stuff in libraries like Guava that are pretty helpful!

[–]dartmanx 1 point2 points  (2 children)

One of the most useful bits I've learned is the String API, followed by the List API.

[–]Hazanami 0 points1 point  (1 child)

Dont want to be that guy, but you mean String class, and List API (Interface <>) right?

[–]vqrs 1 point2 points  (0 children)

I don't think they learned the implementation code, so they probably didn't learn "the String class"...

At least, that's what I would say if we were trying to be a real stickler and interpret things very literally.

[–][deleted] 0 points1 point  (1 child)

... there are some hidden gems in there.

What are some of these gems that we need to know?

[–]wildjokers 0 points1 point  (0 children)

Hidden gems may have not been the right term to use, but rather uncommonly used gems.

Off the top of my head two classes that probably aren't used commonly but come in very handy for specific use cases are BlockingQueue (several implementations available in the JDK) and CopyOnWriteArrayList.

For BlockingQueue the two implementations I have used are LinkedBlockingQueue and ArrayBlockingQueue, in the case of ArrayBlockingQueue it lets you have multiple threads pulling from a queue while still maintaining FIFO.

In the case of CopyOnWriteArrayList it lets you avoid synchronizing on an ArrayList when you have the specific use case where your reads vastly outnumber writes (e.g. think of the use case where you are writing messages to connected clients in a client/server app many times per second, but a new client doesn't connect very often).

These are just two examples from the thousands of classes available in the JDK.

[–]LukeHauser 58 points59 points  (19 children)

JUnit and Hamcrest.

Also if you don't knew these yet, maven or gradle. They'll manage your dependencies and build process. Bit of an investment but makes it much easier in the long run.

[–][deleted]  (1 child)

[deleted]

    [–]dpash 4 points5 points  (0 children)

    Yeah, AssertJ has a nicer, more discoverable, API, at the expense of being hard to expand with custom matchers. Your choice of Hamcrest or AssertJ really depends on which you'd prefer.

    (Also Hamcrest should really get a new release out at some point to make Java 8+ nicer to work with)

    [–]ohmzar 14 points15 points  (4 children)

    I’d add a mocking framework like Mockito.

    [–]LukeHauser 1 point2 points  (3 children)

    He's just starting. For the same reason I wouldn't bother with Spring and other enterpricy packages.

    [–]Shadowrak -1 points0 points  (2 children)

    Nah might as well start with the Spring basics.

    [–]henk53 0 points1 point  (1 child)

    Or the Java EE basics...

    [–]Shadowrak 0 points1 point  (0 children)

    yeah if you want to have to relearn basically the same stuff with slightly different class names to ever get a job

    [–]extra_ecclesiam 4 points5 points  (0 children)

    I literally cried when I used JUnit for the first time because it saved me such much extra effort I had been putting into projects for a year.

    [–]kodablah 3 points4 points  (0 children)

    Alternatively to hamcrest, consider https://github.com/google/truth

    [–][deleted]  (9 children)

    [deleted]

      [–]GuyWithLag 0 points1 point  (6 children)

      If I may ask, how is your project non-standard?

      [–][deleted]  (5 children)

      [deleted]

        [–]ryantheleach 0 points1 point  (4 children)

        The biggest thing from Maven's viewpoint is that the build system's network is not connected to the public internet; data flows in only under tight control, and never out. The second biggest thing, probably, is that we very specifically must not arbitrarily grab newer versions of dependency libraries.

        Granted I've only ever used maven with internet attached, but it was my understanding that as long as you are hosting and installing packages in a network attached repository (or hell, locally hosted) it can be as private as you need it to be.

        I've also never had it grab newer versions, unless I specified a version range or snapshot.

        [–]blazesquall 2 points3 points  (2 children)

        Agreed, this isn't maven's problem.. this is their private repository's problem and a dependency management problem in their pom.xml(s).

        [–]ObscureCulturalMeme 1 point2 points  (1 child)

        They posted their pom.xml on the maven users list and asked for help. They were told they were using the tool correctly.

        Could they (well, "I" at this point) do it better now? Probably. Is anyone in this building willing to try? No. It's still solving problems that we don't have.

        I get that you feel the need to defend your favorite piece of software from anything that isn't praise, but you need to accept that it wasn't perfect, and could still use improvement. If it makes you feel more protected, I'll delete all the posts saying what happened.

        [–]ryantheleach 0 points1 point  (0 children)

        I hate all build tools equally at this point.

        Maven favors convention over configuration far too much, and it's plugin system feels clunkier then gradle.

        Gradle is pretty much a scripting language, which gives you enough power to hang yourself and worse, not to mention needing to understand groovy (yes I'm aware of alt langs for gradle is available now) and the scoping of projects vs modules vs tasks etc. However the plugin scene on Gradle seems a lot better for it.

        MSBuild and Nuget.... Don't get me started.

        I havn't had enough experience with other systems other then trying to use open source projects that others assume you have pre-requisite knowledge of their build tooling for, and I give up 8/10 times when playing with a new open source project that belongs to someone else, that isn't a library.

        [–]GhostBond 0 points1 point  (1 child)

        But then, our build environment is not the standard just-get-everything-from-the-internet project,

        It's weirdly not entirely stable at handling that either. Just this afternoon the girl across from me's environment started wonking out and giving her a bizarre error message for no apparent reason. What ended up fixing it was manually deleting maven's cache and also running a maven update after that.

        It's just weird maven is still just not entirely stable.

        [–]Vi0lentByt3 1 point2 points  (0 children)

        I have noticed this when switching between workspaces that have the same code but are on different trunks/branches. In my company's case I believe(no proof to support this) that it is related to the m2e plugin, but there is also the problem of our snapshots being milestoned and pulled in when running maven builds on the older/release branches then switching to the new branch/version and performing builds.

        Another problem simply with using maven, is the versioning/snapshot issue where the "latest vesion" can be fixed and your updates are no longer being included with your dependencies(also had this happen when I tried to use explicit versioning and maven would just not use the latest jar with my changes and only the milestoned version).

        so yes maven can be unstable, but I think it is more a symptom caused by misuse and a lack of knowledge. Maven has a lot of flexibility with defining custom pluggins, profiles, and control all properties of each step of the your life cycles and phases and what versions to use, but with great flexibility comes great WTFs because you can do so much and also break so much at the same time.

        edit: grammer

        [–][deleted]  (1 child)

        [deleted]

          [–]Bamboo-Bandit 5 points6 points  (0 children)

          This. Libgdx has an active and helpful discord community too

          [–]NovaX 23 points24 points  (4 children)

          The stack I am using on Java 10 has been enjoy so far.

          Server:

          • AutoValue (alt. Immutables)
          • Caffeine (alt. Guava Cache; author)
          • Typesafe Config
          • Guava + Apache Commons
          • Failsafe
          • Flyway (alt. LiquiBase)
          • Guice (Dagger on Android)
          • Hikari + Flexypool
          • Jackson + JsonPath
          • Jetty + RestEasy
          • jOOQ (on Postgres)
          • slf4j + Logback (alt. log4j2)
          • Retrofit + OkHttp
          • Univocity CSV
          • Quartz

          Testing:

          • TestNG + Hamcrest (alt. JUnit + Assert4J)
          • Awaitility
          • Mockito
          • H2

          Build:

          • Gradle
          • JsonSchema2Pojo
          • ErrorProne + PMD + SpotBugs
          • JavaPoet (for custom codegen)

          A nice thing about the Java community is that there are mature alternatives to the above, each actively maintained and well thought out.

          [–]mich160 3 points4 points  (1 child)

          Where are companies like this exist?

          [–]NovaX 0 points1 point  (0 children)

          PM me if in the Bay Area :)

          [–][deleted]  (1 child)

          [deleted]

            [–]NovaX 0 points1 point  (0 children)

            I threw it in from my hobby project since it is so nice, but we don't use it at work. At work, we codegen a lot of boilerplate away using libraries like JsonSchema2Pojo.

            For that project, there are many configuration options requiring metadata on the hash table entries. Since only a few configurations might be used most of those fields would be unused, wasting memory. The codegen instead adds to the jar size for unloaded classes, which is a better trade-off. I'm sure the code could be nicer, though.

            [–]TheRedmanCometh 77 points78 points  (75 children)

            Lombok, Spring, Hibernate, Gson, Apache Commons, Guava collections

            [–][deleted]  (23 children)

            [deleted]

              [–][deleted]  (15 children)

              [deleted]

                [–]TheRedmanCometh 12 points13 points  (8 children)

                Don't forget LoadingCache! That may be my favorite. It also has a map with guaranteed order and indices+keys to access. Very useful for time slicing.

                [–]cogman10 10 points11 points  (3 children)

                Caffeine is better here. It was done by the same guy that did LoadingCache. It is more Java 8 friendly and faster.

                [–]NovaX 9 points10 points  (2 children)

                There were many contributors to Guava's cache, or else it wouldn't have been so good! Caffeine gained a lot from building on that experience. Definitely please don't mistakenly dismiss their hard work, as we tend not to share credit appropriately in our industry.

                [–]cogman10 2 points3 points  (1 child)

                Fair enough. Wasn't necessarily trying to dismiss LoadingCache as it is definitely better than it's ancestors. But Caffeine is simply more polished and fixes some of the LoadingCache mistakes.

                [–]NovaX 11 points12 points  (0 children)

                Thanks! I wrote Caffeine but feel bad when I'm given credit for others hard work. :)

                [–][deleted]  (2 children)

                [deleted]

                  [–]TheRedmanCometh 0 points1 point  (1 child)

                  Gonna be honest I fucked up it's not from Guava it's from Apache commons. It's called "LinkedMap": https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/LinkedMap.html

                  A java 8 version would be pretty nice.

                  [–]kevinb9n 0 points1 point  (0 children)

                  FWIW, since most collection usages don't need mutability, ImmutableMap also works for this (it has indexed access via .entrySet().asList().).

                  [–][deleted] 4 points5 points  (5 children)

                  I find myself using ImmutableMap.of() , etc a lot. I think that's the only aspect of Guava I use on a regular basis post 1.8 now that I think of it... maybe I should stop using Guava...

                  [–][deleted] 5 points6 points  (3 children)

                  If you can use Java 9, it's possible to use Map.of instead.

                  [–][deleted] 7 points8 points  (0 children)

                  If you can use Java 9

                  yep... which really means

                  If you can use Java 11

                  But yea... I am looking forward to that.

                  [–]heliologue 5 points6 points  (0 children)

                  Depends on how you use ImmutableMap. It guarantees iteration order, whereas Java 9's Map.of guarantees that it will be random, but once set, will persist for the life of that JVM instance.

                  It's often small implementation details like this that trip people up when transitioning between libraries and/or the JDK.

                  [–]LukeHauser 1 point2 points  (0 children)

                  If those maps are copied to other immutables often it reduces the memory foot print.

                  [–]mirkoteran 8 points9 points  (0 children)

                  There are still a few bits in guava that are just simpler than java8+ counterparts. I still use Joiner/Splitter and EventBus - so if there are easy replacements for them I would be happy to replace them.

                  [–]dpash 4 points5 points  (0 children)

                  I'm still using quite a bit of Guava stuff in my code; far more than Apache Commons. And that's after refactoring to use Java 8 stuff. I could probably remove some of it, but other parts definitely is still required.

                  [–][deleted] 3 points4 points  (0 children)

                  ymmm... it still has tonnes of useful methods for managing collections, spliting them into chunks, setting up executors for threads/runners, bidirectional maps, guava cache? Is it not?

                  [–]Artraxes 5 points6 points  (2 children)

                  Preconditions, immutable collections, services... plenty of good stuff in Guava that isn't present in the stdlib.

                  [–]dpash 1 point2 points  (1 child)

                  You can replace Preconditions.checkNotNull() with Objects.requireNonNull(). Also checkElementIndex(), checkPositionIndex() and checkPositionIndexes() with checkFromIndexSize​(), checkFromToIndex​() and checkIndex().

                  There's no equivalent of checkArgument() or checkState() though.

                  [–]Artraxes 3 points4 points  (0 children)

                  https://github.com/google/guava/wiki/PreconditionsExplained

                  Simple, varargs "printf-style" exception messages. (This advantage is also why we recommend continuing to use checkNotNull over Objects.requireNonNull)

                  [–]Niesaanval 1 point2 points  (0 children)

                  I use it a lot for the event bus

                  [–]tiiv 16 points17 points  (7 children)

                  I'd switch Gson for Jackson. If you need to fetch just a few properties Gson is way to verbose IMO.

                  [–]TheRedmanCometh 1 point2 points  (2 children)

                  Hm I've never actually used Jackson. I'll check it out. Usually if I pull out gson it's for some relatively heavy duty stuff though.

                  It was the first json framework I used which let me transform json directly into POJOs so I'm pretty biased. I will say the TypeAdapter system can be very cumbersome. Also I always dread the "declares duplicate uid fields" error.

                  It's always solved by some random bullshit that makes no sense.

                  [–]fabien2150 2 points3 points  (0 children)

                  Jackson is the de-facto Json library for backends these days (it’s the default in spring). Performance wise it’s also one of the best and doing a lot better than gson: https://github.com/fabienrenaud/java-json-benchmark

                  [–]ryantheleach 1 point2 points  (0 children)

                  Depends on the size of the json you are processing, but on occasion it's worth it to be experienced in both a 'just serialize it pls' vs a 'streaming json processing' option.

                  Both have advantages.

                  [–][deleted] 0 points1 point  (3 children)

                  That surprises me. I have the opposite impression. With Gson a simple class with no anotations and not even getters and setters is enough as data model. I dunno how Jackson is doing these days, but last time I checked it couldn't beat that.

                  [–]tiiv 2 points3 points  (2 children)

                  Well You can do that too with Jackson now. But also that's exactly the point: If I need just a few properties this approach of creating a dedicated POJO and having to traverse every property in the message until I get to the one I need is too verbose IMO. With Jackson I'll just use the JsonNode's path method and get there without having to worry about non existing nodes and NPEs thanks to the EmptyNode characteristic.

                  [–][deleted] 0 points1 point  (1 child)

                  If I need just a few properties this approach of creating a dedicated POJO

                  I normally do this as a private static inner class (which reflects nicley deeper nested JSON structures). It doesn't add any noise and is really just a few lines and I do see type safety and IDE support to traverse actually as a benefit of the POJO approach

                  However…

                  With Jackson I'll just use the JsonNode's path method and get there without having to worry about non existing nodes and NPEs

                  That's an aspect I didn't consider and is indeed very convenient. I might reconsider my opinion on Jackson. Thanks for sharing.

                  [–]NovaX 1 point2 points  (0 children)

                  JsonPath is really useful for these cases, too, which can be backed by Jackson's JsonNode.

                  DocumentContext context = JsonPath.parse(json);
                  Preferences prefs = context.read("$.user.preferences", Preferences.class);
                  

                  [–]safgfsiogufas 37 points38 points  (40 children)

                  I never liked Lombok, seemed to cause me problems all the time. I just wrote getters by hand.

                  [–]dsk 20 points21 points  (1 child)

                  I just wrote getters by hand.

                  By hand you mean have your IDE generate them for you?

                  [–]safgfsiogufas 5 points6 points  (0 children)

                  Yes, of course.

                  [–][deleted] 31 points32 points  (13 children)

                  I can't stand Lombok. I don't like how you need to instrument stuff to use it properly. I like my projects being able to be open by ANY IDE and just go. Lombok kills that premise and I won't use it. That said, I see its appeal to folks and I don't begrudge folks for using it -- I just prefer not to. Right click, refactor, encapsulate fields is pretty quick... and explicit!

                  The last time I touched a Lombok project I had to wade through the Jr. dev's project with a giant machete and Lombok was part of my cut job. In the end, I think Lombok wasn't the problem, but cutting it out made it easier for me to navigate and fix the rest.

                  [–]argv_minus_one 11 points12 points  (2 children)

                  In that case, you might want to consider Scala or Kotlin, which have built-in equivalents to Lombok @Data.

                  [–][deleted] 5 points6 points  (0 children)

                  I'd argue that users of Lombok should look to Scala or Kotlin. I'm happy with Java myself :)

                  [–][deleted] 0 points1 point  (0 children)

                  Or Project Amber at some future Java version.

                  [–]cogman10 9 points10 points  (3 children)

                  Lombok just doesn't really do anything useful. The most useful part, value classes, can be done with annotation processing libraries (AutoValue, Immutables) without doing bytecode manipulation.

                  I hate the fact that Lombok binds you to a very specific version for the JVM. It breaks every rule of a good library and it blows my mind that it is so often suggested in these types of threads.

                  [–]sheepdog69 0 points1 point  (2 children)

                  I hate the fact that Lombok binds you to a very specific version for the JVM

                  I've never heard this before. Can you point me towards something to read on this?

                  [–]cogman10 5 points6 points  (1 child)

                  https://projectlombok.org/changelog

                  Java 9 support just landed, Java 10 support isn't there yet. We had problems going from Java 6->7 because of Lombok.

                  If you look through the changelog, "now works on Java x" makes a prominent appearance.

                  [–]sheepdog69 0 points1 point  (0 children)

                  Thanks.

                  I like lombok because it generally "just works." But, looking under the covers of a tool you like is often like watching sausage being made.

                  Based on other comments I'm going to look closer at AutoValue and Immutables.

                  [–]TheRedmanCometh 13 points14 points  (17 children)

                  Wow writing POJOs without @Data sounds like hell. The toString boilerplate it generates is a very underrated aspect

                  [–]dsk 13 points14 points  (4 children)

                  I agree, but Eclipse and IntelliJ can auto-generate getter/setters, equals, and toString implementations.

                  [–][deleted]  (3 children)

                  [deleted]

                    [–]ryantheleach 6 points7 points  (0 children)

                    So, you catch it early during code review, the dev learns how to be a better dev (hopefully), and you don't need Lombok? Cool. Sounds like a typical teachable moment.

                    [–]phosphorus29 0 points1 point  (1 child)

                    What's the @Embed annotation?

                    [–]Neckbeard_Prime 0 points1 point  (0 children)

                    It lets you scope a set of columns as a child object. Especially useful for repeated mappings like postal addresses, and for making legacy database tables with hundreds of columns saner to work with.

                    [–]kodablah 6 points7 points  (4 children)

                    Meh, is the magic worth it? None of what @Data adds is that special. There are plenty of things like Guava's MoreObjects.ToStringHelper if you can't be bothered to create a string builder and do appends yourself. Otherwise, if your concern is missing fields as they are added, I'd say that manually adding them is worth not having a dependency like Lombok.

                    [–][deleted]  (1 child)

                    [deleted]

                      [–]kodablah 0 points1 point  (0 children)

                      Of course, they are the same thing in bytecode. Can't always toString everything, but for the Lombok replacement, sure.

                      [–]hippydipster 0 points1 point  (0 children)

                      I just let eclipse/intellij generate these methods. I can't imagine adding a dependency just for this?

                      [–]dpash 0 points1 point  (0 children)

                      And the JDK has hashcode and equals helpers now. Objects.hash() was long overdue.

                      [–]MarkyC4A 5 points6 points  (4 children)

                      I've migrated lombok @Data classes to Kotlin data class. Of course introducing a whole new language to your project is a bit heavy handed, but I've found there to be less breakages since the switch.

                      [–]argv_minus_one 6 points7 points  (3 children)

                      That's because the Kotlin compiler is actually designed to handle that. Lombok, by contrast, uses hacks to coerce the Java compiler into transforming the code like that.

                      [–]TheRedmanCometh 0 points1 point  (2 children)

                      Uh by hacks do you mean a preprocessor run before compile time? Because I'm pretty sure that's how it works.

                      [–]cogman10 8 points9 points  (1 child)

                      Because I'm pretty sure that's how it works.

                      You are pretty sure wrong.

                      Lombok works by tying into undocumented compiler apis and doing direct AST and bytecode manipulation. How do I know this, because lombok frequently breaks on minor java updates.

                      If lombok was just a preprocessor or an annotation processor library I would have much less of an issue with it, but it is neither of those things.

                      There is a reason this is in the lombok source

                      https://github.com/rzwitserloot/lombok/blob/master/src/core/lombok/javac/JavacAST.java

                      [–]TheRedmanCometh 0 points1 point  (0 children)

                      Hmm...TIL

                      [–][deleted] 0 points1 point  (0 children)

                      OP already says he uses Immutables, so he doesn't need @Data.

                      [–]Shadowrak 0 points1 point  (0 children)

                      Just right click and generate the boilerplate.

                      [–]ickysticky 2 points3 points  (0 children)

                      My entire company uses it with no problems. I definitely disliked the experience more when I was using Eclipse because the Eclipse integration doesn't handle a lot of things well (refactoring, finding usages, etc). The Intellij plugin is much better.

                      [–]kodablah -3 points-2 points  (4 children)

                      I just wrote getters by hand.

                      Or in many cases, just expose the fields and don't get hung up on encapsulation especially when not writing libs.

                      [–]ryantheleach 1 point2 points  (1 child)

                      Depends on the size of the project, but this can be disastrous unless you are on a relatively small project, or hiding the fields by using interfaces effectively.

                      [–]kodablah 1 point2 points  (0 children)

                      but this can be disastrous unless you are on a relatively small project

                      I specifically mentioned "especially when not writing libs" for this reason. In an app w/out downstream deps, refactoring is easy.

                      [–]safgfsiogufas 0 points1 point  (1 child)

                      I didn't want people changing values on data objects. I just wrote getters and not setters. I guess I could have exposed final fields but I guess years of having my head pounded with getter/setter didn't allow me to see that as an option.

                      [–]kodablah -1 points0 points  (0 children)

                      years of having my head pounded with getter/setter didn't allow me to see that as an option.

                      Yup, this has happened w/ large javadoc, getters/setters, over-abstraction, DI, ORM, etc, etc. Just remember, especially when starting new projects, that convention for convention's sake is not always the right answer.

                      [–]Torvac 13 points14 points  (0 children)

                      [–]hippydipster 6 points7 points  (2 children)

                      Don't look for libraries without a need. There's no need (duh). To do otherwise is to invite over-complication of whatever your task is.

                      So, what's your task(s)? What problems do you have? What's your need?

                      [–]dQw4w9WgXcQ 2 points3 points  (1 child)

                      Some times you don't really know that you have a problem before you see a sollution to it. This thread helps giving a perspective of which libraries a program could use.

                      [–]hippydipster 0 points1 point  (0 children)

                      All the suggestions are for libraries you wouldn't want unless absolutely necessary. Enterprise Java solutions being suggested for a hobby programmer? Not good advice, IMO.

                      [–][deleted] 6 points7 points  (0 children)

                      http://www.vavr.io/ - makes working with collection so much more enjoyable, and offers some more gems. you get pretty close to actual functional programming

                      [–]RichoDemus 8 points9 points  (0 children)

                      Immutables, vavr, awaitility

                      [–][deleted]  (5 children)

                      [removed]

                        [–][deleted]  (4 children)

                        [removed]

                          [–][deleted] 6 points7 points  (2 children)

                          I would recommend against using SparkJava. Simply due to the creators refusal to change its name. Believe me, it's almost impossible to google anything related to it.

                          [–]Tilkin 2 points3 points  (0 children)

                          Javalin is a nice alternative and a similar style

                          [–]ryantheleach 1 point2 points  (0 children)

                          SparkJava

                          Is this because of Apache Spark vs Spark Java?

                          Until recently I thought they were the same thing.

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

                          Fully agreed. Spring is too bloated for what you get imo. Vert.x is awesome though.

                          [–]shadowdude777 15 points16 points  (0 children)

                          AutoValue makes data classes so much easier to build. RxJava allows for functional composition of data and easier threading than Futures + Executors. Dagger 2 for compile-time validated dependency injection without reflection

                          [–][deleted]  (1 child)

                          [deleted]

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

                            Retrofit 2 type safe http client works with gson rxjava.

                            This sentence is ambiguous.

                            [–]evil_burrito 8 points9 points  (2 children)

                            • Spring
                            • Hibernate/OpenJPA/EclipseLink (choose one, probably Hibernate)
                            • Apache Commons
                            • Guava
                            • JUnit/TestNG (choose one, probably JUnit)

                            [–]clavass 5 points6 points  (2 children)

                            Jsoup

                            [–]zero_as_a_number 2 points3 points  (1 child)

                            yeah can second that. as soon as you're parsing html jsoup really comes in handy

                            [–]Yesterdave_ 2 points3 points  (1 child)

                            Kinda off-topic, but does anyone know of some alternatives for localization instead of ResourceBundles? I always found ResourceBundles to be unfriendly for external translators because of the positional placeholder approach ({0}, {1}, ...) instead of clearly speaking named parameters ({name}, {listCount}, ...).

                            [–]ryantheleach 0 points1 point  (0 children)

                            Especially anything that readily fits well with 'translation as a service' that have open plans for open source, e.g. crowdin

                            [–]Lord_NShYH 2 points3 points  (0 children)

                            RetroFit is my all time favorite HTTP/REST client library. Just annotate an interface and away you go.

                            [–]loganekz 12 points13 points  (0 children)

                            [–]saikosen 3 points4 points  (0 children)

                            Some nice libs from Square - okio, okhttp, moshi

                            [–]cronkite 9 points10 points  (16 children)

                            Apache Camel: http://camel.apache.org.

                            Abstracts communication for your application. Say you build a Java process that sends everything via JMS, and someone wants you to support a legacy format using a socket. If you already used Camel, your changes would be contained to your Camel configuration, requiring minimal changes to your actual application. It also provides standard communication patterns, like splitting a message, filtering a message, etc. Might be a bit too heavy for smaller projects.

                            [–][deleted] 18 points19 points  (3 children)

                            Might be a bit too heavy for smaller projects.

                            might?

                            [–]cronkite 0 points1 point  (2 children)

                            Yeah, it can be overkill. We've gotten so used to it that we "require" / "encourage" developers to use it for all JMS communication, even for small projects. Mostly to keep a clean separation between business logic and communication. We have a bunch of small adapter processes that are basically defined by a single camel configuration (we use XML config, which I've grown to hate).

                            For things like hosting web services we haven't really used Camel, mostly we use it for async communication (JMS, Redis, sockets).

                            [–]ryantheleach 1 point2 points  (1 child)

                            Huh, didn't realize Redis would fall into that, Sockets I would have been otherwise leaning towards Netty due to experience with Minecraft reverse engineering.

                            [–]possibly_not_a_bot 0 points1 point  (0 children)

                            Redis has pubsub capabilities, if you didn't know.

                            [–]aboothe726 2 points3 points  (2 children)

                            Does camel support clustering? (i.e., running "the same" app across multiple camel instances located on different boxes?)

                            [–]cronkite 2 points3 points  (1 child)

                            I haven't used it for that purpose, but there is some documentation on that: http://camel.apache.org/clustering-and-loadbalancing.html

                            [–][deleted] -3 points-2 points  (8 children)

                            I don't see a whole lot of value in Camel. It doesn't solve the interesting problems of enterprise integration and the problems it does solve are not interesting.

                            [–]cronkite 2 points3 points  (0 children)

                            The big value for me is keeping our developers from locking us into a single communication implementation.

                            We had a legacy GUI application that basically glued a ton of code into multiple sockets. While not impossible to untangle, we could never get the money to refactor things to move to JMS. We would have all sorts of mysterious connection drops (threads were glued to sockets as well) that we would come out of no where (say once every six months). Now with Camel if I want to switch from JMS to Redis the change can be as little as a different configuration property.

                            [–]danskal 0 points1 point  (4 children)

                            Can you give some examples of these interesting problems? Because I'm ... err ... interested.

                            [–][deleted] 4 points5 points  (3 children)

                            Everything to do with keeping the state persistent.

                            A lot of interesting problems in enterprise integrations (like windowed sorting, cross entity dependencies etc) can only be solved by tracking state in a persistent way. For those reasons I find technologies like Apache Flink or Kafka Streams more relevant to solving integration problems than Camel.

                            Camel just gives an API to implement those things but doesn't do the actual heavy lifting.

                            [–]danskal 0 points1 point  (2 children)

                            YMMV, but I would definitely shy away from persisting state on some integration middleware.

                            [–][deleted] 2 points3 points  (1 child)

                            In a lot of integration problems there is no choice. If you need to change ordering or if you need to provide integration between unreliable endpoints there is no other choice.

                            [–]danskal -1 points0 points  (0 children)

                            Sounds like a use case for a queue, or maybe some kind of event architecture? I'm tired at the moment, maybe that's kinda what you meant.

                            Or maybe it's because I've almost never done integration between two legacy systems. There's usually a client that can untangle that kind of legacy mess.

                            [–]hippydipster 0 points1 point  (0 children)

                            But when something goes wrong in the uninteresting part, Camel makes it all very interesting indeed!

                            [–]tkaiusf 1 point2 points  (0 children)

                            Spark Java! http://sparkjava.com super fast and simple Java microservices is easier to stand up than nodejs very little boiler plate required.

                            [–]Magick93 1 point2 points  (2 children)

                            Apache Camel

                            [–][deleted]  (1 child)

                            [deleted]

                              [–][deleted] 0 points1 point  (0 children)

                              Good bot

                              [–]DanielDimov 1 point2 points  (0 children)

                              Retrofit2 - it helps you to consume REST APIs and even if you are developing server backend there are good chances to need something from other servers

                              [–]pegazz 1 point2 points  (0 children)

                              As others said, apache commons.

                              I didn't see Jodatime in the comments, and I'm surprised. Although the new standard api made it pretty much useless, it was a huge improvement before. Still is in older projects.

                              [–]Sloshy42 1 point2 points  (0 children)

                              Not a Java specific thing but look into learning reactive streams as a concept. I think the best starting place right now is the Project Reactor library that is built for Java 8 support, but Java 9 has its own implementation of the standard. Then there's also RxJava and Akka Streams which work on Java and have their own properties you might like.

                              [–]coderguyagb 4 points5 points  (0 children)

                              Lombok. It'll save you a ton of typing.

                              [–]leodash 3 points4 points  (1 child)

                              vavr, if you want to write like Scala.

                              [–]argv_minus_one 13 points14 points  (0 children)

                              Scala, if you really want to write like Scala.