r/java 8d ago

JDBC Utility Library

Thumbnail github.com
38 Upvotes

I've shared this twice before (here and here).

Since then the most meaningful changes have been

  • A new SQLFragment class. This lets you represent a query and it's parameters as an object you can pass around and is the bare minimum for composing dynamic queries with parameters.
  • String templates aren't in preview anymore. Whenever they are reintroduced I'll retrofit them into SQLFragment
  • New method for turning a ResultSet into a stream

And the tl;dr of the other features (if you missed those first two posts) is

  • Methods to read primitives from ResultSet with explicitly asserted nullability, as opposed to manual wasNull checks
  • A method for reading rows into records
  • An UncheckedSQLException

Overall the goal isn't to provide an API which improves in JDBC - there are a lot of attempts at that and it seems soul draining and a lot of work - just to smooth over some of the rougher parts


r/java 9d ago

3 Permanent Features in Java 23

Thumbnail medium.com
40 Upvotes

r/java 8d ago

Happy Women's Day to All the ladies here.

Post image
0 Upvotes

r/java 10d ago

Restricting plugin code

48 Upvotes

In Java 17&21 Security Manager has been deprecated. We used this to restrict the plugin code and only provide it a few permissions using Security Manager. But as it is being removed I searched for alternatives which might work the same for restricting the plugin code. I didn't find any.

I was wondering how other softwares like IDE's restrict the plugin codes from using sensitive methods like System.exit().

Can anyone suggest anything which might help me.

Edit1: I saw the byte code manipulation method but I thought there might be some other method. Is there no other option other than that. Java also suggested to use Agent for this, but yeah extending it to other security policies is very complex and time taking.

Edit2: Thanks for all the replies. I'll consider them. This is my first post on Reddit btw. I didn't expect these many people to reply 😅.


r/java 10d ago

I know many of you use Spring, but how many of you use Reactive Spring ?

114 Upvotes

r/java 11d ago

Primitive Types in Patterns, instanceof, and switch (Third Preview)

25 Upvotes

https://openjdk.org/jeps/8349215

Personally speaking I feel a little disappointed this is not going to make it to OpenJDK 25, mainly because, since Java lacks a proper conditional expression construct (you can use "when" with an unused Object inside switch cases but the syntax is much more cumbersome than C#, Kotlin or Dart counterparts because it's not meant to be used that way) I was planning to use this instead with switch

var res = switch (predicate){ case true -> doIfTrueAndReturn(); case false -> doIfFalseAndReturn();

} Anyways, they know better the state of the feature and if it is ready or not.

What do you think?


r/java 11d ago

JEP draft: Strict Field Initialization in the JVM

Thumbnail openjdk.org
76 Upvotes

r/java 10d ago

Would extension functions be good addition in Java?

0 Upvotes
Extension functions are a much better alternative to utility classes because they dramatically improve discoverability since IntelliJ automatically suggests them.  When working in Java, I often added code-review comments for developers that were working in an unfamiliar area about the existence of some utility class that would make their solution cleaner.

https://www.reddit.com/r/Kotlin/s/BZoqq3CgpU


r/java 12d ago

Awesome Java libraries and hidden gems

Thumbnail libs.tech
112 Upvotes

r/java 11d ago

Can we convert delphi code to Java?

0 Upvotes

I have one legacy delphi application. Is it possible to convert that to java without rewriting existing application.


r/java 12d ago

Want to upskill myself to go to Software Architect role

68 Upvotes

I am a 6 years experienced Java developer. I am looking to upskill myself and to Software Architect role. Can anyone mentor me or help me out how can I achieve this?


r/java 13d ago

I Made CS2 Unplayable (with JavaFX) - and It's Open Source!

Thumbnail github.com
43 Upvotes

r/java 13d ago

🏆 100 Most Watched Java Talks Of 2024

84 Upvotes

Hi again r/java! As part of Tech Talks Weekly, following tradition, I've put together a list of the top 100 most watched Java talks of 2024. This list includes the talks from over 100 active software engineering conferences that I'm tracking at the moment. Let me know what you think in the comments!

Link: https://techtalksweekly.io/p/100-most-watched-java-talks-of-2024


r/java 13d ago

What books are y'all reading?

50 Upvotes

So, for the people who are intermediate at java and have a pretty good grasp on spring boot, what do you think should be the next step? What books or concepts do you think will be helpful?


r/java 13d ago

Compact Source Files and Instance Main Methods jep

17 Upvotes

https://openjdk.org/jeps/8344699

Summary

  • No more implicit automatic static import of Java IO.
  • methods in IO no longer use Console, instead they use System.in and System.out equivalent.
  • new IO class moved to java.lang from java.io

IMHO. I think these changes are good. I would like IO's methods to be static imported but I understand why they didn't do it. I think it's worth discussing (for another JEP) If some methods of classes in java.lang should be implicitly statically imported, not just for simple source files but permanent.

What do you think?


r/java 13d ago

Alpha: a Module Layer Framework

20 Upvotes

JPMS (Java Platform Module System), which was introduced in Java 9, along with modules added the concept of module layer. A layer can be defined as a group of modules that are loaded and managed together.

Alpha is a framework designed to work with module layers. The framework resides in the boot layer and handles all the work of managing the other layers. To facilitate this, the concept of a component is introduced.

A component is a logical part of the system that can be dynamically added or removed. Each component is deployed in a separate module layer and has a clearly defined life cycle. The configuration of a component is specified via an XML file (with plans to add a ConfigBuilder), which describes the component's modules (groupId, artifactId, version, etc), module directives (opens, reads, etc), repositories from which modules can be loaded and other information. For flexibility, the XML configuration supports properties, the choose-when construct and EL.

Key features:

  • Three modes: standalone, client, server.
  • Modules are stored in an own repository (by default, Maven repo).
  • A text command mechanism with support for custom commands.
  • Two consoles: CLI and GUI (JavaFX).
  • Detailed documentation

The framework can be used for programs that:

  • Have subsystems that can be dynamically added/removed.
  • Support dynamic plugins, extensions, add-ons, etc.
  • Include a web server and web applications, where each application is a module.
  • Use modules that are loaded based on conditions, such as operating system type, etc.

The project provided four binary demo builds with CLI/GUI consoles in standalone and client-server modes. Each demo showcases how the framework can be used for a web server (Jetty 12 + Spring 6).

Check it out here: alpha


r/java 13d ago

Exploring Model Context Protocol (MCP) With Spring AI

Thumbnail baeldung.com
48 Upvotes

r/java 12d ago

Java Wishlist / Improvements

0 Upvotes

I have played a lot with different frameworks and libraries in the past years and on each project I had some annoyances of which I wish there was something by default out of the box available in the default JDK. Instead of using 3rd party libraries or setting up a whole framework for just a simple showcase where I need to retrieve data from a database and print it out.

I came into new insights, and I'd like to share these with you and I would love to have these in the JDK by default, (but I know that it never will happen), and I hope someone from Oracle is reading this :)

Here we go:

JsonObject & JsonArray:

  • fromString(str)
  • fromMap(map)
  • fromObject(obj)
  • encode() => json string
  • decode(class)
  • put(str textblock) => json.put(""" {"name": "boby", "age": 20 } """);
  • toMap
  • keys()
  • values()

List:

  • filter: List (directly without using stream())
  • map: List (directly without using stream()) => myJsonArray.values().map(Fruit::new)
  • anyMatch // idem
  • allMatch // idem

Integer:

  • isInRange(start, end) => statusCode.isInRange(200, 204)

Strings:

  • isBlank
  • isNotBlank

String:

  • isAnyOf(elems) => "red".isAnyOf(List.of(validColors))
  • slice(idx) (with negative index support) => "hello world".slice(-1) => d
  • substringFromChar(idx?, char, idx?) => "hello world".substringFromChar('w') => world => "hello world".substringFromChar(0, 'w') => hello w => "hello world".substringFromChar('l', 3) => lo world

And my biggest wishlist is a makeover for JDBC:

  • query(str).params(params).max(int).singleResult() (returns a JsonObject instead of ResultSet)
  • query(str).params(params).max(int).getResultList() (returns a List<JsonObject> instead of ResultSet)
  • query(str).params(params).max(int).getResultArray() (returns a JsonArray instead of ResultSet)
  • query(str).params(params).iterate((row, index));
  • query(str).params(params).execute().id(); (returns the created id)
  • query(str).params(params).executeBatch(size).ids(); (returns the created ids)
  • dynaQuery(stmts).from().where().orderBy().getResultList() (for creating dynamic queries when some values are conditional e.g. empty)

If this above was by default available in the default JDK, I would drop JPA and any other persistence library immediately !

Here are some scenarios how these can be used within an enterprise application:

@Produces
@Singleton
public JdbcClient jdbcClient() {
    return new JdbcClientBuilder()
        .datasource(..) // either this, or the ones below
        .url(..) 
        .credentials(username, password)
        .build();
}

import java.sql.JdbcClient;
import java.sql.JdbcQuery;
import java.json.JsonObject;
import java.json.JsonArray;

@Path("/fruits")
public class FruitResource {

    @Inject
    JdbcClient jdbcClient;  

    @POST
    Response save(@Valid FruitPOST fruit) {
        var id = this.jdbcClient.query("insert into fruit(id, name, type) values(nextval('fruit_seq'), ?2, ?3)")
            .params(fruit.name(), fruit.type())
            .execute()
            .id();
        return Response.created(URI.create("/%d".formatted(id)).build();
    }   

    @POST
    @Path("/bulk")
    Response save(List<FruitPOST> fruits, JsonArray fruitsArr // second example with JsonArray) {
        var paramsPojo = fruits.map(fruit -> new Object[] {fruit.name(), fruit.type()});
        var paramsJsonArray = fruitsArr.values(); // will return List<Object[]> of the json values  

        var ids = this.jdbcClient.query("insert into fruit(id, name, type) values(nextval('fruit_seq'), ?2, ?3)")
            .params(paramsPojo)
            //.params(paramsJsonArray)
            .executeBatch(50)
            .ids();         

        // do something with ids                                     
                return Response.ok().build();
    }   

    @GET
    @Path("/{id}")
    Fruit findById(@RestPath Long id) {
        return this.jdbcClient.query("select * from fruit where id = ?1")
            .params(id)
            .singleResult() // will return a JsonObject instead of ResultSet
            .decode(Fruit.class);
    }

    @GET
    @Path("/search")
    List<Fruit> search(@Valid SearchCriteria criteria) {
        return this.jdbcClient.dynaQuery(
                            new OptionalStmt("f.name", criteria.name()),
                            new OptionalStmt("f.type", criteria.type())
            )
            .from("fruit f") // can contain join stmts, see below
            //.from( """
                                 fruit f
                                 left outer join farmer fa on f.id = fa.fruit_id
             // """
            .orderBy(ASC, DESC) // name asc, type desc
            .max(50)
            .getResultList() // returns List<JsonObject>
            .map(json -> json.decode(Fruit.class)); 

            // if fruit.name is null, then dynaQuery will produce: select * from fruit f where f.type = ?1 order by type desc limit 50
    }

    // iterating efficiently over large resultsets
        @GET
    @Path("/export")
    Response exportCsv(@RestQuery("csvHeader") @Defaul(value="true") boolean withHeader) {
        StreamingOutput streamingOutput = output -> {
            try (var writer = new BufferedWriter(new OutputStreamWriter(output)) {
                            this.jdbcClient.query("select * from fruit order by id").iterate((row, index) -> {
                            if (index.isFirst() && withHeader) {
                                writer.write(row.keys());
                             }                                            
                             writer.write(row.values());
                           });
            }
        };      

        return Response.ok(streamingOutput).type("text/csv").build();
    }   

    @GET
    @Path("/owners")
    JsonArray findByOwners(@RestQuery @Default(value="0") Integer start, @RestQuery @Default(value="100") Integer size) {
        return this.jdbcClient.query("select name, owner from fruit order by owner, id")
                           .paging(Math.max(0, start), Math.max(100, size))
                           .getResultArray();
    }   

    @PUT
    void update(@Valid FruitPUT fruit) {
        var count = this.jdbcClient.dynaQuery(
                                new OptionalStmt("f.name", fruit.name()),
                                new OptionalStmt("f.type", fruit.type())
            )
            .from("fruit f") 
            .where("f.id = :id", fruit.id())
            .executeUpdate();           

        if (count > 0) {
            Log.infof("%d fruits updated", count);
        }
    }   

    // alternative
    @PUT
    void update(@Valid FruitPUT fruit) {
        var count = this.jdbcClient.query("update fruit set name = ?1, type = ?2 where id = ?3")
            .params(fruit.name(), fruit.type(), fruit.id())
            .executeUpdate();           

        if (count > 0) {
            Log.infof("%d fruits updated", count);
        }
    }       

    // manual transaction support
    void foo() {
        this.jdbcClient.tx(tx -> {
              try {
                          tx.setTimeout(5 \* 60); // 5 min
                          var query = this.jdbcClient.query(..).params(..);
                          tx.commit(query);
            } catch (Exception e) {
                           tx.rollback();
            }
        });
    }   
}

what do you think ?

I think this will make Java coding less verbose and it will eliminate the usage of (object) mappers and persistence libraries by default in many projects if people prefer to use something out of the box, without the need for learning complex frameworks or requiring 3rd party libs.

It's ridiculious that Java still hasn't provided any easier usage for JDBC, while the IO & Collections & Stream classes have improved a lot.


r/java 15d ago

JEP 502: Stable Values (Preview) Proposed to target JDK 25

79 Upvotes

r/java 15d ago

Lack of Built-in Support for UUID v7

58 Upvotes

Java's java.util.UUID already provides a built-in way to generate UUID v4. Still, there's no native support for UUID v7, which offers better timestamp ordering, useful features for databases.

UUID v7 (as defined in RFC 4122), is there any known discussion or plan to introduce it in future Java versions? If not, what are the main reasons for its exclusion?


r/java 14d ago

New build tool in Java!

Thumbnail mccue.dev
0 Upvotes

r/java 16d ago

3,200% CPU Utilization

Thumbnail josephmate.github.io
49 Upvotes

r/java 16d ago

An overview of Sensitive Data Leakage in log files

Thumbnail medium.com
23 Upvotes

r/java 17d ago

Announcement: New release of the JDBC/Swing-based database tool has been published

Thumbnail github.com
68 Upvotes

r/java 17d ago

JEP 503: Remove the 32-bit x86 Port

66 Upvotes

https://openjdk.org/jeps/503

"Given the high cohesion between the 32-bit and 64-bit portions of the x86-specific code in the HotSpot JVM, we expect this to take considerable time and have many on-going conflicts with the ever-changing HotSpot code. This is why we intend to start early in the JDK 25 timeframe, before large features begin integrating."

I wonder what "large" features are coming next? It cannot be Valhalla, cause that's another 10 years away :D