tool / 77

Java Libraries

The libraries that today's Java developers actually use — frameworks, HTTP, JSON, database, testing, security.

All local
27/27
Frameworks3
Spring Boot

The dominant Java framework for building production applications. Convention over configuration, autoconfigured starters, embedded server.

when to use
Almost any backend service. Web APIs, batch jobs, message consumers.
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring.io/projects/spring-boot
Quarkus

Kubernetes-native Java framework with fast startup and low memory. Compiles to native via GraalVM.

when to use
Cloud-native services where cold start matters. Serverless functions in Java.
<dependency>
  <groupId>io.quarkus</groupId>
  <artifactId>quarkus-rest</artifactId>
</dependency>
quarkus.io
Micronaut

Compile-time DI framework — no runtime reflection. Fast startup, low memory.

when to use
Microservices, especially serverless. Alternative to Spring Boot for performance-critical services.
<dependency>
  <groupId>io.micronaut</groupId>
  <artifactId>micronaut-http-server-netty</artifactId>
</dependency>
micronaut.io
HTTP Clients2
OkHttp

Square's HTTP client. Connection pooling, transparent GZIP, response caching, HTTP/2.

when to use
When the built-in java.net.http.HttpClient feels too low-level or you want connection-level control.
OkHttpClient client = new OkHttpClient();
Request req = new Request.Builder()
    .url("https://api.example.com")
    .build();
try (Response res = client.newCall(req).execute()) {
  System.out.println(res.body().string());
}
square.github.io/okhttp
Retrofit

Type-safe HTTP client built on OkHttp. Define an interface, Retrofit generates the implementation.

when to use
Calling REST APIs from Java/Android with strongly-typed request/response models.
interface UserApi {
  @GET("users/{id}")
  Call<User> getUser(@Path("id") String id);
}
Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.example.com/")
    .addConverterFactory(JacksonConverterFactory.create())
    .build();
UserApi api = retrofit.create(UserApi.class);
square.github.io/retrofit
JSON2
Jackson

The standard Java JSON library. Fast, configurable, supports streaming and tree-model APIs.

when to use
Almost every Java app that touches JSON. Default in Spring Boot.
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(user);
User back = mapper.readValue(json, User.class);
JsonNode node = mapper.readTree(json);
github.com/FasterXML/jackson
Gson

Google's JSON library. Simpler API than Jackson but slower. Great for quick scripts.

when to use
Smaller projects, Android, when you want a simpler API than Jackson.
Gson gson = new Gson();
String json = gson.toJson(user);
User back = gson.fromJson(json, User.class);
github.com/google/gson
Database4
Hibernate

The original Java ORM. Implements JPA. Mature but heavyweight; LAZY loading footguns.

when to use
Spring Boot apps that need an ORM. When you have rich object graphs and want JPA portability.
@Entity
public class User {
  @Id @GeneratedValue Long id;
  String email;
}
EntityManager em = ...;
User u = em.find(User.class, 42L);
hibernate.org
jOOQ

Type-safe SQL DSL. Generate Java classes from your schema, then write SQL with the IDE's full power.

when to use
When you want SQL without an ORM, with compile-time safety. Avoids the JPA cognitive overhead.
Result<Record> result = create
    .select()
    .from(USERS)
    .where(USERS.ACTIVE.eq(true))
    .orderBy(USERS.NAME)
    .fetch();
jooq.org
HikariCP

The fastest JDBC connection pool. Default in Spring Boot.

when to use
Always — you don't think about it, but it's there.
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost/mydb");
config.setMaximumPoolSize(20);
HikariDataSource ds = new HikariDataSource(config);
github.com/brettwooldridge/HikariCP
Flyway

Database migrations as numbered SQL files. The de facto standard.

when to use
Any service with a database. Run migrations on app startup or in CI.
// db/migration/V1__create_users.sql
CREATE TABLE users (
  id BIGSERIAL PRIMARY KEY,
  email TEXT UNIQUE NOT NULL
);

// runs automatically with spring-boot-starter-flyway
flywaydb.org
Testing4
JUnit 5

The standard Java testing framework. Annotations, parameterized tests, dynamic tests, extensions.

when to use
Every Java test suite written today.
@Test
void shouldAddNumbers() {
  assertEquals(5, calc.add(2, 3));
}

@ParameterizedTest
@ValueSource(ints = {1, 2, 3})
void positive(int n) { assertTrue(n > 0); }
junit.org/junit5
AssertJ

Fluent assertions that read like English. Massively better error messages than JUnit's built-in assertions.

when to use
Pair with JUnit 5. Use everywhere instead of assertEquals.
assertThat(users)
    .hasSize(3)
    .extracting(User::name)
    .containsExactly("Ada", "Grace", "Linus");
assertj.github.io/doc
Mockito

The standard mocking library. Stub, verify, spy.

when to use
Unit tests where you need to fake dependencies.
UserRepo repo = mock(UserRepo.class);
when(repo.findById(42L)).thenReturn(Optional.of(user));

UserService svc = new UserService(repo);
svc.greet(42L);

verify(repo).findById(42L);
site.mockito.org
Testcontainers

Spin up real Docker containers from your tests. Postgres, Kafka, Redis, anything with an image.

when to use
Integration tests that need real services. Beats mocking the database.
@Container
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:16");

@Test
void integrationTest() {
  String url = postgres.getJdbcUrl();
  // run real queries against a real Postgres
}
testcontainers.com
Build2
Maven

XML-based build tool. Everyone knows it; everyone has a love-hate relationship with it.

when to use
Default for most enterprise Java. Stable, predictable.
<project>
  <groupId>com.example</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0.0</version>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
</project>
maven.apache.org
Gradle

Groovy / Kotlin DSL build tool. More flexible than Maven, faster incremental builds.

when to use
Newer projects, especially Kotlin and Android. When Maven feels too verbose.
// build.gradle.kts
plugins {
  java
  id("org.springframework.boot") version "3.3.0"
}
dependencies {
  implementation("org.springframework.boot:spring-boot-starter-web")
  testImplementation("org.springframework.boot:spring-boot-starter-test")
}
gradle.org
Logging2
SLF4J + Logback

SLF4J is the logging facade everyone codes against. Logback is the most common implementation.

when to use
Always. Spring Boot ships with this combo by default.
private static final Logger log = LoggerFactory.getLogger(MyClass.class);

log.info("Processing user {}", userId);
log.warn("Slow query: {} ms", elapsed);
log.error("Failed", exception);
slf4j.org
Log4j 2

Apache logging framework. Async logging, JSON layouts. Use the latest version (post-Log4Shell).

when to use
Alternative to Logback in some legacy or high-throughput systems.
private static final Logger log = LogManager.getLogger();
log.info("Hello, {}", name);
logging.apache.org/log4j
Reactive2
Project Reactor

Reactive Streams for Java. Backbone of Spring WebFlux. Mono / Flux types.

when to use
Reactive non-blocking services, streaming APIs, when you need backpressure.
Flux.fromIterable(userIds)
    .flatMap(userRepo::findById)
    .filter(u -> u.isActive())
    .map(User::email)
    .collectList()
    .subscribe(emails -> log.info("Found {}", emails));
projectreactor.io
RxJava

The original ReactiveX implementation for Java. Less common in new server code (Reactor wins) but huge on Android.

when to use
Android apps. Some legacy server code.
Observable.fromIterable(items)
    .filter(i -> i.value > 0)
    .map(Item::name)
    .subscribe(System.out::println);
github.com/ReactiveX/RxJava
Utilities3
Lombok

Annotation processor that generates getters, setters, equals, builders at compile time. Reduces boilerplate.

when to use
Almost every Spring Boot app. Records have replaced some uses; @Builder still has no equivalent.
@Data
@Builder
public class User {
  private Long id;
  private String email;
  // getters, setters, equals, hashCode, toString, builder — generated
}

User u = User.builder().id(1L).email("a@b.c").build();
projectlombok.org
Guava

Google's core libraries. Caches, immutable collections, string/file utilities, EventBus.

when to use
When you want batteries that the JDK doesn't include yet.
Cache<String, User> cache = CacheBuilder.newBuilder()
    .maximumSize(1000)
    .expireAfterWrite(Duration.ofMinutes(10))
    .build();

ImmutableList<String> list = ImmutableList.of("a", "b", "c");
github.com/google/guava
Apache Commons

Grab-bag of mature utility libraries. commons-lang3, commons-io, commons-text, commons-csv, etc.

when to use
When you need a string utility, file copy, CSV parser and don't want to write it.
// commons-lang3
StringUtils.isBlank("  ");           // true
StringUtils.capitalize("hello");     // "Hello"

// commons-io
String content = FileUtils.readFileToString(file, UTF_8);
commons.apache.org
Security3
Spring Security

Auth and authorization for Spring. OAuth 2, JWT, method-level security, CSRF, CORS.

when to use
Any Spring Boot app that needs authentication.
@Bean
SecurityFilterChain chain(HttpSecurity http) throws Exception {
  return http
      .authorizeHttpRequests(a -> a
          .requestMatchers("/admin/**").hasRole("ADMIN")
          .anyRequest().authenticated())
      .oauth2ResourceServer(oauth -> oauth.jwt(Customizer.withDefaults()))
      .build();
}
spring.io/projects/spring-security
BCrypt (jBCrypt / spring-security-crypto)

Password hashing with built-in salt and work factor. Never store plain passwords.

when to use
Anywhere you store user passwords.
BCryptPasswordEncoder enc = new BCryptPasswordEncoder(12);
String hash = enc.encode("hunter2");
boolean ok = enc.matches("hunter2", hash);
spring.io/projects/spring-security
jose4j / nimbus-jose-jwt

JWT and JOSE (signing, encryption) libraries. Nimbus is the more popular of the two.

when to use
Anywhere you sign or verify JWTs in Java.
JWSSigner signer = new MACSigner(secret);
SignedJWT jwt = new SignedJWT(
    new JWSHeader(JWSAlgorithm.HS256),
    new JWTClaimsSet.Builder()
        .subject("alice")
        .expirationTime(new Date(System.currentTimeMillis() + 60_000))
        .build());
jwt.sign(signer);
String serialized = jwt.serialize();
connect2id.com/products/nimbus-jose-jwt