Devoxx UK 2026: Talks, panel, booth and people!

Last week I had the pleasure of attending Devoxx UK for the third time! It was a great two days.

Arriving in London

Immediately upon arrival I ran into Dimitris Doutsiopoulos at the hotel. Great start to the conference!

After checking in, I first had to do some work. Next I went to find Piotr Przybył to return some equipment he had left behind at Voxxed Days Bucharest the week before. We then headed to the speaker dinner together; and ran into Baruch Sadogursky before we even made it out of the hotel.

Speaker dinner

Speaker dinners are always a great chance to catch up with familiar faces and meet new people. From some of the organisers (Mark Hazell, Kim Fletcher, Sam Hepburn and others) to other speakers like Ana-Maria Mihalceanu, Brian Vermeer, Alexander Chatzizacharias, Ixchel Ruiz, Matthias Haeussler, Maarten Mulders and many, many more! Just like last year, it was impossible to get from A to B without running into more people to greet. There simply wasn’t enough time to talk to everyone. Instead, I ended up having a really great conversation with Thomas Wuerthinger.

Opening session

The conference kicked off with live music(!) and a welcome by Mark Hazell and Kim Fletcher. Mark had announced earlier that this will be his last time organising Devoxx UK, and he will be missed.

My talk: Be more productive with IntelliJ IDEA

Fortunately, my talk was scheduled in the morning of day 1. It’s nice to get it out of the way, and this gave me the opportunity to invite people to stop by our booth during the conference.

The talk Be more productive with IntelliJ IDEA is never the same, as I try to incorporate new features. For starters, I’ve updated my demo to show more Command Completion (“dot dot”), which is a new(ish) feature that unlocks any commands relevant to your context in the editor. New this time was a sneak preview of Logpoint, a feature that gives you the option to add “logging” to your application without changing the code or redeploying your application. This feature will be added to the upcoming IntelliJ IDEA 2026.2 release, but you can already try it in the EAP, which you can download using the JetBrains Toolbox App

It was nice to have an (almost) full room, despite my talk not being about AI. In fact, I warned the audience there would be “handcrafted, artisanal code” and very little AI. But they seemed ok with that… Several people, including colleagues(!!) told me they learned some new things. To be honest, I don’t think there’s anyone inside JetBrains who knows all the features.

Unfortunately, I don’t think the talk was recorded. If you’d like to see a previous recording of the talk, you can find them on the talk page.

Booth

This year, we had a JetBrains booth at Devoxx UK. This is a great opportunity for us to speak to our users as well as people working on libraries and frameworks in the ecosystem. It’s also a good opportunity for people to stop by with questions and feedback.

My colleague Andrei Kogun told me that several people stopped by our booth during the conference to ask about the new Logpoint feature that I showed in my talk!

An added bonus for me is that I get to see some of my colleagues in person.

Spring Documentary premiere and panel

In the evening of day 1, there was a premiere of theSpring documentary: 

Following the screening, there was a panel with several of the cast members who were at Devoxx UK: Josh Long, David Syer, Steve Poole and myself. The panel was moderated by Daniel Garnier-Moiroux. It was interesting to discuss some of the history of Spring.

After the panel, we went for a quick dinner with friends Andrzej Grzesik, his wife Ewa, Piotr Przybył, Marek Machnik and several others. 

Dinner

Talks 

This year, I did not attend many talks, as I was busy talking to people at the booth and in the hallway. One talk I didn’t want to miss was Piotr‘s talk Butcher Virtual Threads like a pro! as I always like sseing him speak. It was certainly different to be in the audience for a change, instead of on stage together. Although there was a little audience participation 😉

I did also manage to attend The Structured Concurrency API in JDK 26: Scoped and Joiners by José Paumard, which was very interesting. You can find the slides here.

Hallway track

Of course, the best track of any conference is the hallway track. Unexpectedly, I ran into my colleague Sonya Kondirova from the Java Build Tools team (we have worked together on new features for Maven and Gradle) which was a nice surprise. 

Also, I got to spend some time with Estelle Landry (probably more at Devoxx UK, than in our lightning trip to Devoxx France recently). 

Finally, I managed to sit down with Holly Cummins to give her some tailored pointers for presenting with IntelliJ IDEA (at her request). It’s fun to share tips and tricks, and I hope they will come in handy!

Again there was not enough time to talk to everyone as much as I would have liked. But there is always the next one!

Hallway track

Heading home

Unfortunately I had to leave in the afternoon of day 2 to catch my flight, which meant I missed some of the last talks and the party. Maybe next year… 🤞

Thank you!

Many thanks to the organisers , volunteers and sponsors for putting on such a great event. Thanks to all the speakers and attendees; it was great to see and meet you! Hope to see you at the next one 😉

Links

Photos by Dimitris Doutsiopoulos 🫶

Voxxed Days Bucharest: The end of an era

Almost two weeks ago, I had the pleasure of speaking at Voxxed Days Bucharest 2026. This was my third Voxxed Days Romania event; I’ve spoken at Voxxed Days Bucharest before in 2024, and in 2022 I gave two talks at Voxxed Days Cluj-Napoca, including stepping in as the closing keynote speaker to replace Tom Cools who unfortunately couldn’t make it.

Travelling

On the plane from Schiphol to Bucharest, I immediately ran into fellow Dutch speakers Alexander Chatzizacharias and Sander Hoogendoorn. It turned out that Sander and I were both staying near the new venue so we took an Uber together from the airport. Ana-Maria Mihalceanu had very helpfully shared instructions with the speakers on how to best get to our hotels. 

Speaker dinner

Since the speaker dinner was near the old venue, Sander and I ended up walking across Bucharest for about an hour, partially through a park.

The speaker dinner was a nice place to catch up with fellow speakers. Some I has seen only the week before at different conferences. The food was a wonderful display of Romanian hospitality, as always. 

Conference day

The conference was opened by organisers Andra Ghibuțiu and Alex Proca. Andra revealed that this was sadly the last edition of Voxxed Days Romania. It was an honor to be part of this event. Fortunately, Andra and Alex will continue to organise different events in Romania.

Sander gave one of the keynotes on the conference day, which unfortunately I did not get to enjoy as I had to go and prepare for our talk, which was scheduled right after. It was nice that he mentioned me, and also used something in his keynote that we had talked about the evening before on our way to the speaker dinner. 🙂

Piotr and I once again took the stage with Learning modern Java the playful way, after three conferences in four days the week before! As always, it was a joy to give this talk, and the audience was wonderful! Thank you for your lovely feedback.

The slot right after ours belonged to George Patrașcu. Our talks were scheduled back to back, which meant a hasty change over between speakers, mics and laptops. In the confusion, Piotr left the dongle for his clicker behind on stage. We only found out after he had already left. Fortunately we were both speaking at Devoxx UK the following week, so I could return it to him there.

The hallway track

One of the things I love most about conferences is seeing friends and meeting new people. At Voxxed Days Bucharest I got to catch up with some familiar faces, like Abdel Sghiouar, Ana-Maria Mihalceanu, Brian Vermeer and Loïc Magnette. I also got to meet new speakers like George Patrașcu, and talk with other attendees. This is a good way to hear what people are working on, and get feedback on how we can help them better.

And of course, some of the best conversations happened in the hallway track in between sessions.

Leaving for Munich

Unfortunately I couldn’t stay until the end of the event, as I had to travel to Munich where I had to record a video the next day.

Thank you!

Many thanks to Andra, Alex and the whole team of organisers and volunteers for making Voxxed Days Bucharest 2026 such a lovely event. And of course, thanks to all the sponsors and attendees who made it possible. It was a privilege to be part of this final edition, and I wish Andra and Alex all the best with their future endeavours.

Links

Three conferences in four days: JCON, Devoxx France and Devoxx Greece

Two weeks ago I had an extremely busy week: speaking at three conferences in three different countries in four days — JCON (Cologne, Germany), Devoxx France (Paris) and Devoxx Greece (Athens). We had the opportunity to give our talk “Learning modern Java the playful way” three times! It was well worth it, as I got to see so many people and our talk was well received everywhere.

JCON Europe

On Monday, I took the train to Cologne.

Social media post by Marit van Dijk with the text "On my way to JCON". The post contains a picture of a green suitcase with a luggage label containing the IntelliJ IDEA icon and the text "Luggage tagged. Code secured. JetBrains IDEs", and a black North Face backpack containing a red label with the text "Unlocking productivity", a tag of the IntelliJ IDEA logo, and a tag with Duke, the Java mascot.
On my way to JCON

Java Luminaries Summit

In the afternoon, there was a Java Luminaries Summit @ JCON Europe, where folks active in the Java community discuss topics relevant to the language and ecosystem. This includes Java Champions, JUG leaders, speakers and other active members from the community, like Sharat Chander, Ana-Maria MihalceanuAndres Almiray, Brian Vermeer, Cay Horstmann, Kevin Wittek, Kevin Dubois and many more. Unfortunately, I wasn’t able to attend the whole summit, as I had some work to do first.

After the summit, there was a pizza session, which was a great opportunity to socialize with other speakers, like Tim te Beek and Rick Ossendrijver, and community members. Also, I got to see my colleague Marcin Mycek and introduce him to some people.

JCON conference day 1

On Tuesday morning, we first prepared our session. Even though we have done this talk before, we always update it to the latest Java version and make small tweaks to continuously improve it.

For lunch, I met with Annelore Egger, François Martin and two of his colleagues.

Social Media post by François Martin about lunch at JCON, including a picture with Annelore Egger, François Martin, Marit van Dijk and Tamar Gogebashvili at a lunch table.
Lunch at JCON

Before the conference, we also had the opportunity to sign up for interviews with Baruch Sodogursky which were livestreamed on YouTube.

During his interview, Piotr Przybył talked about our talk:

Baruch and I had a lovely conversation about reading code in the age of AI:

This is a topic dear to my heart, as I have been talking about Reading Code for a while — and I still think it’s important no matter who has “written” the code.

In the afternoon it was time for our first talk of the week.

Piotr Przybył and Marit van Dijk simultaneously putting on their labcoat.
Synchronous putting-on-labcoat (photo by Dimitris Doutsiopoulos)
Piotr Przybył and Marit van Dijk simultaneously putting a pen in the front pocket of their labcoat.
Synchronous putting-pen-in-pocket (photo by Dimitris Doutsiopoulos)

Giving this talk is a lot of fun. It was very nice to have people come up to us afterwards to tell us how much they liked it. (Special thanks to JavaCro organiser Branko Mihaljević for all your kind words!)

Fortunately, I also had some time to catch up with more people, like Sandra Parsick, Sandra Ahlgrimm, and several others.

JCON speaker dinner

In the evening, it was time for the speaker dinner.

Marit van Dijk making a heart at photographer Dimitris Doutsiopoulos
When you see Dimitris (photo by Dimitris Doutsiopoulos)

Earlier during the day, I had run into my friend Rien Korstanje, who I hadn’t seen in a while. We know each other from when I used to contribute to cucumber-jvm, as he is one of the core maintainers. Turns out is now also a maintainer for JUnit, so we had some time to catch up during dinner with Marc Philipp and Christian Stein (thanks for laughing at all my silly jokes!).

Unfortunately there was not enough time to properly catch up with everyone.

Social media post by Catherine Edelveis with the text "Caught Marit van Dijk for 2 minutes" containing a picture of Catherine and Marit.
Seeing Catherine (too) briefly at the JCON speaker dinner

Devoxx France

On Wednesday, it was time to travel to Paris. We took the train and through sheer luck ended up with seats next to each other, even though we had booked through our respective employers. This gave us time to reflect on how the talk went at JCON and prepare for our session at Devoxx France in the afternoon.

After surviving the Paris metro, the first person we saw at Devoxx France was Estelle Landry, which was a very happy reunion as I hadn’t seen her since Devoxx Morocco.

Estelle helped us get some lunch, pointed us to the speaker room and got us settled in so we were ready for our session. We also ran into Daniel Garnier-Moiroux in the speaker room.

Our talk was again in the afternoon, and the audience was amazing! This was quite possibly the most engaged audience we have had for this talk, and also the best version of the talk we have done so far.

Social media post by Piotr Przybył with the text: "Thank you for being such a vivid and welcoming audience, Devoxx France. And now, with Marit van Dijk: FROMAGE !". The post contains a picture of Marit van Dijk and Piotr Przybył, both wearing labcoats, on stage at Devoxx France with the audience in the background.
Taking a selfie at Devoxx France: Fromage!

It seems we were not the only ones who thought so, because we also received the highest rating for our talk so far: 4.92/5. In addion, we received some very nice feedback like “You make an awesome team” and “Very funny”.

Talk ratings from the Devoxx Mobile app for Learning modern Java the playful way. With 235 hearts, 24 ratings and 5 comments, the average rating is 4,92/5.
A 4.92/5 rating at Devoxx France

Unfortunately, the video is not available yet, but it should be added to the Devoxx France YouTube channel soon. And photos will be added to the Devoxx France Flickr albums.

In the evening, it was again time for the speaker dinner, where I had the opportunity to catch up with people like José Paumard, Zineb Bendhiba, and several others… We didn’t stay too late, as we had an early start to travel to Athens the next day.

Devoxx Greece

We met up early in the morning to take the train to the airport and fly to Athens. Upon arrival, we took a taxi to the venue to figure out the logistics for our talk the next day.

In the evening, there was a speaker reception where we got to meet some of the other speakers, including Viktor Gamov, Alina Yurenko, Alexander Chatzizacharias, Holly Cummins and Patrick Baumgartner. An added bonus for me was the opportunity to catch up with my colleague Michelle Frost, who I don’t get to see that often.

The next morning we met up at the venue for our talk. It was once again time to put on a labcoat 😉

Black and white photo of Marit van Dijk putting on her labcoat over a Java Champion polo.
Putting on the labcoat at Devoxx Greece (photo by Dimitris Doutsiopoulos)

We were a little rushed, as the talk slots were slightly shorter. But it seems that our talk was again well received; we received nice ratings (4,78/5) and lovely feedback. Special thanks to the person who came up to talk to me in Dutch and the folks who came up to us when we were taking pictures to tell us that ours was their favorite session!

We did a short interview for Devoxx Greece and recorded a short video ourselves with the help of Alina Yurenko (thanks!).

Social media post by Alina Yurenko with the text: "Working a double shift as a personal media team for some speakers!!!🙄😄" tagging Marit van Dijk, Piotr Przybył and Devoxx Greece. The post contains a selfie of Alina Yurenko. Marit van Dijk and Piotr Przybył are standing in the background in front of a Devoxx Greece banner; both are wearing a white labcoat.
Alina Yurenko as our personal media team
Marit van Dijk and Piotr Przybył in front of a Devoxx Greece banner; both are wearing a white labcoat.
At Devoxx Greece (photo by Dimitris Doutsiopoulos)

In the afternoon, I had some time to catch up with people, had to take a meeting (is it even remote work if you don’t work from various weird places like conferences, trains, airports and hotel lobbies?) and then it was time to head home.

A great week

Overall, I had a great week. It was wonderful to see so many friends and meet new people. Many thanks to the conference organisers, volunteers and attendees at JCON, Devoxx France and Devoxx Greece and of course my amazing cospeaker Piotr Przybył.

Links

Voxxed Days Amsterdam 2026: An absolute blast!

Just over two weeks ago, I was at Voxxed Days Amsterdam. This was the second edition of the conference, and this year it was two days instead of one!

Day 1: Wednesday, April 1

Opening the day

As a member of the Program Committee, I got to open day 1 together with Michel Schudel. During the opening we introduced the speakers, the program committee, and the community reviewers. This year we had around 650 proposals, and some of us (including myself) reviewed each and every one of them! We also remind people to use the app to rate the talks, as that helps both speakers and organisers to know how talks are received. We use this information to improve our talks and the program!

dD_1103

Like last year, we had rotating keynotes; which meant that the keynote speakers would do their keynote twice (once in each room) rather than have an overflow room where people watch the keynotes on a screen. One of the keynotes on day 1 was Baruch Sadogursky‘s Never Trust a Monkey! Can We Trust AI-Generated Code? Baruch’s takes are always interesting, so I’d recommend checking it out.

Speaking with Piotr Przybył about modern Java

Right after the opening, it was time for Piotr Przybył and I to take the stage. We present our talk Learning modern Java the playful way, which we updated for Java 26. During this talk we show you how to update Java code from Java 8-11 to modern Java, using some of our favorite new Java language features, including Records, Stream Gatherers, Structured Concurrency, and for the Java 26 version we also added Lazy Constants. We do so using a demo application, and of course some silly jokes!

We aim for the session to be educational and entertaining. Fortunately, someone who attended our session stopped by to tell us that was exactly what they thought of our session, just as we were taking pictures for a social media post.

Foojay podcast

Frank Delporte was back again this year to interview speakers for the Friends of OpenJDK (Foojay.io) podcast. We discussed some topics dear to my heart: Java and reading code.

dD_2327

You can catch all of the interviews below:

Other talks

During the day I also managed to catch a few other sessions:

10 Things I Hate About Java by Adele Carpenter

Adele is an amazing speaker, and this talk was no exception. I’d been wanting to see this talk ever since I first heard about it! In this talk, Adele goes over some of the decisions that were made during the design of the language, and how those resulted in some of the features that Java has (or doesn’t have). The talk was well-researched and the delivery was amazing. The title of the talk refers to the movie title “10 things I hate about you”. Adele ended the talk with a poem about Java, similar to the one Julia Stiles recites during the movie, and it was brilliant!

Building AI Agents with Spring & MCP by James Ward and Josh Long

It is always fun to see what Josh and James are up to with Spring and AI. Even if you’ve seen them before, they are always entertaining. And in this session they also briefly mentioned Mellum by JetBrains.

What Sorcery is This? How software uses Dark Patterns to manipulate users by Rachel Appel

Another talk I’d been wanting to see for a while. Even though Rachel is my colleague, we don’t usually go to the same conferences, as we are in different ecosystems. Rachel showed how easy it is to manipulate users through software design, with some absolutely appalling examples of dark patterns. This talk is a good reminder of the responsibility we have as developers.

Language Games by Eli Holderness

This talk combines philosophy, language and communication in a way I cannot reproduce; you’ll just have to watch it yourself! Due to technical difficulties, Eli’s slides were not always shown properly. They managed to work around that quite well by describing the image that should have been displayed. It was a master class in communication.

Despite being able to catch some talks, there were also many I missed. For example, my other colleague Anton Arhipov was speaking at the same time as Rachel. And, as much as I would like to, unfortunately I still haven’t managed to clone myself so I can attend multiple sessions at the same time… 😔

dD_2122

Also, there is more to do on a conference day than attending talks; I also had regular work to do in between, like writing the Featured Content for Java Annotated Monthly that was about to be published.

Day 2: Thursday, April 2

Opening the day

On day 2, I opened the conference together with Ko Turk. Again we introduced the speakers, program committee and community reviewers, and I got to announce Iulia Feroli 🤩 as one of the keynote speakers. Her keynote Building my own (accurate!) Spotify Wrapped was a good way to start the day.

In fact, her keynote inspired Devoxx founder Stephan Janssen to add a Devoxx wrapped to the Devoxx Mobile companion app.

Other talks

On the second day, I didn’t manage to catch so many talks, as I also had other things to do. But the ones I did see were again very good!

How I built my own Intelligent Robot Arm from Scratch by Iulia Feroli

In addition to her keynote, Iulia gave a talk about her physical AI adventures, bringing real hardware on stage. This was a very inspiring session; I am always amazed with how creative some people are in ways that are different from myself.

Iulia is definitely someone to watch! You can follow her YouTube channel Back to Engineering if you want to learn more.

5.5 prompt injection techniques in 15 minutes by Brian Vermeer

A last minute addition to the program (we are lucky to have so many great speakers in the Netherlands!), Brian talks about some much needed security awareness in the age of AI.

Hallway track

And of course, some of the best parts of a conference happen in the hallway. It was great to catch up with friends and meet new people across both days. Among other things, I had a great conversation with Ronald Dehuysser about what working as a Developer Advocate looks like (spoiler: it’s more than speaking at conferences!). One of the things I like about this job is speaking to our users, getting their feedback and seeing how we can help them better. Ronald happened to have some relevant feedback that we discussed.

dD_4188
dD_0790

Thanks!

Many thanks to everyone who helped make this such a great event: the speakers for their great sessions, volunteers for helping out, sponsors for making this possible and of course all the attendees! 

All recordings are available in the playlist on YouTube

Photos by Dimitris Doutsiopoulos 🫶 are available for day 1 and day 2.

All photos in this post (except for screenshots) by Dimitris Doutsiopoulos.

dD_3010

Voxxed Days Zürich 2026: Another great event!

Almost three weeks ago, I had the pleasure of speaking at Voxxed Days Zürich. This was my third time at this conference, and also my third Swiss Voxxed Days this year (which will be relevant later!).

Speaker dinner

The speaker dinner the evening before the conference is always a good time to catch up with friends and meet other speakers. Good food and drinks are a bonus.  

Because the restaurant was a little loud (maybe because it was filled with speakers…), some of us ended up outside.

Photographer Dimitris Doutsiopoulos took advantage of this to take some beautiful pictures, like this one of Paco van Beckhoven and me, which my colleague Jason Torres pointed out looks like a still from a movie. (It does, doesn’t it?)

Welcome

The conference day started with a welcome by Federico Yankelevich and Patrick Baumgartner.

Patrick created a beautiful animation for this year’s edition. And I have to say I am rather partial to these colors. They even got the steps of the cinema to match!

During the session they called out the Voxxed Days Switzerland Champions. Apparently I was one of six speakers who spoke at all three Swiss Voxxed Days conferences: Voxxed Days Ticino, Voxxed Days CERN and Voxxed Days Zürich. As I am a sucker for vanity metrics, I really appreciated this callout. 😂

Speaking with Andres Almiray about Maven

At Voxxed Days Zürich this year, I had the pleasure to do a new(ish) talk with Andres Almiray: “Getting more out of Maven”. This was only the second time we did this talk (the first time was at JavaLand). Unfortunately we had some trouble connecting my macbook to the screen, which threw us off a little…

During the talk we discussed several tips for using Maven in IntelliJ IDEA. We showed using the Maven wrapper to increase reproducibility of the build, and the enforcer plugin to see where your build breaks. We explained Maven lifecycle and goals, as well as how inheritance works, and more. And of course, we showed some useful IntelliJ IDEA features for working with Maven and dependency management, the dependency analyzer to find conflicts in dependencies, inspections to show you when dependencies have known vulnerabilities and finally the Vulnerable API inspection which can show you whether you are actually using the vulnerable API of a known vulnerability. 

And of course, our session also included some custom memes that we created for this talk. If you want to see all the memes, you can find them in this repo.

Despite the initial technical trouble, overall our session went well. We got some positive feedback, and I had a nice conversation later with some of the attendees about the topic of our talk.

Other talks

During the day I managed to catch the following talks:

Agentic AI Patterns by Kevin Dubois and Mario Fusco

This was a great talk to stay up to date with everything AI. Kevin and Marco did also have some technical trouble, when there was some interference with audio from another room, which was quickly fixes by the conference.

Are We Ready For The Next Cyber Security Crisis Like Log4Shell? by Soroosh Khodami

Soroosh showed us how easy it can be to get compromised and different ways to prevent this.

Supercharge your JVM performance with Project Leyden and Spring Boot by Moritz Halbritter

Moritz showed us how Project Leyden can help you speed up your Spring Boot applications. Mandatory watching for anyone using Java and Spring Boot!

Hallway track

And I also managed to take advantage of the hallway track, again to catch up with people. 

Thanks!

Many thanks to Federico Yankelevich, Patrick Baumgartner and team for organizing another great event! I hope to be back again in the future.

You can find the Voxxed Days Zürich photo album here and the playlist here.

Credit

All photos on this page by Dimitris Doutsiopoulos. 🫶

Tips and tricks to use Java 25 in IntelliJ IDEA

IntelliJ IDEA supports new Java versions from day one. Several features were added to make working with Java 25 language features in IntelliJ IDEA easier.

New project

Create a new project in IntelliJ IDEA.

You can use the New Project Wizard to create a new project in IntelliJ IDEA. If you select the option to Add sample code, IntelliJ IDEA will add sample code to your project, containing a class with a main method.

If you select IntelliJ as your Build system, set JDK to 25, the sample code will be a compact source file and instance main method, introduced in Java 25.

Compact source file

Create a compact source file in IntelliJ IDEA.

Compact source files were introduced in Java 25. To create a compact source file, right-click the Project tool window (or press ⌘N (macOS) / Alt+Ins (Windows/Linux)) and select New | Java Class. In the New Java Class popup, select the option Compact source file.

This compact source file is created in the root directory of your project, even if you create it from another package. IntelliJ IDEA automatically adds an instance main method void main() to the file.

Java Compact File

Create a compact source file in IntelliJ IDEA.

To create a Java Compact File, introduced in Java 25, right-click the src/main/java directory in the Project tool window and select New | Java Compact File. IntelliJ IDEA will provide a default name for the file, so your thought process is not disrupted when you want to quickly try something out. IntelliJ IDEA automatically adds an instance main method void main() to the file.

Convert compact source file to class

Convert a compact source file to a class in IntelliJ IDEA.

Java 25 introduced the concept of implicit classes or compact source files. We can convert an implicit class to a regular class as needed. Invoke Context Actions by pressing ⌥⏎ (macOS) / Alt+Enter (Windows/Linux) and select Convert an implicitly declared class of a compact source file into a regular class.

The reverse is also possible, should you prefer to use an implicit class at any point. To do so, use the quick-fix Convert into compact source file.

New live templates for main methods

Create an instance main method using a live template.

IntelliJ IDEA has some new live templates to add a main method to an implicit class, either with or without arguments: mainmainapsvmpsvma. Using the live templates psvm or main inside a compact source file will add the new main method, while they will continue to add the classic main method inside a class, as you can see in the preview.

Add arguments

Add args to your main method.

The new void main() method, introduced in Java 25, does not need String[] args. However, should you decide to use the args in your code, IntelliJ IDEA will help you by also adding them to the main method. Type args and press  (macOS) / Enter (Windows/Linux) to select args from code completion.

Live templates for simple IO

Add simple IO methods using live templates.

Java 25 introduces simple IO methods, such as IO.println() and readln() to make interacting with the console more convenient. IntelliJ IDEA introduces two new live templates to use these methods: iop for println() and ior for readln().

In addition, there are quick-fixes available to convert IO.println() to System.out.println(), and vice versa. Invoke Context Actions ⌥⏎ (macOS) / Alt+Enter (Windows/Linux) on the method and select the option Replace with System.out.println() or Replace with IO.println().

Add static import for simple IO

Add a static import for simple IO methods.

Java 25 introduces simple IO methods, such as IO.println() and readln() to make interacting with the console more convenient. To use these methods in a compact source file, you don’t need to add an import. However, you can add a static import the java.lang.IO class if you prefer. Invoke Context Actions ⌥⏎ (macOS) / Alt+Enter (Windows/Linux) on the method and select the option Add on-demand static import for java.lang.io.

Module Import

Using module import in IntelliJ IDEA.

Java 25 introduces module imports. When adding a module import, use Jump Down to see the contents of the module. When using Optimized Imports, IntelliJ IDEA will automatically remove any imports that are added by the module import. If you prefer to use single class imports, invoke Context Actions ⌥⏎ (macOS) / Alt+Enter (Windows/Linux) and select Replace with single class imports.

If desired, it is possible to delete unused module imports when using Optimized Imports. To configure this option, open Settings | Editor | Code Style | Java and go to the Imports tab. Select the option Delete unused module imports. When this option is selected, Optimized Imports will remove unused module imports.

Delete unused module imports

Conclusion

Support for Java language features in IntelliJ IDEA makes it easy to adopt and work with new Java language versions.

Vulnerable API usage: Is your Java code vulnerable?

One of the downsides of using external dependencies, is that they might have known vulnerabilities at any time, as we have seen in the case of Log4Shell, Spring4Shell and other examples. 

This means that, as developers, we have to keep track of which dependencies have known vulnerabilities and upgrade them if an unaffected version is available. Sometimes we might need to prioritize which dependencies to update when. This is where it comes in handy to know what the severity of the vulnerabilities is. And whether we are even using the vulnerable API of a vulnerable dependency. In IntelliJ IDEA, Package analysis, provided by the Package Checker plugin, and the Vulnerable API Usage inspection can do just that!

See which dependencies have known vulnerabilities

If the dependencies in your project have known vulnerabilities, IntelliJ IDEA will highlight them in the build file (`pom.xml` or `build.gradle`). When we hover over the highlighted dependency, we’ll see a list of known vulnerabilities with a link to more information, a severity score and a brief description. 

Vulnerable dependency

We can click the link for a CVE number to open detailed information about that particular CVE in the Mend Vulnerability Database.

But we don’t need to leave our IDE to get more information about these vulnerabilities. In the popup, click the link Show details… to open the Vulnerable Dependencies tab in the Problems tool window.

Vulnerable Dependencies

The Vulnerable Dependencies tab contains a list of dependencies with known vulnerabilities in our project and the severity of these vulnerabilities. Some dependencies bring in transitive dependencies with known vulnerabilities; we can expand these dependencies in the list to see the transitive dependencies, their known vulnerabilities and their severity.

When we select a dependency in the list, we can see more details about its vulnerabilities in the right hand side of the tab. We see the dependency, CVE number, severity score, and a summary of the vulnerability. If we still need more information, we can click the link Read more, to open the information about this vulnerability in the Mend Vulnerability Database..

Vulnerable Dependencies – Details

Dealing with vulnerabilities

To deal with the vulnerabilities, we can use ⌥⏎ (on macOS) or Alt+Enter (on Windows/Linux) to have IntelliJ IDEA show us suggested fixes. For a vulnerable dependency, we have the option to update the dependency to an unaffected version (if one is available), ignore the vulnerability or show the vulnerability information for that dependency. The last option will show a list of all the known vulnerabilities for that dependency. 

Suggested fixes

In most cases, we’ll want to upgrade the dependency instead. When we upgrade, we’ll also want to make sure that our project still builds and our tests still pass. 

In some cases you may want to ignore a library that has known vulnerabilities. To do so, select the option “Ignore vulnerable <library name>” from the context action menu. In the Ignore Vulnerable Package popup that opens, select the reason you want to ignore this vulnerability. If you select Other, you’ll have the option to add a description.

Ignore Vulnerable Package

You may not want to ignore them forever though. To access the list with ignored vulnerabilities, open the IDE settings (⌘, on macOS or Ctrl+Alt+S on Windows/Linux) and go to Editor | Inspections. Expand the Security node and click Vulnerable declared dependency

Vulnerable declared dependency

To make this easier to find, click the Filter Inspection button and select Show Only Modified Inspections. The list is located in the Options section in inspection details. Remove a dependency from the list of ignored dependencies, by selecting that dependency and clicking the remove button or using the shortcut. Once removed from this list, vulnerabilities in that dependency will no longer be ignored.

Show only modified inspections

Prioritizing updates

If our application has multiple dependencies with known vulnerabilities, you might need to prioritize which to update first. You can look at the severity of the vulnerabilities, but you might want to know whether your code is actually using the vulnerable part of a dependency.

If we are looking at code that calls the vulnerable API of a dependency, this code will be highlighted in the editor. When we hover over the highlighted code, we see a list of vulnerabilities found in this API call. 

Vulnerabilities found in API call

We can use Show Intention Actions (⌥⏎ on macOS or Alt+Enter on Windows/Linux) and select Go to file with declared dependency from the menu. 

This will take us to the place in the build file where the dependency is declared, where we can use ⌥⏎ (on macOS) or Alt+Enter (on Windows/Linux) again to Update to unaffected version.

Go to file with declared dependency

Find out whether our code is using the Vulnerable API

But what if you’re not working on the exact file that uses the vulnerable API? How can you find out whether your code is using a vulnerable API anywhere in your project? 

We can run the Vulnerable API usage inspection manually to get a report about all vulnerable APIs usages in our project. To run an inspection by name, we can go to Code | Analyze Code | Run Inspection by Name in the main menu, use Search Everywhere (⇧⇧ on macOS or Shift+Shift on Windows/Linux) to look for “Run inspection by Name”, or use the shortcut ⌘⌥⇧I (on macOS) or Ctrl+Alt+Shift+I (on Windows/Linux). 

Run Inspection by Name

In the Enter inspection name popup that opens, type the name of the inspection you want to run: “Vulnerable API usage”. 

Enter inspection name

Next, select the scope you want to run this inspection on. You could run the inspection on a file or custom scope, or use the File mask(s) option to narrow down the number of files that will be inspected. In some cases you might only want to look at a part of your application. In other cases, you’ll want to run the inspection on the whole project.

Scope

The results of the inspection will open in a tab in the Problems tool window. 

Inspection results

The results will be shown on the left. Click one of the results to open a preview of that result on the right. This gives you the option to Go to file with declared dependency, which will navigate to the place in the build file where the relevant dependency is declared, and we can upgrade the dependency to the unaffected version from there. Alternatively, double-click the result to navigate to the affected code in the editor, to see exactly where and how the vulnerable API is used. 

Vulnerable API Usage

Supressing inspections

Notice that it is also possible to Suppress the inspection. We can suppress the inspection either for the statement or the class, or suppress all inspections for the class. 

Suppress

When you suppress an inspection, IntelliJ IDEA adds a new element before the selected symbol. When we select suppress for class, IntelliJ IDEA adds the `@SuppressWarnings` annotation. For statements, the `//noinspection` comment is added.

When an inspection is suppressed, the problem found by this inspection is no longer highlighted. To re-enable a suppressed inspection, delete the annotation or comment that the IDE has added before the selected symbol.

Suppressed vulnerability

Upgrade dependency

Since we’re actually using the vulnerable API for this dependency in this example, we’ll definitely want to upgrade it! We can go to the file with the declared dependency, and use Intention actions (⌥⏎ on macOS or Alt+Enter on Windows/Linux) to upgrade to the unaffected version. If needed, Load Maven Changes (⌘⇧I on macOS or Ctrl+Shift+O in Windows/Linux) to import the updated dependency.

Conclusion

When we have resolved the vulnerable API usage, when we run the Vulnerable API inspection again, we will get the result: “Code inspection did not find anything to report.”

Knowing whether our code uses a vulnerable API can help us developers better prioritize which dependencies to update.

Command completion: IntelliJ IDEA with less shortcuts

How many shortcuts can you remember? Three? Five? More? I try to learn as many as I can and still forget some of them…

What if you could unlock IntelliJ IDEA features, without having to remember shortcuts? You can still use shortcuts if you want. But you don’t have to.

Command completion (..) is a new feature in IntelliJ IDEA that lets you discover and execute IDE actions right from your editor. 

Command completion extends regular completion

Command completion is an extension of regular code completion – something every developer already uses. For example, when you have a variable, you can type a dot to show you completion options. It will show you API completion (all of the methods you can call on this variable), and postfix completion (templates you can apply to this variable). The list now also includes commands; all relevant commands for your current context. Code completion (a single dot) is now a universal entry point for all relevant actions.

To filter the list to show commands only, type two dots ... As the list can be quite long, the list is searchable, so you can type part of the command you want to use. 

Command completion extends regular completion

By default, the commands are shown in a separate section of the list. If you prefer Commands to be part of the regular completion list, you can adjust this in the Settings. Use Search Everywhere (Shift Shift) and look for “command completion” to go straight to the relevant settings and uncheck the option Show command completion as a separate group.

Command Completion Settings: Show command completion as a separate group

Fix errors and warnings with command completion

You can use this new feature to fix errors and warnings in your code. If you write code that doesn’t compile, IntelliJ IDEA will tell you. You can navigate to the error using F2 and press Alt+Enter to show context actions. However, Alt+Enter gives you only a few options; it is designed to give you the most relevant fixes to your problem. That means it might not always include the action you want to perform. On the other hand, command completion (..) offers you all actions that are relevant in your current context. IntelliJ IDEA will give you a preview of what each command will do.

Fix errors and warnings

Perform file- or class-level actions

It is now possible to unlock this type of completion in places where it wasn’t available before, like on a blank line. Typing a dot on a blank line now shows you file-level actions, like Reformat Code or Optimize Imports. For example, use Optimize Imports to remove an import statement that is no longer needed. 

Perform file or class level actions

Refactoring and code transformation

Command completion can also help you when refactoring or transforming your code. When writing code, you can use it to keep moving forward. For example, to create classes, methods and fields.

Keep moving forward and create classes, methods and fields

You can use it to generate code for you, such as a toString() method.

You can transform your code as you go, for example to make use of modern Java language features. For example, you can refactor a class into a record, using only command completion.

Transform code

Use command completion for navigation

You can use it for navigation. For example, we can navigate to the String class declaration. You’ll notice that this file is read only! How will we use completion here? Don’t worry, you can change your settings to be able to use command completion in read-only files!

Open the Settings for Command Completion, by using Search Everywhere (Shift Shift) and searching for “command completion”. Select the option Enable command completion for read only files. Now, you can use command completion in read-only files, for example to navigate back to where you were.

Command Completion Settings: Enable command completion for read only files.

If you want to rename your class, you can use a shortcut to do so, but you need to know this shortcut (⇧F6 on macOS / Shift+F6 on Windows/Linux). Now, you can use command completion instead. Go to the end of the class or method name you want to rename and type ..rename.

Aliases for several commands

In some cases, you don’t even need to know the exact name of the command you’re looking for, as some commands have aliases. For example, you can also use ..change name instead of ..rename.

Aliases

This makes features even more discoverable; you don’t need to remember the exact name of the feature.

Complements existing features

You can still use existing shortcuts, postfix completion and live templates. Command completion is intended to complement existing features.

Imagine we declare a new instance of a class Person. To assign this new Person() to a variable, you can use the shortcut to Extract Variable (⌥⌘V on macOS / Ctrl+Alt+V on  Windows/Linux). But this requires you to know this feature exists and the relevant shortcut.

Alternatively you could use postfix completion .var to create a variable. But that would again require you to know (or quickly be able to find) this specific postfix completion.

Instead, you can now use command completion to introduce a local variable. After the declaration of the new instance, use ..Introduce local variable.

Command completion complements existing features

If you want, you can still use postfix completion. For example, you type person.sout to print variable person to System.outSystem.out.println(person);.

You can transform this code to modern Java and use features introduced in Java 25, like simple IO. After the line System.out.println(person); type .. and select ..Replace with IO.println().

You can use refactoring, like Extract Method (⌥⌘M on macOS / Ctrl+Alt+M on Windows/Linux), even if you don’t remember the shortcut. To do so, type .. and select ..Extract method after the method you want to extract.

Refactor: Extract method

What if you want to add JavaDoc to your code? You could use Alt+Enter to Add JavaDoc. But now you can also use command completion to generate JavaDoc, and convert it to Markdown.

Command completion is as easy as adding a dot, or two..

As you can see, using command completion is as easy as adding a dot, or two..

Conclusion

Command completion extends regular completion – which you already use. It lets you discover and use IntelliJ IDEA features without having to remember shortcuts. This keeps you in the flow of coding; you can think about what you want to do, instead of how to do it.

Type a . to find commands as part of regular completion, or .. to see all available commands relevant to your current context.  You might discover powerful features you never knew were there!

Vibe coding an IntelliJ IDEA progress bar plugin for fun

In June, I presented the talk Learning modern Java the playful way with Piotr Przybył at Devoxx Poland 2025. For this presentation, I thought it would be funny to have a custom progress bar running in IntelliJ IDEA during our demos. Since we adapted our presentation to the Polish audience a little, I figured a Polish flag and #PolishSmile would be appropriate.

Creating an IntelliJ IDEA plugin

As I had never implemented an IntelliJ IDEA plugin before, I had no idea how hard it would be. When I asked my colleague, Anton Arhipov, he suggested using Junie to vibe code it. And given that this was just a fun idea for a plugin intended to be used only once, it was the perfect candidate for vibe coding: We don’t care that much about the code quality, since we won’t be maintaining it. All we need is for the plugin to work.

We started a new project using the Plugin template on GitHub. While Junie may or may not be able to do the configuration for such a project, there is a deterministic template available; why not use that? 

When you open the project, IntelliJ IDEA will show a popup Suggested plugin Plugin DevKit available. Clicking the button Configure plugins will open Settings | Plugins with this plugin selected and the option to Install it. 

Using Junie for vibe coding

Then we started with a prompt asking Junie to implement the plugin similar to the Nyan Progress Bar plugin. The prompt we used was as follows:

“Please implement a progress bar plugin similar to the nyancat progress bar. Instead of Nyancat I want it to display a Polish flag on the progress bar instead of the rainbow and a neutral smile emoji instead of the nyan cat. PLease suggest a detailed implementation plan and implement the plugin.” 

Junie correctly identified that no implementation was available and set about creating one. Before doing so, it first scanned the project and looked at the README and plugin.xml, correctly identifying that “the project is based on an IntelliJ platform plugin template”.

The plugin template project includes multiple Gradle goals, including runIDE; which allows you to run your plugin on an instance of the IDE so that you can try it out. This is perfect for our vibecoded project, since all we care about is whether the plugin does what we want. 

When Junie is done, it will say so in the Junie tool window and give an overview of files that were changed. The links to the files are clickable, if you want to look at the diff for these files.

First results

The first implementation of the progress was a step in the right direction but not quite what we wanted. Instead of a continuous Polish flag, it showed only small sections of white and red. Also, while the code referenced an icon, no icon was available, so we had to download a Polish smile emoji ourselves and add it to the project in the right location. We also had to manually resize this image to fit the progress bar, which unfortunately made it slightly pixelated… 

One of the things I like about Junie is that it can to build your project, and will try to fix any issues if the project doesn’t build successfully. It might not try to do so every time (AI is non-deterministic after all), so if it doesn’t you might want to add something to your `.junie/guidelines.md` along the lines of “DO make sure the project builds successfully.

Also, Junie might stop if it cannot resolve issues in several tries. This is usually a hint to either break up the task into smaller pieces and/or provide more detailed information.

In our example, we tried prompting Junie to make the Polish flag on the progress bar continuous, but with no luck. We used the following follow up prompt: 

“i want the brogress bar to be continuous and smooth and it should move 5 times slower”.

(Note that even though the prompt has typos, Junie doesn’t seem to mind.)

Providing a code example for better results

Unfortunately, this prompt did not have the desired outcome. Instead, Anton had the idea to take part of the Nyan Progress Bar plugin implementation and provide that code to Junie as an example to work with.  We did so and used the following prompt: 

“analyze the code in NyanCatProgressBar.txt (it is in Java) and create PolishFlagBProgressBar in Kotlin by following the same logic but with the polish flag colors”

This turned out to be a great idea; the plugin showed a continuous Polish flag now. This goes to show that providing Junie with examples of what you want will lead to better results.

Unfortunately, the smiley still jumped up and down on the progress bar, which is not what I wanted. But I figured it was good enough for a plugin I would only use for fun anyway. It wasn’t until after the conference that I realised that the smiley jumped up and down because that is what the Nyan Cat does in the Nyan Progress Bar. It took me five minutes to prompt Junie to fix this.

The next challenge was to build the plugin in a way that I could install it in IntelliJ IDEA from disk (as I had no plans to publish the plugin). A plugin project can be built using the task buildPlugin. Unfortunately this didn’t work for our project. It took several tries to get Junie to fix it, but I have to say that I was impressed that Junie fixed my Gradle problem.

Installing the plugin

Once the project was built successfully, I could install it. To install a plugin from disk, open Settings (⌘,  on macOS) / Ctrl+Alt+S on Windows/Linux) and go to Plugins. On the Plugins page, next to Marketplace and Installed, click the icon to Manage Repositories, Configure Proxy or Install Plugin from Disk. From the menu, select Install Plugin from Disk, and select the .jar file for the built plugin from your file system.

Uninstalling the plugin

When it came time to uninstall the plugin, I found that I had trouble doing so. Fortunately my colleagues were able to provide a workaround. To manually uninstall the plugin, delete the plugin from the plugins main directory, which you can find in Help | Diagnostic Tools | Special Files And Folders.

Results

Remember, this plugin is not meant to be published to the marketplace. However, if you’re interested in the code, you can find it here.

Overall, it was fun vibe code something silly with Junie and I am happy with the result. Also, it turns out, I could actually reuse the plugin when speaking in Poland again.

For the record: How to format records in IntelliJ IDEA

Recently my friend Piotr posted a question on social media about how to format records in IntelliJ IDEA…

How to format records

Sidenote: I don’t know why he wouldn’t just ask me directly, but I guess this was more fun 😉

Configuring code style

IntelliJ IDEA can format your code for you. Code will be formatted as you type it, and if needed you can Reformat the code (⌘⌥L on macOS) / Ctrl+Alt+L on Windows/Linux). If the (pre)defined code style isn’t to your liking, you can change it.

By default, IntelliJ IDEA will format records with the curly braces {} on two lines. When you apply Reformat to a record, IntelliJ IDEA will let you know “No lines changed: content is already properly formatted”.

Content is already properly formatted

To change the formatting for records so that the curly braces {} will be on the same line, open Settings (⌘, on macOS / Ctrl+Alt+S on Windows/Linux) and go to Editor | Code style | Java. Open the tab Wrapping and Braces and in the section Keep when reformatting select the option Simple classes in one line. Don’t forget to Save Changes.

Settings – Code style

Now if we have any code with a record (or any other simple class), we can use the Reformat the code (⌘⌥L on macOS) / Ctrl+Alt+L on Windows/Linux) to reformat the simple class accordingly. Note that you’ll need to use the shortcut twice to remove custom line breaks.

The same formatting will be applied in other situations. For example, when we add another record to the file, and use Complete Current Statement (⌃⇧⏎ on macOS / Ctrl+Shift+Enter on Windows/Linux), our new record will be completed with the curly braces {} on one line. 

What about generating a new Record?

From the Project tool window, we can generate a new record. Use Generate New (⌘N  on macOS / Alt+Ins on Windows/Linux) and select Java class. In the New Java Class dialog, type the name of your new record, and select Record. Note this record is still generated with the curly braces {} on 2 lines.

To make sure a newly created record is also formatted with the curly braces {} on one line, we can change the File template for Record.

Open Settings (⌘, on macOS / Ctrl+Alt+S on Windows/Linux) and go to Editor | Code style | File and Code Templates. Open the template for Record and change the template to have the curly braces {} on one line. Again, don’t forget to Save Changes.

File and Code Templates – Record

Now when we generate a new record it will be formatted with the curly braces {} on one line.

Note that changing only the File Template for Record is not enough to format records with the curly braces {} on one line. For one, it will be immediately reformatted upon creation according to the code style, as long as the Reformat according to style box is checked for this file template. Even if we uncheck this option, reformatting a file with a record would reformat it to the code style (which by default is {} on 2 lines).

Links