Since its appearance, Java has built up a relatively negative reputation, especially as higher-level languages and frameworks started to take hold. Despite that, Java still ranks among the top 5 in IEEE Spectrum's default ranking in 2022 and among the top 3 in GitHub's top programming languages in 2022.
So that begs the question: "Is it still worth learning Java?" Which may also lead to another question for some: "I learned and used Java before, but left it because of [insert one or more reasons here]. Does it still matter?" In my opinion, the answer to both questions are: definitely yes.
In this post, we will be focusing on the latter of the questions above. We will take a quick look into Java's newer versions before diving into creating a new web application with one of the newer frameworks out there.
Java has matured even more
In my personal experience, I started with Java between versions 6 and 7 (does that age me?). Shortly after I was exposed to Android development and shifted to non-Java development. Since then, Java has advanced over 10 major versions and the next version is only two months away at the time of writing. Some of the more significant changes from versions 8 to 17 can be seen here.
Also at the time of writing, there are currently 3 LTS (long-term support) versions that exist simultaneously: versions 8, 11 and 17. The next LTS version, 21, is also slated to release in less than a year. In my opinion, version 8 is the, sort of, transitional version for those who have large code bases to upgrade. There were minor changes and upgrades, but the migration should be easily doable. Then came Java 11. You can see the drastic changes just by looking at Oracle's official migration documentation. Many modules and APIs were deprecated, updated and removed. Since we're starting from scratch and don't want to start with technical debt, we'll choose Java 17.
Choosing a version was easy, but installing can be difficult. Thankfully, we have a tool called SDKMAN! (the
! is part of the name and I'm not that excited about open source) which helps us install and manage our Java versions. Similar to
nvm in the Python, Ruby and Node.js worlds, respectively, this helps download, install and manage different Java versions as well as install a number of a number of other Java libraries and SDKs.
A few new features of note
To demonstrate a few of Java’s latest features, we have a snippet below. All the features make using Java less verbose and maybe even more fun to use.
What we're going to build
For this post, and a subsequent post, we'll be focusing on creating an application with a framework as a base. We will then create a REST web application with CRUD (create, read, update, delete) functionality and database integration with Hibernate ORM. In the end, we will have a fully functional, database-backed application which can be deployed in a number of different ways thanks to the framework of choice, but we can discuss that in a later section.
Getting set up
First we'll need to install SDKMAN!. For this and the rest of the command line snippets, we'll be assuming you are on a Linux or MacOS terminal:
# Same instructions as on the SDKMAN install link above $ curl -s "https://get.sdkman.io" | bash $ sdk version SDKMAN 5.16.0
For our Java version, we will be using OpenJDK from
jdk.java.net. This distribution is the official reference implementation of Java since 7 and is GPLv2 licensed. Conversely, you could use the official Oracle distribution, but it is available under a non-open-source license. There are a number of other JDK distributions made for different situations, but we'll be using the official java.net version to keep it simple. You can see the other available versions here or enter
sdk list java in your terminal.
$ sdk install java 17-open [...] Installing: java 17-open Done installing! Setting java 17-open as default.
Let's double-check which version we have:
$ java -version openjdk version "17" 2021-09-14 OpenJDK Runtime Environment (build 17+35-2724) OpenJDK 64-Bit Server VM (build 17+35-2724, mixed mode, sharing)
Your development environment
If it's been a long time since you've developed in Java, you may have used the Eclipse IDE or NetBeans IDE. Feel free to use either of those, or any other IDE you're comfortable with. For this, and a future post, an IDE screenshots will be from JetBrains' IntelliJ IDEA.
The start of our application
For this example application, we will be using Quarkus. According to their about page:
Quarkus is a Kubernetes-native Java framework tailored for GraalVM and HotSpot, crafted from best-of-breed Java libraries and standards.
Does that mean anything for us right now? Not really. What do we need to know now? It runs fast and development is simpler with the tools Quarkus provides.
There are a few other Java frameworks that provide features similar to Quarkus, such as Micronaut and Spring Boot. If you are already familiar with the Spring ecosystem, Spring Boot can be a better choice for you. Micronaut is also aimed at "being small and running fast" like Quarkus, however, it is also built to be more familiar for Spring developers. One caveat: both Quarkus and Micronaut are only a few years old and may not be as mature in some areas, so it's best to check each framework to see which fits your project's needs.
For now, our needs are minimal and we'll move on with Quarkus. Let's install it:
# You can install via their install script $ curl -Ls https://sh.jbang.dev | bash -s - trust add https://repo1.maven.org/maven2/io/quarkus/quarkus-cli/ $ curl -Ls https://sh.jbang.dev | bash -s - app install --fresh --force quarkus@quarkusio # Or, since we have SDKMAN already installed, SDKMAN $ sdk install quarkus
Double-checking our install:
$ quarkus Quarkus CLI version 2.16.1.Final Create Quarkus projects with Maven, Gradle, or JBang. Manage extensions and source registries. Create: quarkus create Iterate: quarkus dev Build and test: quarkus build [...]
And now we use
quarkus to help generate our starting point:
# We are specifying Java 17 and using Maven for our build process. # `demo-todo` is our app name, which will also be the name of the directory. You can also use the format "com.example:app_name" if you also want to specify a group-id. $ quarkus create app \ --java=17 \ --maven \ demo-todo ----------- applying codestarts... 📚 java 🔨 maven 📦 quarkus 📝 config-properties 🔧 dockerfiles 🔧 maven-wrapper 🚀 resteasy-reactive-codestart ----------- [SUCCESS] ✅ quarkus project has been successfully generated in: --> /java/quarkus/demo-todo ----------- Navigate into this directory and get started: quarkus dev
Running your Quarkus app
At the start, your Quarkus app is completely working. We can see it in action by running the command at the end of our output above:
$ quarkus dev # alternatively, you can use the Maven wrapper that's provided # `./mvnw compile quarkus:dev` $ quarkus dev --2023-02-01 10:12:06-- https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar Resolving repo.maven.apache.org (repo.maven.apache.org)... 126.96.36.199 Connecting to repo.maven.apache.org (repo.maven.apache.org)|188.8.131.52|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 58727 (57K) [application/java-archive] Saving to: ‘/java/quarkus/demo-todo/.mvn/wrapper/maven-wrapper.jar’ /java/quarkus/demo-todo/.mvn/wrapper 100%[====================================================================================================================================>] 57.35K --.-KB/s in 0.02s 2023-02-01 10:12:06 (2.43 MB/s) - ‘/java/quarkus/demo-todo/.mvn/wrapper/maven-wrapper.jar’ saved [58727/58727] [INFO] Scanning for projects... [INFO] [INFO] -----------------------< com.example:demo-todo >------------------------ [INFO] Building demo-todo 0.0.1 [INFO] --------------------------------[ jar ]--------------------------------- [...] Listening for transport dt_socket at address: 5005 __ ____ __ _____ ___ __ ____ ______ --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ --\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 2023-02-01 10:35:41,634 INFO [io.quarkus] (Quarkus Main Thread) demo-todo 0.0.1 on JVM (powered by Quarkus 2.16.1.Final) started in 0.892s. Listening on: http://localhost:8080 2023-02-01 10:35:41,642 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated. 2023-02-01 10:35:41,642 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy-reactive, smallrye-context-propagation, vertx] -- Tests paused Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
Initially, you'll see a lot of output as Maven downloads and builds dependencies that the app needs. After all of that's done, you can see near the end:
Listening on: http://localhost:8080. Quarkus comes prepackaged with a built-in developer mode. Visiting that URL above on your favorite web browser and you'll get something similar to what we have below:
And visiting the dev UI will give you:
There's a lot to take in here, so feel free to look around and see what the framework provides out of the box. Keep in mind that you customize your initial app (making it as minimal as possible or even as big as possible) by changing a few switches on the
quarkus create app .
You can also see what's available to install as an extension with
./mvnw quarkus:list-extensions while in your project directory:
$ ./mvnw quarkus:list-extensions [INFO] Scanning for projects... [INFO] [INFO] -----------------------< com.example:demo-todo >------------------------ [INFO] Building demo-todo 0.0.1 [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- quarkus-maven-plugin:2.16.1.Final:list-extensions (default-cli) @ demo-todo --- [INFO] Current Quarkus extensions available: [INFO] [INFO] ✬ ArtifactId Extension Name [INFO] ✬ blaze-persistence-integration-quarkus Blaze-Persistence [INFO] ✬ camel-quarkus-activemq Camel ActiveMQ [INFO] ✬ camel-quarkus-amqp Camel AMQP [INFO] ✬ camel-quarkus-arangodb Camel ArangoDb [INFO] ✬ camel-quarkus-as2 Camel AS2 [...] [INFO] ✬ quarkus-webjars-locator WebJar Locator [INFO] ✬ quarkus-websockets WebSockets [INFO] ✬ quarkus-websockets-client WebSockets Client [INFO] quarkus-xmlsec Santuario XML Security [INFO] quarkus-zeebe Quarkus - Zeebe - Runtime [INFO] quarkus-zookeeper Zookeeper [INFO] ✬ runtime-tools-quarkus-extension Kogito Runtime Tools [INFO] [INFO] To get more information, append `-Dformat=full` to your command line. [INFO] [INFO] To list only extensions from specific category, append `-Dcategory="categoryId"` to your command line. [INFO] [INFO] Add an extension to your project by adding the dependency to your pom.xml or use `./mvnw quarkus:add-extension -Dextensions="artifactId"`
For the app itself, (make sure it's still running), we can see the list of endpoints from our dev UI (or visit: http://localhost:8080/q/dev/io.quarkus.quarkus-resteasy-reactive/endpoints). And below we can see it in action:
$ curl -i http://localhost:8080/hello HTTP/1.1 200 OK Content-Type: text/plain;charset=UTF-8 content-length: 28 Hello from RESTEasy Reactive
In this post we've taken a quick look at Java's history and Java's present. We got our machine set up with SDKMAN! , Java 17 and Quarkus and finally got a Quarkus starter app running. In the next post we will take a closer look at Quarkus, its extensions and how they all tie together and work in concert. If you'd rather not wait, Quarkus's documentation and guides are also very helpful, but have a few areas (in my opinion) that are worth a second look -- and will be covered in the next post.
Here at Anvil engineering, we've been looking at the exciting possibilities and improvements provided by the next generation of Java versions and frameworks. We have examples available for using the Anvil API in Java for those looking to integrate PDF filling or e-signing capabilities into their own Java projects. We hope this post has helped you get started on your next Java/Quarkus application and hope to see you again on the next post. If you have any questions or comments, drop us a message at email@example.com.