building "what you needed" with Java and the road to linkblogis available for download.
Jakarta Data API is a powerful specification that simplifies data access across a variety of database types, including relational and NoSQL databases. In this article you will learn how to leverage this programming model which will be part of Jakarta 11 bundle. Overview of Jakarta Data API Jakarta.Data API: Offers a higher-level abstraction for data ... Read more
The post Getting Started with Jakarta Data API appeared first on Mastertheboss.
Welcome to issue number two hundred and twenty-one of Hashtag Jakarta EE!
The work with Jakarta EE 11 is chugging along, and we are approaching the deadline for component specifications to engage in release reviews to be a part of Milestone 3. Talking about milestones, Jakarta EE 11 Milestone 2 will be available shortly. The reason why it is not available just yet is that we need all component specifications to be released to Maven Central before we can push the button. This will happen as soon as the release reviews have concluded. The current status of these reviews are:
Release Review in progress:
– Jakarta Contexts and Dependency Injection 4.1
– Jakarta Expression Language 6.0
– Jakarta Interceptors 2.2
Release Review about to start:
– Jakarta Annotations 3.0
The release review for Jakarta Annotations can start as soon as there is a compatible implementation that passes the TCK on Java 17. Eclipse GlassFish 8.0.0-M3 passes on Java 21. It looks like the next beta release of Open Liberty will include the Jakarta Annotations 3.0 API and be used as a compatible implementation for ratification along with GlassFish.
The 2024 Jakarta EE Developer Survey is open until May 31, 2024, but there is no need to wait. Take a couple of minutes and provide your valuable insights. By completing the survey, you can win a wonderful Jakarta EE T-shirt!
Subscribe to airhacks.fm podcast via: spotify| iTunes| RSS
building "what you needed" with Java and the road to linkblogis available for download.
It was a great evening with the Belgian JUG in Hasselt yesterday, the first time in the Limburg area! The BeJUG tours different cities and regions in Belgium with an even every month. This is a great concept as it unites the Java communities in the different cities that works especially well in Belgium where each corner of the country is reachable within a couple of hours.
You can’t visit Belgium without having fries. This time they had food truck serving fries outside before the talks. First up was Simon Verhoeven who did a walkthrough of the new features in Java 22. Very well timed since Java 22 was released yesterday.
I upgraded in the hotel before heading to the event since I like to always be on the latest version. As expected, Jakarta EE 11 works fine on Java 22! I have done the talk Prepare for Jakarta EE 11 – Performance and Developer Productivity a couple of times now, but never exactly the same as I keep the slides and content aligned with the progress of the release.
Subscribe to airhacks.fm podcast via: spotify| iTunes| RSS
the differences between Project Panama and JNI, Java's GPU optimizations and Code Reflectionis available for download.
This article will teach you how to use a plain Datasource resource in a Quarkus application. We will create a simple REST Endpoint and inject a Datasource in it to extract the java.sql.Connection object. We will also learn how to configure the Datasource pool size. Quarkus Connection Pool Quarkus uses Agroal as connection pool implementation ... Read more
The post How to use a Datasource in Quarkus appeared first on Mastertheboss.
In this tutorial, we’ll explore the database modeling aspect of a small blog using PlantUML. We’ll start by defining the tables and their attributes, then establish relationships between them based on the provided database model.
Let’s review the database model for our small blog:
Now, let’s represent the database model using PlantUML:
@startuml !define primary_key(x) <b><color:#b8861b><&key></color> x</b> !define foreign_key(x) <color:#aaaaaa><&key></color> x !define column(x) <color:#efefef><&media-record></color> x !define table(x) entity x << (T, white) >> table(Posts) { primary_key(id): UUID <<PK>> -- column(title): VARCHAR(255) NOT NULL column(slug): VARCHAR(255) <<U>> column(content): TEXT column(excerpt): TEXT column(publish_date): DATETIME column(is_published): BOOLEAN foreign_key(author_id): UUID <<FK>> } table(Authors) { primary_key(id): UUID <<PK>> -- column(username): VARCHAR(255) NOT NULL <<U>> column(email): VARCHAR(255) NOT NULL <<U>> column(password): VARCHAR(255) } table(Comments) { primary_key(id): UUID <<PK>> -- foreign_key(post_id): UUID <<FK>> column(author_name): VARCHAR(255) column(author_email): VARCHAR(255) column(content): TEXT column(comment_date): DATETIME } table(Tags) { primary_key(id): UUID <<PK>> -- column(name): VARCHAR(255) <<U>> } table(PostTags) { primary_key("post_id, tag_id"): UUID <<PK>> -- foreign_key(post_id): UUID <<FK>> foreign_key(tag_id): UUID <<FK>> } Posts }|..|| Authors note left of Authors: This is 1 to Many \n Posts.author_id <-> Authors.Ide Comments }|..|| Posts PostTags }|..|| Posts PostTags }|..|| Tags @enduml
After execution the diagram should look like the following
Let’s break down the PlantUML code step by step:
primary_key
): This macro defines the styling for primary key columns. It uses HTML formatting to display the key icon in bold and a specified color (#b8861b).Example: primary_key(id): UUID <<PK>>
foreign_key
): Similar to the primary key macro, this defines the styling for foreign key columns. It displays the key icon in a specified color (#aaaaaa).Example: foreign_key(author_id): UUID <<FK>>
column
): This macro defines the styling for regular columns. It displays a media-record icon in a specified color (#efefef).Example: column(title): VARCHAR(255) NOT NULL
table
): This macro defines the styling for tables. It sets the background color to white.Example: table(Posts) { ... }
Posts
): This table represents blog posts. It contains columns for primary key (id
), title (title
), slug (slug
), content (content
), excerpt (excerpt
), publish date (publish_date
), and a boolean flag for publication status (is_published
). The author_id
column is a foreign key referencing the Authors
table.Authors
): This table stores information about blog authors. It includes columns for primary key (id
), username (username
), email (email
), and password (password
). Both username
and email
are marked as unique to ensure data integrity.Comments
): This table contains comments left by users on blog posts. It includes columns for primary key (id
), foreign key referencing the Posts
table (post_id
), author name (author_name
), author email (author_email
), content (content
), and comment date (comment_date
).Tags
): This table stores tags associated with blog posts. It includes columns for primary key (id
) and tag name (name
). The name
column is marked as unique to ensure each tag is unique.PostTags
): This table serves as a join table to establish a many-to-many relationship between posts and tags. It includes composite primary key (post_id, tag_id
) and foreign keys referencing the Posts
and Tags
tables, respectively.author_id
column in the Posts
table references the id
column in the Authors
table.post_id
column in the Comments
table references the id
column in the Posts
table.PostTags
join table.PostTags
join table.In this tutorial, we’ve explored the PlantUML code for modeling the database structure of a blog. By understanding the macros, table definitions, and relationships within the code, you’ll be better equipped to visualize and customize your database model.
DevNexus is the longest-running and largest Java Conference in the US. It’s organised by a vibrant Java community who are passionate about enabling education for all and empowering the Java developer community. Last year’s event brought more than 1400 developers together from all over the world, and more than 90 speakers shared their knowledge on exciting, trending topics like software architecture, core Java, Kubernetes, and security.
You can see more of the 2023 highlights in this promo video. For those of you who are keen eyed, you might even spot our very own Liberty Space Rover!
This year the event is being held in downtown Atlanta at the Georgia World Congress Center from April 9th-11th and tickets are already sold out! It’s sure to be an awesome event, with 145 international speakers taking the stage.
This year we are excited to have our very own Open Liberty booth as well as having members of the Open Liberty team on site hosting sessions, quick labs, workshops, and running demonstrations at the IBM, MicroProfile and Jakarta EE booths.
We’re honoured to have a booth alongside other open source projects like MicroProfile, Jakarta EE, and PostgresSQL. Having our own booth gives attendees the opportunity to come and meet the people behind the technology and offers the chance to ask questions and learn more about these amazing open source projects!
So, if you’re coming to DevNexus, be sure to pop by our Open Liberty booth in the breaks and say hi. You may even get some cool Open Liberty swag!
The great part about attending a conference like DevNexus is the huge array of topics, sessions, and speakers presenting throughout the event. You have the chance to learn about everything from agile, architecture, and AI, through to cloud infrastructure, cloud technologies, and core Java/Jakarta EE. But with over 140 different sessions to choose from, and up to 13 sessions all occurring at the same time, how do you choose which sessions to attend?!
Deciding which sessions to see can be a real challenge! But to help make this easier, we’ve put together this guide of the sessions available on each day that focus on open source, cloud-native Java technologies, including Open Liberty, MicroProfile, Jakarta EE, and more. There’s also a dedicated Jakarta EE track this year, so make sure to check out those sessions.
Workshop: The Ultimate One-Day Java Workshop: Deploying AI-Enhanced Applications with Security & Scalability
This all-day workshop, led by 5 internationally renowned speakers, is sure to be a great hands-on learning experience. It bridges the gap between traditional Java application deployment and modern cloud-based solutions, offering participants a deep dive into the latest technologies, methodologies, and best practices, including the exciting realm of AI.
Time: 10:00-11:00
Jakarta EE guru Ivar Grimstad takes us on a journey to understand how the namespace change from javax.
to jakarta.
in Jakarta EE 9 impacted the entire Java ecosystem, the cool new features introduced in Jakarta EE 10, and the renewed focus on performance and developer productivity introduced in Jakarta EE 11.
Time: 11:30-12:30
Luis Neto showcases how Jakarta EE can help our applications constantly evolve to stay safe and remain secure, by defining a standard for creating secure enterprise Java applications, and innovating with each release to provide the best measures possible.
Time: 16:00-17:00
Join Java Champion Edwin Derks as he explores Jakarta EE, MicroProfile and application server runtimes and how they can provide the perfect tools to achieve optimal value when developing and running enterprise software.
Time: 17:00-18:00
Concerned about moving your applications from JEE 5 & 7 to Jakarta EE 10? Join this session by Alberto Salazar to understand the potential pitfalls and put away the concerns of updating and evolving your enterprise applications.
Time: 17:00-18:00
In this session, Rich Hagarty will dig into JITServer technology, showing the challenges of implementation, detailing its strengths and weaknesses, and illustrating its performance characteristics. For those interested in cloud native deployment, he will also show how to deploy it in containers, demonstrate its advantages compared to a traditional JIT compilation technique, and offer practical recommendations about when to use this technology.
Time: 10:00-11:00
This hands-on session will show you how to enable deployments of Jakarta EE applications using Open Liberty or WebSphere Liberty to the cloud with AI. With two Java champions presenting (Emily Jiang and Brian Benz), it’s sure to be a great session!
Time: 11:30-12:30
In this session, Jakarta Data committer Kyle Aure, will showcase the domain-driven repository pattern of the Jakarta Data project and highlight the query mechanism to utilize sorting, streaming, and paging. Using a live demo application, Kyle will swap out a relational database for a non-relational database to showcase just how easy this can now be with Jakarta Data!
Time: 11:30-12:30
OpenJDK’s Project Valhalla is set to revolutionize how the JVM handles data objects in memory. This talk offers an exploration of Valhalla’s objectives, progress, and its potential impact on the Java ecosystem with examples throughout. Join Theresa Mammarella in this session to discover how Project Valhalla is on the verge of reshaping the landscape of Java, paving the way for a more efficient and high-performing future.
Time: 13:30-14:30
Join Markus Kett and Java Champion Emily Jiang in this session to learn how the combinaton of Liberty InstantOn and EclipseStore enables Java applications to achieve the 3 most critical factors for cloud-native applicatons making use of AI, ML, VR, and big data in the cloud: high performance, low data storage costs, and simple, fast and cost-efficient implementation and maintenance.
Time: 13:30-14:30
Enabling applications to really thrive (and not just survive) in cloud environments can be challenging. The original 12 factor app methodology helped to lay out some of the key characteristics needed for cloud-native applications… but… as our cloud infrastructure and tooling has progressed, so too have these factors. In this session, Java Champion Grace Jansen will dive into the extended and updated 15 factors and take a look at open source technologies and tools that can help us achieve this.
Time: 16:00-17:00
Java guru Michael Redlich presents this session providing a history of JavaEE/Jakarta EE and a review of new and updated specifications with code examples.
As well as the numerous sessions during the conference and our dedicated Open Liberty booth, the Open Liberty team will also be manning the IBM booth in the exhibition hall. Stop by to catch our in-booth theatre with a series of SmartTalks, grab some awesome swag, and have a chat about all things OSS Java. We’d love to see you there!
This year, we’ll also have our exciting intergalactic booth challenge… The Open Liberty Space Rover Challenge. In this challenge, you’ll need to navigate the planets and get your rover safely to your destination in the stars. Take control of a spaceship and use hand signals to direct it’s flight from planet to planet. Climb the rankings on your way to become top cadet in Star Academy. While you’re with us, ask our developers about the underlying technologies they’ve used to create the demo, including OpenJ9, Jakarta EE, MicroProfile, and "the most flexible runtime in the cosmos", Open Liberty.
We hope this guide helps you to plan your time at DevNexus. If you’re interested in other sessions, check out the full schedule on the DevNexus conference website.
This article will detail how to get started quickly with Jakarta EE which is the new reference specification for Java Enterprise API. As most of you probably know, the Java EE moved from Oracle to the Eclipse Foundation under the Eclipse Enterprise for Java (EE4J) project. There are already a list of application servers which ... Read more
The post Getting started with Jakarta EE appeared first on Mastertheboss.
This tutorial will teach you how to run WildFly applications on Openshift using WildFly S2I images. At first, we will learn how to build and deploy applications using Helm Charts. Then, we will learn how to use the S2I legacy approach which relies on ImageStreams and Templates. WildFly Cloud deployments There are two main strategies ... Read more
The post How to run WildFly on Openshift appeared first on Mastertheboss.
The post FetchType: Lazy/Eager loading for Hibernate & JPA appeared first on Thorben Janssen.
Choosing the right FetchType is one of the most important decisions when defining your entity mapping. It specifies when your JPA implementation, e.g., Hibernate, fetches associated entities from the database. You can choose between EAGER and LAZY loading. The first one fetches an association immediately, and the other only when you use it. I explain...
The post FetchType: Lazy/Eager loading for Hibernate & JPA appeared first on Thorben Janssen.
Setting up a GlassFish server cluster with an Apache HTTP server as a load balancer involves several steps:
We’ll assume that you’ve already configured GlassFish for clustering. If you haven’t done so, you can follow our guide on how to set up a GlassFish cluster to prepare your own GlassFish cluster. After you’ve prepared it, this tutorial will guide you to configure Apache HTTP Server as a load balancer with sticky sessions.
Install Apache HTTP Server on a machine that will act as the load balancer. This should be a separate machine from machines that run GlassFish cluster instances, mainly for security reasons. While your cluster should be accessible through the Apache server, GlassFish cluster instances shouldn’t be accessible publicly. Therefore, you should configure your firewall or networking rules to only allow access to GlassFish instances only from the Apache server.
On Apt-based systems, like Ubuntu or Debian, you can install Apache HTTP Server from the system repository with the following commands:
sudo apt update
sudo apt install apache2
Enable the necessary proxy modules (proxy
, proxy_http
, proxy_balancer
, and lbmethod_byrequests
modules) in Apache server:
sudo a2enmod proxy
sudo a2enmod proxy_http
sudo a2enmod proxy_balancer
sudo a2enmod lbmethod_byrequests
Edit the Apache configuration file (usually located at /etc/apache2/sites-available/000-default.conf
) and add the following configuration:
<VirtualHost *:80>
# Basic server configuration, use appropriate values according to your set up
ServerAdmin webmaster@localhost
ServerName yourdomain.com
# access and error log files
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# Forward requests through the load balancer named "balancer://glassfishcluster/"
# Uses the JSESSIONID cookie to stick the sesstion to an appropriate GlassFish instance
ProxyPass / balancer://glassfishcluster/ stickysession=JSESSIONID failontimeout=On
ProxyPassReverse / balancer://glassfishcluster/
# Configuration of the load balancer and GlassFish instances connected to it
<Proxy balancer://glassfishcluster>
ProxySet lbmethod=byrequests
BalancerMember http://glassfish1:28080 route=instance1 timeout=10 retry=60
BalancerMember http://glassfish2:28080 route=remoteInstance timeout=10 retry=60
# Add more BalancerMembers for additional GlassFish instances
</Proxy>
</VirtualHost>
Replace the following according to your actual setup:
yourdomain.com
– the domain name of your application (the DNS record should point to the Apache server) glassfish1
– hostname or IP address of your GlassFish instance with name instance1
glassfish2
– hostname or IP address of your GlassFish instance with name remoteInstance
instance1
, remoteInstance
– names of your GlassFish instances. If you use different names, adjust them here and make sure that the jvmRoute
system property on GlassFish instances is set to the same instance name Note that:
route
arguments of BalancerMember
must be GlassFish instance names matching that member (values set by the jvmRoute
system property). The value of the jvmRoute
system property should be defined in the GlassFish cluster configuration to the value of ${com.sun.aas.instanceName}
to reflect the GlassFish instance name. This value will then be added to the session cookie so that the Apache loadbalancer can match a cookie with the right GlassFish instance.failontimeout=On
, the load balancer waits at most 10 seconds for the request to complete. If it takes longer, it considers the GlassFish instance as unresponsive and fails over to another instance to process the request. This is to consider GlassFish instances that are stuck (e.g. when out of available memory) as inactive. If some requests take more time to complete, either disable this option, or increase the timeout
arguments on BalancerMemberJSESSIONID
with your custom cookie nameVerify that:
Restart Apache to enable the new modules and apply the configuration changes.
On an operating system that uses SystemD services (e.g. Ubuntu):
sudo systemctl restart apache2
Test your setup by accessing your application through the Apache load balancer. Verify that sticky sessions are working, ensuring that requests within the same session are directed to the same GlassFish instance and requests without a session are routed to a random instance.
You can use the test cluster application available at https://github.com/OmniFish-EE/clusterjsp/releases:
With these steps, you should have a basic setup of a GlassFish server cluster
In case of an issue with a GlassFish instance, the load balancer should stop sending requests to that instance and keep using the remaining GlassFish instances in the cluster. Once the GlassFish instance recovers from issues, it will rejoin the load balancer and will start receiving requests again.
You can also rely on this mechanism when you need to restart the cluster; instead of restarting the whole cluster at once, you can restart GlassFish instances one by one. While one of the instances is being restarted, Apache server will continue sending requests to the other instances.
In this article we will learn how to create and run a sample Quarkus 3 application which uses Hibernate ORM and JPA. We will create a sample REST Endpoint to expose the basic CRUD operations against a relational Database such as PostgreSQL. Create the Quarkus Project Firstly, create a basic Quarkus project first. For example, ... Read more
The post Getting started with Quarkus and Hibernate appeared first on Mastertheboss.
The post How to generate DAOs and queries with Hibernate appeared first on Thorben Janssen.
Executing a query with Hibernate requires several lines of repetitive boilerplate code, and many developers have complained about that for years. You have to instantiate a Query object and set all bind parameter values before you can finally execute the query. Since version 6.3.1, Hibernate has solved this with an improved metamodel generator that provides...
The post How to generate DAOs and queries with Hibernate appeared first on Thorben Janssen.
The error message “0/1 nodes are available: 1 Insufficient memory. preemption: 0/1 nodes are available: 1 No preemption victims found for incoming pod.” indicates your pod can’t be scheduled due to memory constraints. Here are the steps to address this issue- Investigate Memory Usage Firstly, check the current Memory Usage of the OpenShift Node where ... Read more
The post Solving 0/1 nodes are available: 1 Insufficient memory appeared first on Mastertheboss.
Whether you’re a beginner exploring OpenShift for the first time or an experienced user looking for quick references, this cheat sheet is designed to provide you with a CheatSheet of OpenShift commands, concepts, and best practices. From managing pods and services to setting up routes and exploring advanced deployment strategies, we’ve got you covered. Login ... Read more
The post Openshift Cheatsheet for DevOps appeared first on Mastertheboss.
This tutorial will guide you to set up a GlassFish cluster that serves a single application on multiple machines.
This setup doesn’t enable HTTP session replication. Session data will be available only on the original cluster instance that created it. Therefore, if you access the cluster instances through a load balancer server, you should enable sticky session support on the load balancer server. With this mechanism, a single user will be always served by the same GlassFish instance, different users (HTTP sessions) may be served by different GlassFish instances. It’s also possible to configure session replication in a GlassFish cluster so that each session is available on each instance but this is not covered by this tutorial.
bin
directory of your GlassFish installation.asadmin start-domain
myCluster
)instance1
as an instance name, keep “Node” selected to the default “localhost-domain1”This will create a clustering configuration myCluster
in GlassFish, with one GlassFish server instance instance1
, which runs on the same machine as the GlassFish administration server (DAS).
Clusters → myCluster
This configuration is needed to simplify the sticky session routing mechanism in load balancers, e.g. in Apache HTTP server.
This will navigate you to the welcome page of the instance1
GlassFish instance running on port 28080.
Deploy a cluster tester application, which you can download from https://github.com/OmniFish-EE/clusterjsp/releases.
Applications
and click the “Deploy…”
buttonBrowse…
and select the application WAR fileRight now, there’s a single instance in the cluster. All requests are handled by that instance, session data is always present, and all should work as expected. As you’ll add more instances to the cluster, you can use this tester application again to verify that all works even if requests are sent to different instances.
Now, add a SSH connection to a remote server, where you want to run other GlassFish cluster instances.
This assumes that you already have a remote machine with SSH server and Java installed.
Make sure that GlassFish admin server can access the remote machine on the SSH port (port 22 by default). Then:
Nodes
. There’s always at least 1 node, e.g. localhost-domain1
, which represents the local machinesshNode1
).Clusters → myCluster
.remoteInstance
) and select the SSH node (sshNode1
) as the target “Node”.Make sure that the admin port of the remote instance is open for connections from GlassFish admin server and isn’t blocked by a firewall. The port number is 24848 by default. You can find it in GlassFish Admin Console:
Clusters → myCluster
, the tab “Instances”Without this, the admin server will be able to start the instance via SSH but will not be able to communicate with it or detect that it is running.
To start the new remote instance, you can start the cluster again, as you already did before. Starting a cluster if you already started it before will keep the “instance1” instance running, and will start all other instances which are not running.
Alternatively, you can start the remoteInstance
individually:
remoteInstance
and click on the “Start” button.This assumes that you’ve already set up a load balancer server, e.g. Apache HTTP server, and the load balancer is configured to support sticky sessions.
Access the tester application you deployed previously through the load balancer and verify that requests are load-balanced between the instances:
http://load-balancer-ip:load-balancer-port/cluster
Replace load-balancer-ip
and load-balancer-port
with the appropriate values for your load balancer server.
After everything is working, you can undeploy the test application clusterjsp
and deploy your own application. Remember to select your cluster as the deployment target, so that your application is deployed to all GlassFish instances in the cluster.
Before you deploy your application to the cluster, make sure that all resources that your application requires are deployed to the cluster too. For example, a JDBC resource:
Now, deploy your application to the cluster, similarly as you deployed the tester application before in the Step 5:
Applications
and click the “Deploy…”
buttonThat’s it! You have now created a GlassFish cluster with instances, added an SSH node, and created an instance on this node using the Admin Console. Your application is running on all instances of the cluster. Now you can set up a load balancer server (e.g. Apache HTTP Server) with sticky sessions to proxy incoming requests to GlassFish instances, which we’ll cover in a future article.
Last updated 2024-01-28 13:40:07 +0100
This article covers how to create sample random Data for your REST Services using a well-known library Data Faker. We will show how to bind a Fake Model to our Entity so that you can create sample Test Data in a snap! In the first article of this series ( Generating Random data for REST ... Read more
The post How to create Test Data in Jakarta EE applications appeared first on Mastertheboss.
Here is a list of OpenShift interview questions that can help you to prepare for a Cloud Interview where you will discuss about Red Hat OpenShift. OpenShift Architecture OpenShift Installation Openshift configuration What is an OpenShift project and how does it relate to application configuration? Answer: An OpenShift project is a logical unit that enables ... Read more
The post Openshift Interview Questions (2024) appeared first on Mastertheboss.
Several databases provide varying levels of support for JSON data, including storage, indexing, querying, and manipulation capabilities. In this article we will explore how to insert and fetch JSON Data using Jakarta Persistence API and WildFly. JSON Native Support in Relational Databases Several relational databases offer support for storing and manipulating JSON data as a ... Read more
The post How to store JSON Data with JPA and Hibernate appeared first on Mastertheboss.
This article provides a comparison of the features of two popular Java Enterprise Runtimes: WildFly Application Server and Quarkus framework. While both offer robust support for Java applications, their distinct approaches to development, deployment, and scalability cater to diverse use cases. Comparing Quarkus and WildFly. Fair comparison ? Firslty a disclaimer note: Comparing WildFly, a ... Read more
The post Quarkus vs WildFly Application Server appeared first on Mastertheboss.
In this article we will learn how to use the Java Multi-line feature and and we can combine it with String Templates to create complex Object structures such as JSON payloads or even JSON Objects! What is Java Multiline? The Java multiline feature, introduced in JDK 13, aims to enhance the readability and usability of ... Read more
The post Java Multi-line and String Templates in Action appeared first on Mastertheboss.
In the fast-paced world of software development, effective communication and clear documentation are paramount. This is where the power of visual representation comes into play, and one tool that has significantly simplified this process is PlantUML. This open-source project has revolutionized the way developers, project managers, and analysts create and share diagrams. It’s not just a tool; it’s a visual language that transforms the way we think about and document software architecture, processes, and workflows.
PlantUML stands out for its simplicity and efficiency. At its core, it’s a scripting language for creating diagrams. Unlike conventional diagramming tools that rely on a graphical interface, PlantUML allows users to describe diagrams using an intuitive and straightforward textual description. This text-based approach means diagrams can be easily version-controlled, shared, and edited, making collaboration seamless. PlantUML supports various types of diagrams, including sequence diagrams, use case diagrams, class diagrams, activity diagrams, component diagrams, state diagrams, and more, making it a versatile tool in the software development toolkit.
The importance of diagrams in software development and documentation cannot be overstated. They are the bridge between abstract concepts and their practical implementation. Diagrams provide a bird’s-eye view of complex systems, making it easier to understand, design, and communicate intricate software architecture and processes. They are essential for planning, explaining decisions, and onboarding new team members. In the realm of software engineering, where complexity is a given, diagrams are the lingua franca that ensures everyone, from developers to stakeholders, is on the same page.
This blog post is dedicated to exploring the depths of PlantUML with a particular focus on three key areas: sequence diagrams, component diagrams, and advanced theming.
Throughout this blog post, we aim to provide you with comprehensive knowledge, practical examples, and best practices to harness the full potential of PlantUML. Whether you’re a seasoned developer or just starting out, understanding how to effectively use PlantUML can elevate your documentation and improve your project’s communication and efficiency. Let’s embark on this journey to master the art of diagramming with PlantUML.
Sequence diagrams, integral to the Unified Modeling Language (UML), offer a dynamic modeling solution crucial in software development. They provide a clear visualization of how objects in a system interact over time, making them indispensable for understanding operational workflows and object interactions. These diagrams are particularly useful in depicting the sequence of messages and events between various parts of a system, which is essential for comprehending the flow of control and data within complex software architectures. By representing different entities as lifelines and their interactions as messages, sequence diagrams facilitate a detailed and temporal view of a system’s functionality, enabling developers and analysts to trace the sequence of events and interactions from start to end.
To create a basic sequence diagram in PlantUML, you start by defining the participants or objects involved. For instance, in a user authentication process, the primary actors might include a ‘User,’ an ‘Authenticator,’ and a ‘Database.’
Here’s a simple PlantUML script to illustrate this process:
@startuml actor User participant Authenticator database Database User -> Authenticator: Request Login Authenticator -> Database: Validate Credentials Database -> Authenticator: Credentials Valid Authenticator -> User: Authentication Result @enduml
The output is:
This script creates a sequence diagram where the ‘User’ sends a login request to the ‘Authenticator,’ which then interacts with the ‘Database’ to validate credentials. The database responds, and the authenticator communicates the result back to the user. Each arrow represents a message or interaction, with the direction indicating the flow.
PlantUML allows the addition of advanced features to sequence diagrams, such as loops, conditions, and concurrency. These elements add depth to the representation, making it possible to depict more complex scenarios.
For example, to introduce a condition in the authentication process, where the system retries the validation if credentials are incorrect, you can use an alt
frame:
@startuml actor User participant Authenticator database Database loop Authentication Attempt User -> Authenticator: Request Login Authenticator -> Database: Validate Credentials alt Credentials Valid Database -> Authenticator: Success Authenticator -> User: Authentication Successful else Credentials Invalid Database -> Authenticator: Failure Authenticator -> User: Retry Login end end loop @enduml
The output is:
In this enhanced diagram, the alt
frame introduces a conditional operation. If the credentials are valid, the process ends with a success message. If not, it prompts the user to retry login, and the loop continues until successful authentication.
Component diagrams are a cornerstone of software architecture visualization. These diagrams illustrate the modular structure of a system, highlighting how various parts, such as databases, user interfaces, or even entire subsystems, interrelate and interact. In PlantUML, crafting component diagrams is an art that combines technical accuracy with clarity. This section focuses on the creation of component diagrams, starting from basic concepts and progressively incorporating more complexity, including composite components.
Creating a component diagram in PlantUML begins with defining the system’s primary components. Let’s consider a simple web application comprising a Web Server, an Application Logic component, and a Database.
In PlantUML, this can be represented as:
@startuml component [Web Server] component [Application Logic] database [Database] [Web Server] --> [Application Logic] [Application Logic] --> [Database] @enduml
The output is:
This script represents a straightforward web application, where the Web Server communicates with the Application Logic, which in turn interacts with the Database. The arrows indicate the direction of communication between these components.
As systems grow in complexity, you might need to represent composite components—components that encapsulate other components or groups of components. For instance, in a microservices architecture, a composite component can represent an entire service that consists of multiple smaller components.
Let’s expand our previous example to include composite components. Assume the Application Logic is now a composite component containing two subcomponents: ‘User Management’ and ‘Order Processing’.
@startuml package "Web Application" { component [Web Server] package "Application Logic" { component [User Management] component [Order Processing] } database [Database] } [Web Server] --> [User Management] [Web Server] --> [Order Processing] [User Management] --> [Database] [Order Processing] --> [Database] @enduml
The output is:
In this enhanced diagram, ‘Application Logic’ is a composite component containing ‘User Management’ and ‘Order Processing’. The Web Server interacts separately with each subcomponent, while both subcomponents interact with the Database. This representation provides a clearer view of the system’s modular structure, showcasing how larger components are broken down into smaller, manageable parts.
For even more complex architectures, PlantUML allows you to depict dependencies, interfaces, and other intricate details. For example, in a microservices architecture, you might have services interacting via RESTful APIs or message queues.
Consider a scenario where the ‘Order Processing’ component communicates with an external ‘Payment Service’ via a REST API:
@startuml package "Web Application" { component [Web Server] package "Application Logic" { component [User Management] component [Order Processing] } database [Database] } [Order Processing] ..> [Payment Service] : REST API [Payment Service] ..> [Payment Gateway] : Uses cloud { [Payment Service] [Payment Gateway] } [Web Server] --> [User Management] [Web Server] --> [Order Processing] [User Management] --> [Database] [Order Processing] --> [Database] @enduml
The output is:
In this complex diagram, the ‘Order Processing’ component within the Application Logic uses a REST API to communicate with an external ‘Payment Service’, which in turn uses a ‘Payment Gateway’. This level of detail is invaluable in large-scale distributed systems, providing a comprehensive view of component interactions and dependencies.
Theming in PlantUML involves customizing the visual elements of diagrams, such as colors, fonts, and notes, to enhance readability and visual appeal. Effective theming can make complex diagrams more understandable and engaging. Basic theming involves setting global styles or individual element styles within the PlantUML script. For instance, you can change the color of components, background of notes, or the style of lines and arrows.
Here’s a simple example of applying basic theming to a sequence diagram:
@startuml skinparam sequenceArrowColor DeepSkyBlue skinparam sequenceActorBorderColor DarkSlateGray actor User participant Authenticator database Database User -> Authenticator: Request Login Authenticator -> Database: Validate Credentials Database -> Authenticator: Credentials Valid Authenticator -> User: Authentication Result @enduml
The output is:
In this script, sequenceArrowColor
and sequenceActorBorderColor
are used to customize the colors of the sequence diagram elements.
For advanced theming, PlantUML allows the creation of custom themes and styles using preprocessor directives and skin parameters. This feature is especially useful for applying consistent styling across multiple diagrams or for adhering to corporate branding guidelines.
To create a custom theme, you define a set of skin parameters in a separate file and then include this theme in your diagrams. For instance, you might have a ‘MyCustomTheme.iuml’ file with the following content:
!define MY_THEME_COLOR #3498db skinparam backgroundColor #f0f0f0 skinparam ArrowColor MY_THEME_COLOR skinparam ActorBorderColor MY_THEME_COLOR skinparam component { BackgroundColor #ecf0f1 ArrowColor MY_THEME_COLOR }
You can then include this theme in your diagrams using the !include
directive:
@startuml !include MyCustomTheme.iuml actor User participant Authenticator database Database ... // rest of the diagram @enduml
The final output is:
This approach allows for a high degree of customization and ensures consistent application of visual styles across different diagrams.
Let’s apply a custom theme to the microservices architecture component diagram created earlier. Assuming the theme file ‘MicroserviceTheme.iuml’ contains specific color and style definitions, the enhanced diagram script will look like this:
@startuml !include MicroserviceTheme.iuml package "Microservices Architecture" { [User Service] [Order Service] [Payment Service] [Database] } interface "User API" as UserAPI interface "Order API" as OrderAPI interface "Payment API" as PaymentAPI UserAPI ..> [User Service] OrderAPI ..> [Order Service] PaymentAPI ..> [Payment Service] [User Service] --> [Database]: Reads/Writes [Order Service] --> [Database]: Reads/Writes [Payment Service] --> [Database]: Reads/Writes @enduml
The final output is:
In this final version, the inclusion of the custom theme enhances the visual aesthetics and clarity of the diagram, making it more engaging and easier to interpret for the audience.
In this comprehensive guide, we’ve explored the power of PlantUML in creating sequence diagrams, component diagrams, and applying advanced theming. Whether you’re a developer, architect, or project manager, mastering these skills in PlantUML can significantly improve the clarity and effectiveness of your software documentation and architectural design. We encourage you to experiment with the examples provided, customize them to your needs, and explore the vast capabilities of PlantUML to elevate your diagramming skills to the next level.
Open Liberty 24.0.0.1-beta includes a preview of the new Jakarta Data specification for Jakarta EE, as it currently stands at Milestone 2. Milestone 2 provides API updates to pagination and various improvements to the Javadoc and specification text. You can try it out and give feedback on the specification so far.
See also previous Open Liberty beta blog posts.
Jakarta Data is a new Jakarta EE specification being developed in the open that standardizes the popular Data Repository pattern across a variety of providers. Open Liberty 24.0.0.1-beta includes the Jakarta Data 1.0 Milestone 2 release, which provides API updates to pagination and various improvements to the Javadoc and specification text. The Open Liberty beta includes a test implementation of Jakarta Data that we are using to experiment with proposed specification features so that developers can try out these features and provide feedback to influence the development of the Jakarta Data 1.0 specification beyond Milestone 2. The test implementation currently works with relational databases and operates by redirecting repository operations to the built-in Jakarta Persistence provider.
To use the pagination API to request pages of results in Jakarta Data, you need an Entity and a Repository.
Start by defining an entity class that corresponds to your data. With relational databases, the entity class corresponds to a database table and the entity properties (public methods and fields of the entity class) generally correspond to the columns of the table. An entity class can be:
annotated with jakarta.persistence.Entity
and related annotations from Jakarta Persistence
a Java class without entity annotations, in which case the primary key is inferred from an entity property named id
or ending with Id
and an entity property named version
designates an automatically incremented version column.
You define one or more repository interfaces for an entity, annotate those interfaces as @Repository
and inject them into components via @Inject
. The Jakarta Data provider supplies the implementation of the repository interface for you.
The following example shows a simple entity:
@Entity
public class Product {
@Id
public long id;
public String name;
public float price;
@Version
public long version;
}
The following example shows a repository that defines operations that relate to the entity. Your repository interface can inherit from built-in interfaces, such as BasicRepository
and CrudRepository
, to gain a variety of general purpose repository methods for inserting, updating, deleting, and querying for entities. However, in this case, we will define all of the methods ourselves by using the new lifecycle annotations:
@Repository(dataStore = "java:app/jdbc/my-example-data")
public interface Products {
@Insert
Product add(Product newProduct);
@Update
boolean modify(Product product);
@Delete
boolean remove(Product product);
// parameter based query that requires compilation with -parameters to preserve parameter names
Optional<Product> find(long id);
// query-by-method name pattern:
KeysetAwarePage<Product> findByNameIgnoreCaseContains(String searchFor, Pageable pageRequest);
// query via JPQL:
@Query("UPDATE Product o SET o.price = o.price - (?2 * o.price) WHERE o.id = ?1")
boolean discount(long productId, float discountRate);
}
The following example shows the repository being used:
@DataSourceDefinition(name = "java:app/jdbc/my-example-data",
className = "org.postgresql.xa.PGXADataSource",
databaseName = "ExampleDB",
serverName = "localhost",
portNumber = 5432,
user = "${example.database.user}",
password = "${example.database.password}")
public class MyServlet extends HttpServlet {
@Inject
Products products;
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Insert:
Product prod = ...
prod = products.add(prod);
// Update:
prod.price = prod.price + 1.00;
if (products.update(prod))
System.out.println("Successfully increased the price.");
else {
// someone else either removed the product or updated its version before we could
prod = products.find(productId).orElseThrow();
...
}
// Request only the first 10 results on a page, ordered by price, then name, then id:
Pageable pageRequest = Pageable.size(10).sortBy(Sort.desc("price"), Sort.asc("name"), Sort.asc("id"));
KeysetAwarePage<Product> page = products.findByNameIgnoreCaseContains(searchFor, pageRequest);
...
// Request the next page relative to the end of the current page
page = products.findByNameIgnoreCaseContains(searchFor, page.nextPageable());
...
// Request the prior page relative to the start of the current page
page = products.findByNameIgnoreCaseContains(searchFor, page.previousPageable());
...
}
}
To try out these features, update your build tools to pull the Open Liberty All Beta Features package instead of the main release. The beta works with Java SE 21, Java SE 17, Java SE 11, and Java SE 8.
If you’re using Maven, you can install the All Beta Features package using:
<plugin>
<groupId>io.openliberty.tools</groupId>
<artifactId>liberty-maven-plugin</artifactId>
<version>3.10</version>
<configuration>
<runtimeArtifact>
<groupId>io.openliberty.beta</groupId>
<artifactId>openliberty-runtime</artifactId>
<version>24.0.0.1-beta</version>
<type>zip</type>
</runtimeArtifact>
</configuration>
</plugin>
You must also add dependencies to your pom.xml file for the beta version of the APIs that are associated with the beta features that you want to try. For example, for Jakarta EE 10 and MicroProfile 6, you would include:
<dependency>
<groupId>org.eclipse.microprofile</groupId>
<artifactId>microprofile</artifactId>
<version>6.0-RC3</version>
<type>pom</type>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>10.0.0</version>
<scope>provided</scope>
</dependency>
Or for Gradle:
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'io.openliberty.tools:liberty-gradle-plugin:3.8'
}
}
apply plugin: 'liberty'
dependencies {
libertyRuntime group: 'io.openliberty.beta', name: 'openliberty-runtime', version: '[24.0.0.1-beta,)'
}
Or if you’re using container images:
FROM icr.io/appcafe/open-liberty:beta
Or take a look at our Downloads page.
If you’re using IntelliJ IDEA, Visual Studio Code or Eclipse IDE, you can also take advantage of our open source Liberty developer tools to enable effective development, testing, debugging and application management all from within your IDE.
For more information on using a beta release, refer to the Installing Open Liberty beta releases documentation.
Let us know what you think on our mailing list. If you hit a problem, post a question on StackOverflow. If you hit a bug, please raise an issue.
Write a pure-Java microservice from scratch, without an application server nor any third party frameworks, tools, or IDE plugins — Just using JDK, Maven and JAX-RS aka Jakarta REST 3.1. This video series shows you the essential steps!
You asked, why I am not simply using the Jakarta EE 10 Core API. There are many answers in this video!
If you like this video, please give it a thumbs up, share it, subscribe to my channel, or become my patreon https://www.patreon.com/mkarg. Thanks!
Let’s take a deep dive into the source code of #Jersey (the heart of GlassFish, Payara and Helidon) to learn how we can make our own I/O code run faster on modern Java.
In this first step, we apply NIO APIs from #Java 7 and 8 to process data more efficiently, and most notably: outside of the JVM.
If you like this video, please give it a thumbs up, share it, subscribe to my channel, or become my patreon https://www.patreon.com/mkarg. Thanks!
This blog aims at giving some pointers in order to address the challenge related to the switch from `javax` to `jakarta` namespace. This is one of the biggest changes in Java of the latest 20 years. No doubt. The entire ecosystem is impacted. Not only Java EE or Jakarta EE Application servers, but also libraries of any kind (Jackson, CXF, Hibernate, Spring to name a few). For instance, it took Apache TomEE about a year to convert all the source code and dependencies to the new `jakarta` namespace. This blog is written from the user perspective, because the shift from...
The post Moving from javax to jakarta namespace appeared first on Tomitribe.
This blog aims at giving some pointers in order to address the challenge related to the switch from `javax` to `jakarta` namespace. This is one of the biggest changes in Java of the latest 20 years. No doubt. The entire ecosystem is impacted. Not only Java EE or Jakarta EE Application servers, but also libraries of any kind (Jackson, CXF, Hibernate, Spring to name a few). For instance, it took Apache TomEE about a year to convert all the source code and dependencies to the new `jakarta` namespace.
This blog is written from the user perspective, because the shift from `javax` to `jakarta` is as impacting for application providers than it is for libraries or application servers. There have been a couple of attempts to study the impact and investigate possible paths to make the change as smooth as possible.
The problem is harder than it appears to be. The `javax` package is of course in the import section of a class, but it can be in Strings as well if you use the Java Reflection API for instance. Using Byte Code tools like ASM also makes the problem more complex, but also service loader mechanisms and many more. We will see that there are many ways to approach the problem, using byte code, converting the sources directly, but none are perfect.
The first legitimate approach that comes to our mind is the byte code approach. The goal is to keep the `javax` namespace as much as possible and use bytecode enhancement to convert binaries.
It is possible to do a post treatment on the libraries and packages to transform archives such as then are converted to `jakarta` namespace.
The Maven shade plugin has the ability to relocate packages. While the primary purpose isn’t to move from `javax` to `jakarta` package, it is possible to use it to relocate small libraries when they aren’t ready yet. We used this approach in TomEE itself or in third party libraries such as Apache Johnzon (JSONB/P implementation).
Here is an example in TomEE where we use Maven Shade Plugin to transform the Apache ActiveMQ Client library https://github.com/apache/tomee/blob/main/deps/activemq-client-shade/pom.xml
This approach is not perfect, especially when you have a multi module library. For Instance, if you have a project with 2 modules, A depends on B. You can use the shade plugin to convert the 2 modules and publish them using a classifier. The issue then is when you need A, you have to exclude B so that you can include it manually with the right classifier.
We’d say it works fine but for simple cases because it breaks the dependency management in Maven, especially with transitive dependencies. It also break IDE integration because sources and javadoc won’t match.
The Eclipse Transformer is also a generic tool, but it’s been heavily developed for the `javax` to `jakarta` namespace change. It operates on resources such as
Simple resources:
Container resources:
It can be configured using Java Properties files to properly convert Java Modules, classes, test resources. This is the approach we used for Apache TomEE 9.0.0-M7 when we first tried to convert to `jakarta`. It had limitation, so we had to then find tricks to solve issues. As it was converting the final distribution and not the individual artifacts, it was impossible for users to use Arquillian or the Maven plugin. They were not converted.
This tool can operate on a directory or an archive (zip, ear, jar, war). It can migrate quite easily an application based on the set of specifications supported in Tomcat and a few more. It has the notion of profile so that you can ask it to convert more.
You can run it using the ANT task (within Maven or not), and there is also a command line interface to run it easily.
When using application server, it is sometimes possible to step in the deployment process and do the conversion of the binaries prior to their deployment.
Mind that by default, the tool converts only what’s being supported by Apache Tomcat and a couple of other APIs. It does not convert all specifications supported in TomEE, like JAX RS for example. And Tomcat does not provide yet any way to configure it.
We haven’t seen any working solution in this area. Of course, we could imagine a JavaAgent approach that converts the bytecode right when it gets loaded by the JVM. The startup time is seriously impacted, and it has to be done every time the JVM restarts or loads a class in a classloader. Remember that a class can be loaded multiple times in different classloaders.
This may sound like the most impacting but this is probably also the most secured one. We also strongly believe that embracing the change sooner is preferable rather than later. As mentioned, this is one of the biggest breaking change in Java of the last 20 years. Since Java EE moved to Eclipse to become Jakarta, we have noticed a change in the release cadence. Releases are not more frequent and more changes are going to happen. Killing the technical depth as soon as possible is probably the best when it’s so impacting.
There are a couple of tools we tried. There are probably more in the ecosystem, and also some in-house developments.
[IMPORTANT]
This is usually a one shoot operation. It won’t be perfect and no doubt it will require adjustment because there is no perfect tool that can handle all cases.
IntelliJ IDEA added a refactoring capability to its IDE in order to convert sources to the new `jakarta` namespace. I haven’t tested it myself, but it may help to do the first big step when you don’t really master the scripting approach below.
For simple case, and we used that approach to do most of the conversion in TomEE, you can create your own simple tool to convert sources. For instance, SmallRye does that with their MicroProfile implementations. Here is an example https://github.com/smallrye/smallrye-config/blob/main/to-jakarta.sh
Using basic Linux commands, it converts from `javax` to `jakarta` namespace and then the result is pushed to a dedicated branch. The benefit is that they have 2 source trees with different artifacts, the dependency management isn’t broken.
One source tree is the reference and they add to the script the necessary commands to convert additional things on demand.
Because the Eclipse Transformer can operate on text files, it can be easily used to migrate the sources from `javax` to `jakarta` namespace.
Weather you are working on Open Source or not, someone will consume your artifacts. If you are using Maven for example, you may ask yourself what option is the best especially if you maintain the 2 branches `javax` and `jakarta`.
[NOTE]
It does not matter if you use the bytecode or the source code approach.
This is probably the more practical solution. Some project like Arquillian for example decided to go using a different artifact name (-jakarta suffix) because the artifact is the same and solves the same problem, so why bringing a technical concerned into the name? I’m more in favor of using the version to mark the namespace change. It is somehow an major API change that I’d rather emphasize using a major version update.
[IMPORTANT]
Mind that this only works if both `javax` and `jakarta` APIs are backward compatible. Otherwise, it won’t work
This is not an option we would recommend. Unfortunately some of our dependencies use this approach and it has many drawbacks. It’s fine for a quick test, but as I mentioned previously, it badly impacts how Maven works. If you pull a transformed artifact, you may get a transitive and not transformed dependency. This is the case for multi module project as well.
Another painful side effect is that javadoc and sources are still linked to the original artifact, so you will have a hard time to debug in the IDE.
We tried the bytecode approach ourselves in TomEE with the hope we could avoid maintaining 2 source trees, one for `javax` and the other one for `jakarta` namespace. Unfortunately, as we have seen before the risk is too important and there are too many edge cases not covered. Apache TomEE runs about 60k tests (including TCK) and our confidence wasn’t good enough. Even though the approach has some benefits and can work for simple use cases, like converting a small utility tool, it does not fit in our opinion for real applications.
The post Moving from javax to jakarta namespace appeared first on Tomitribe.
This blog aims at giving some pointers in order to address the challenge related to the switch from `javax` to `jakarta` namespace. This is one of the biggest changes in Java of the latest 20 years. No doubt. The entire ecosystem is impacted. Not only Java EE or Jakarta EE Application servers, but also libraries of any kind (Jackson, CXF, Hibernate, Spring to name a few). For instance, it took Apache TomEE about a year to convert all the source code and dependencies to the new `jakarta` namespace. This blog is written from the user perspective, because the shift from...
The post Moving from javax to jakarta namespace appeared first on Tomitribe.
This blog aims at giving some pointers in order to address the challenge related to the switch from `javax` to `jakarta` namespace. This is one of the biggest changes in Java of the latest 20 years. No doubt. The entire ecosystem is impacted. Not only Java EE or Jakarta EE Application servers, but also libraries of any kind (Jackson, CXF, Hibernate, Spring to name a few). For instance, it took Apache TomEE about a year to convert all the source code and dependencies to the new `jakarta` namespace.
This blog is written from the user perspective, because the shift from `javax` to `jakarta` is as impacting for application providers than it is for libraries or application servers. There have been a couple of attempts to study the impact and investigate possible paths to make the change as smooth as possible.
The problem is harder than it appears to be. The `javax` package is of course in the import section of a class, but it can be in Strings as well if you use the Java Reflection API for instance. Using Byte Code tools like ASM also makes the problem more complex, but also service loader mechanisms and many more. We will see that there are many ways to approach the problem, using byte code, converting the sources directly, but none are perfect.
The first legitimate approach that comes to our mind is the byte code approach. The goal is to keep the `javax` namespace as much as possible and use bytecode enhancement to convert binaries.
It is possible to do a post treatment on the libraries and packages to transform archives such as then are converted to `jakarta` namespace.
The Maven shade plugin has the ability to relocate packages. While the primary purpose isn’t to move from `javax` to `jakarta` package, it is possible to use it to relocate small libraries when they aren’t ready yet. We used this approach in TomEE itself or in third party libraries such as Apache Johnzon (JSONB/P implementation).
Here is an example in TomEE where we use Maven Shade Plugin to transform the Apache ActiveMQ Client library https://github.com/apache/tomee/blob/main/deps/activemq-client-shade/pom.xml
This approach is not perfect, especially when you have a multi module library. For Instance, if you have a project with 2 modules, A depends on B. You can use the shade plugin to convert the 2 modules and publish them using a classifier. The issue then is when you need A, you have to exclude B so that you can include it manually with the right classifier.
We’d say it works fine but for simple cases because it breaks the dependency management in Maven, especially with transitive dependencies. It also break IDE integration because sources and javadoc won’t match.
The Eclipse Transformer is also a generic tool, but it’s been heavily developed for the `javax` to `jakarta` namespace change. It operates on resources such as
Simple resources:
Container resources:
It can be configured using Java Properties files to properly convert Java Modules, classes, test resources. This is the approach we used for Apache TomEE 9.0.0-M7 when we first tried to convert to `jakarta`. It had limitation, so we had to then find tricks to solve issues. As it was converting the final distribution and not the individual artifacts, it was impossible for users to use Arquillian or the Maven plugin. They were not converted.
This tool can operate on a directory or an archive (zip, ear, jar, war). It can migrate quite easily an application based on the set of specifications supported in Tomcat and a few more. It has the notion of profile so that you can ask it to convert more.
You can run it using the ANT task (within Maven or not), and there is also a command line interface to run it easily.
When using application server, it is sometimes possible to step in the deployment process and do the conversion of the binaries prior to their deployment.
Mind that by default, the tool converts only what’s being supported by Apache Tomcat and a couple of other APIs. It does not convert all specifications supported in TomEE, like JAX RS for example. And Tomcat does not provide yet any way to configure it.
We haven’t seen any working solution in this area. Of course, we could imagine a JavaAgent approach that converts the bytecode right when it gets loaded by the JVM. The startup time is seriously impacted, and it has to be done every time the JVM restarts or loads a class in a classloader. Remember that a class can be loaded multiple times in different classloaders.
This may sound like the most impacting but this is probably also the most secured one. We also strongly believe that embracing the change sooner is preferable rather than later. As mentioned, this is one of the biggest breaking change in Java of the last 20 years. Since Java EE moved to Eclipse to become Jakarta, we have noticed a change in the release cadence. Releases are not more frequent and more changes are going to happen. Killing the technical depth as soon as possible is probably the best when it’s so impacting.
There are a couple of tools we tried. There are probably more in the ecosystem, and also some in-house developments.
[IMPORTANT]
This is usually a one shoot operation. It won’t be perfect and no doubt it will require adjustment because there is no perfect tool that can handle all cases.
IntelliJ IDEA added a refactoring capability to its IDE in order to convert sources to the new `jakarta` namespace. I haven’t tested it myself, but it may help to do the first big step when you don’t really master the scripting approach below.
For simple case, and we used that approach to do most of the conversion in TomEE, you can create your own simple tool to convert sources. For instance, SmallRye does that with their MicroProfile implementations. Here is an example https://github.com/smallrye/smallrye-config/blob/main/to-jakarta.sh
Using basic Linux commands, it converts from `javax` to `jakarta` namespace and then the result is pushed to a dedicated branch. The benefit is that they have 2 source trees with different artifacts, the dependency management isn’t broken.
One source tree is the reference and they add to the script the necessary commands to convert additional things on demand.
Because the Eclipse Transformer can operate on text files, it can be easily used to migrate the sources from `javax` to `jakarta` namespace.
Weather you are working on Open Source or not, someone will consume your artifacts. If you are using Maven for example, you may ask yourself what option is the best especially if you maintain the 2 branches `javax` and `jakarta`.
[NOTE]
It does not matter if you use the bytecode or the source code approach.
This is probably the more practical solution. Some project like Arquillian for example decided to go using a different artifact name (-jakarta suffix) because the artifact is the same and solves the same problem, so why bringing a technical concerned into the name? I’m more in favor of using the version to mark the namespace change. It is somehow an major API change that I’d rather emphasize using a major version update.
[IMPORTANT]
Mind that this only works if both `javax` and `jakarta` APIs are backward compatible. Otherwise, it won’t work
This is not an option we would recommend. Unfortunately some of our dependencies use this approach and it has many drawbacks. It’s fine for a quick test, but as I mentioned previously, it badly impacts how Maven works. If you pull a transformed artifact, you may get a transitive and not transformed dependency. This is the case for multi module project as well.
Another painful side effect is that javadoc and sources are still linked to the original artifact, so you will have a hard time to debug in the IDE.
We tried the bytecode approach ourselves in TomEE with the hope we could avoid maintaining 2 source trees, one for `javax` and the other one for `jakarta` namespace. Unfortunately, as we have seen before the risk is too important and there are too many edge cases not covered. Apache TomEE runs about 60k tests (including TCK) and our confidence wasn’t good enough. Even though the approach has some benefits and can work for simple use cases, like converting a small utility tool, it does not fit in our opinion for real applications.
The post Moving from javax to jakarta namespace appeared first on Tomitribe.
We’re currently in the middle of a substantial transition as we are migrating mission-critical websites from Drupal 7 to Drupal 9, with our sights set on Drupal 10. This shift has been motivated by several factors, including the announcement of Drupal 7 end-of-life which is now scheduled for January 5, 2025, and our goal to reduce technical debt that we accrued over the last decade.
To provide some context, we’re migrating a total of six key websites:
We’ve made substantial progress this year with our migration efforts. The team successfully completed the migration of Eclipse Blogs and Eclipse Newsroom. We are also in the final stages of development with the Eclipse Marketplace, which is currently scheduled for a production release on October 25, 2023. Next year, we’ll focus our attention on completing the migration of our more substantial sites, such as Eclipse PMI, Eclipse Accounts, and Eclipse Packaging.
This initiative isn’t just about moving from one version of Drupal to another. Simultaneously, we’re undertaking the task of decoupling essential APIs from Drupal in the hope that future migration or upgrade won’t impact as many core services at the same time. For this purpose, we’ve chosen Quarkus as our preferred platform. In Q3 2023, the team successfully migrated the GitHub ECA Validation Service and the Open-VSX Publisher Agreement Service from Drupal to Quarkus. In Q4 2023, we’re planning to continue down that path and deploy a Quarkus implementation of several critical APIs such as:
Our migration journey from Drupal 7 to Drupal 9, with plans for Drupal 10, represents our commitment to providing a secure, efficient, and user-friendly online experience for our community. We are excited about the possibilities this migration will unlock for us, advancing us toward a more modern web stack.
Finally, I’d like to take this moment to highlight that this project is a monumental team effort, thanks to the exceptional contributions of Eric Poirier and Théodore Biadala, our Drupal developers; Martin Lowe and Zachary Sabourin, our Java developers implementing the API decoupling objective; and Frederic Gurr, whose support has been instrumental in deploying our new apps on the Eclipse Infrastructure.
Now that Jetty 12.0.1 is released to Maven Central, we’ve started to get a few questions about where some artifacts are, or when we intend to release them (as folks cannot find them).
Things have change with Jetty, starting with the 12.0.0 release.
First, is that our historical versioning of <servlet_support>.<major>.<minor>
is no longer being used.
With Jetty 12, we are now using a more traditional <major>.<minor>.<patch>
versioning scheme for the first time.
Also new in Jetty 12 is that the Servlet layer has been separated away from the Jetty Core layer.
The Servlet layer has been moved to the new Environments concept introduced with Jetty 12.
Environment | Jakarta EE | Servlet | Jakarta Namespace | Jetty GroupID |
ee8 | EE8 | 4 | javax.servlet | org.eclipse.jetty.ee8 |
ee9 | EE9 | 5 | jakarta.servlet | org.eclipse.jetty.ee9 |
ee10 | EE10 | 6 | jakarta.servlet | org.eclipse.jetty.ee10 |
This means the old Servlet specific artifacts have been moved to environment specific locations both in terms of Java namespace and also their Maven Coordinates.
Example:
Jetty 11 – Using Servlet 5
Maven Coord: org.eclipse.jetty:jetty-servlet
Java Class: org.eclipse.jetty.servlet.ServletContextHandler
Jetty 12 – Using Servlet 6
Maven Coord: org.eclipse.jetty.ee10:jetty-ee10-servlet
Java Class: org.eclipse.jetty.ee10.servlet.ServletContextHandler
We have a migration document which lists all of the migrated locations from Jetty 11 to Jetty 12.
This new versioning and environment features built into Jetty means that new major versions of Jetty are not as common as they have been in the past.
The results of the 2023 Jakarta EE Developer Survey are now available! For the sixth year in a row, we’ve reached out to the enterprise Java community to ask about their preferences and priorities for cloud native Java architectures, technologies, and tools, their perceptions of the cloud native application industry, and more.
From these results, it is clear that open source cloud native Java is on the rise following the release of Jakarta EE 10.The number of respondents who have migrated to Jakarta EE continues to grow, with 60% saying they have already migrated, or plan to do so within the next 6-24 months. These results indicate steady growth in the use of Jakarta EE and a growing interest in cloud native Java overall.
When comparing the survey results to 2022, usage of Jakarta EE to build cloud native applications has remained steady at 53%. Spring/Spring Boot, which relies on some Jakarta EE specifications, continues to be the leading Java framework in this category, with usage growing from 57% to 66%.
Since the September 2022 release, Jakarta EE 10 usage has grown to 17% among survey respondents. This community-driven release is attracting a growing number of application developers to adopt Jakarta EE 10 by offering new features and updates to Jakarta EE. An equal number of developers are running Jakarta EE 9 or 9.1 in production, while 28% are running Jakarta EE 8. That means the increase we are seeing in the migration to Jakarta EE is mostly due to the adoption of Jakarta EE 10, as compared to Jakarta EE 9/9.1 or Jakarta EE 8.
The Jakarta EE Developer Survey also gives us a chance to get valuable feedback on features from the latest Jakarta EE release, as well as what direction the project should take in the future.
Respondents are most excited about Jakarta EE Core Profile, which was introduced in the Jakarta EE 10 release as a subset of Web Profile specifications designed for microservices and ahead-of-time compilation. When it comes to future releases, the community is prioritizing better support for Kubernetes and microservices, as well as adapting Java SE innovations to Jakarta EE — a priority that has grown in popularity since 2022. This is a good indicator that the Jakarta EE 11 release plan is on the right direction by adopting new Java SE 21 features.
2,203 developers, architects, and other tech professionals participated in the survey, a 53% increase from last year. This year’s survey was also available in Chinese, Japanese, Spanish & Portuguese, making it easier for Java enthusiasts around the world to share their perspectives. Participation from the Chinese Jakarta EE community was particularly strong, with over 27% of the responses coming from China. By hearing from more people in the enterprise Java space, we’re able to get a clearer picture of what challenges developers are facing, what they’re looking for, and what technologies they are using. Thank you to everyone who participated!
We encourage you to download the report for a complete look at the enterprise Java ecosystem.
If you’d like to get more information about Jakarta EE specifications and our open source community, sign up for one of our mailing lists or join the conversation on Slack. If you’d like to participate in the Jakarta EE community, learn how to get started on our website.
Looking at the web, we don’t see many articles talking about Contexts Dependency Injection’s best practices. Hence, I have made the decision to discuss the utilization of Contexts Dependency Injection (CDI) using best practices, providing a comprehensive guide on its implementation.
The CDI is a Jakarta specification in the Java ecosystem to allow developers to use dependency injection, managing contexts, and component injection in an easier way. The article https://www.baeldung.com/java-ee-cdi defines the CDI as follows:
CDI turns DI into a no-brainer process, boiled down to just decorating the service classes with a few simple annotations, and defining the corresponding injection points in the client classes.
If you want to learn the CDI concepts you can read Baeldung’s post and Otavio Santana’s post. Here, in this post, we will focus on the best practices topic.
In fact, CDI is a powerful framework and allows developers to use Dependency Injection (DI) and Inversion of Control (IoC). However, we have one question here. How tightly do we want our application to be coupled with the framework? Note that I’m not talking you cannot couple your application to a framework, but you should think about it, think about the coupling level, and think about the tradeoffs. For me, coupling an application to a framework is not wrong, but doing it without thinking about the coupling level and the cost and tradeoffs is wrong.
It is impossible to add a framework to your application without minimally coupling your application. Even though your application does not have a couple expressed in the code, probably you have a behavioral coupling, that is, a behavior in your application depends on a framework’s behavior, and in some cases, you can not guarantee that other framework will provide a similar behavior, in case of changes.
When writing code in Java, we often create classes that rely on external dependencies to perform their tasks. To achieve this using CDI, we employ the @Inject
annotation, which allows us to inject these dependencies. However, it’s essential to be mindful of whether we are making the class overly dependent on CDI for its functionality, as it may limit its usability without CDI. Hence, it’s crucial to carefully consider the tightness of this dependency. As an illustration, let’s examine the code snippet below. Here, we encounter a class that is tightly coupled to CDI in order to carry out its functionality.
public class ImageRepository {
@Inject
private StorageProvider storageProvider;
public void saveImage(File image){
//Validate the file to check if it is an image.
//Apply some logic if needed
storageProvider.save(image);
}
}
As you can see the class ImageRepository
has a dependency on StorageProvider
, that is injected via CDI annotation. However, the storageProvider
variable is private and we don’t have setter method or a constructor that allows us to pass this dependency by the constructor. It means this class cannot work without a CDI context, that is, the ImageRepository is tightly coupled to CDI.
This coupling doesn’t provide any benefits for the application, instead, it only causes harm both to the application itself and potentially to the testing of this class.
Look at the code refactored to reduce the couple to CDI.
public class ImageRepository implements Serializable {
private StorageProvider storageProvider;
@Inject
public ImageRepository(StorageProvider storageProvider){
this.storageProvider = storageProvider;
}
public void saveImage(File image){
//Validate the file to check if it is an image.
//Apply some logic if needed
storageProvider.save(image);
}
}
As you can see, the ImageRepository
class has a constructor that receives the StorageProvider as a constructor argument. This approach follows what is said in the Clean Code book.
“True Dependency Injection goes one step further. The class takes no direct steps to resolve its dependencies; it is completely passive. Instead, it provides setter methods or constructor arguments (or both) that are used to inject the dependencies.”
(from “Clean Code: A Handbook of Agile Software Craftsmanship” by Martin Robert C.)
Without a constructor or a setter method, the injection depends on the CDI. However, we still have one question about this class. The class has a CDI annotation and depends on the CDI to be compiled. I’m not saying it is always a problem, but it can be a problem, especially if you are writing a framework. Coupling a framework with another framework can be a problem in cases you want to use your framework with another mutually exclusive one. In general, it should be avoided by frameworks. Thus, how can we fully decouple the ImageRepository
class from CDI?
The CDI producer is a source of an object that can be used to be injected by CDI. It is like a factor of a type of object. Look at the code below:
public class ImageRepositoryProducer {
@Produces
public ImageRepository createImageRepository(){
StorageProvider storageProvider = CDI.current().select(StorageProvider.class).get();
return new ImageRepository(storageProvider);
}
}
Please note that we are constructing just one object, but the StorageProvider
‘s object is read by CDI. You should avoid constructing more than one object within a producer method, as this interlinks the construction of these objects and may lead to complications if you intend to designate distinct scopes for them. You can create a separated producer method to produce the StorageProvider
.
This is the ImageRepository
class refactored.
public class ImageRepository implements Serializable {
private StorageProvider storageProvider;
public ImageRepository(StorageProvider storageProvider){
this.storageProvider = storageProvider;
}
public void saveImage(File image){
//Validate the file to check if it is an image.
//Apply some logic if needed
storageProvider.save(image);
}
}
Please note that the ImageRepository
class does not know anything about the CDI, and is fully decoupled from CDI. The codes about the CDI are inside the ImageRepositoryProducer
, which can be extracted to another module if needed.
The CDI Interceptor is a very cool feature of CDI that provides a nice CDI-based way to work with cross-cutting tasks (such as auditing). This is a little definition said in my book:
“A CDI interceptor is a class that wraps the call to a method — this method is called target method — that runs its logic and proceeds the call either to the next CDI interceptor if it exists, or the target method.”
(from “Jakarta EE for Java Developers” by Rhuan Rocha.)
The purpose of this article is not to discuss what a CDI interceptor is, but to discuss CDI best practices. So if you want to read more about CDI interceptor, check out the book Jakarta EE for Java Developers.
As said, the CDI interceptor is very interesting. I am quite fond of this feature and have incorporated it into numerous projects. However, using this feature comes with certain trade-offs for the application.
When you use the CDI interceptor you couple the class to the CDI, because you should be annotating the class with a custom annotation that is a interceptor binding. Look at the example below shown on the Jakarta EE for Java Developers book:
@ApplicationScoped
public class SecuredBean{
@Authentication
public String generateText(String username) throws AutenticationException{
return "Welcome "+username;
}
}
As you can see we should define a scope, as it should be a bean managed by CDI, and you should be annotating the class with the interceptor binding. Hence, if you eliminate CDI from your application, the interceptor’s logic won’t execute, and the class won’t be compiled. With this, your application has a behavioral coupling, and a dependency on the CDI lib jar to compile.
As said, it is not necessarily bad, however, you should think if it is a problem in your context.
The CDI Event is a great feature within the CDI framework that I have employed extensively in various applications. This functionality provides the implementation of the Observer Pattern, enabling us to emit events that are then observed by observers who execute tasks asynchronously. However, if we add the CDI codes inside our class to emit events we will couple the class to the CDI. Again, this is not an error, but you should be sure it is not a problem with your solution. Look at the example below.
import jakarta.enterprise.event.Event;
public class User{
private Event<Email> emailEvent;
public User(Event<Email> emailEvent){
this.emailEvent = emailEvent;
}
public void register(){
//logic
emailEvent.fireAsync(Email.of(from, to, subject, content));
}
}
Note we are receiving the Event class, which is from CDI, to emit the event. It means this class is coupled to CDI and depends on it to work. One way to avoid it is creating your own class to emit the event, and abstract the details about what is the mechanism (CDI or other) that is emitting the event. Look at the example below.
import net.rhuan.example.EventEmitter;
public class User{
private EventEmiter<Email> emailEventEmiter;
public User(EventEmiter<Email> emailEventEmiter){
this.emailEventEmiter = emailEventEmiter;
}
public void register(){
//logic
emailEventEmiter.emit(Email.of(from, to, subject, content));
}
}
Now, your class is agnostic to the emitter of the event. You can use CDI or others, according to the EventEmiter implementation.
The CDI is an amazing specification from Jakarta EE widely used in many Java frameworks and Java applications. Carefully determining the degree of integration between our application and the framework holds immense significance. This intentional decision becomes an important factor in proactively mitigating challenges during the solution’s evolution, especially when working on the development of a framework.
If you have a question or want to share your thoughts, feel free to add comments or send me messages about it.
It is that time of the year: the Jakarta EE 2023 Developer Survey open for your input! The survey will stay open until May 25st.
I would like to invite you to take this year six-minute survey, and have the chance to share your thoughts and ideas for future Jakarta EE releases, and help us discover uptake of the Jakarta EE latest versions and trends that inform industry decision-makers.
Please share the survey link and to reach out to your contacts: Java developers, architects and stakeholders on the enterprise Java ecosystem and invite them to participate in the 2023 Jakarta EE Developer Survey!
In this post, I will talk to you about what the Apache Camel is. It is a brief introduction before I starting to post practical content. Thus, let’s go to understand what this framework is.
Apache Camel is an open source Java integration framework that allows different applications to communicate with each other efficiently. It provides a platform for integrating heterogeneous software systems. Camel is designed to make application integration easy, simplifying the complexity of communication between different systems.
Apache Camel is written in Java and can be run on a variety of platforms, including Jakarta EE application servers and OSGi-based application containers, and can runs inside cloud environments using Spring Boot or Quarkus. Camel also supports a wide range of network protocols and message formats, including HTTP, FTP, SMTP, JMS, SOAP, XML, and JSON.
Camel uses the Enterprise Integration Patterns (EIP) pattern to define the different forms of integration. EIP is a set of commonly used design patterns in system integration. Camel implements many of these patterns, making it a powerful tool for integration solutions.
Additionally, Camel has a set of components that allow it to integrate with different systems. The components can be used to access different resources, such as databases, web services, and message systems. Camel also supports content-based routing, which means it can route messages based on their content.
Camel is highly configurable and extensible, allowing developers to customize its functionality to their needs. It also supports the creation of integration routes at runtime, which means that routes can be defined and changed without the need to restart the system.
In summary, Camel is a powerful and flexible tool for software system integration. It allows different applications to communicate efficiently and effectively, simplifying the complexity of system integration. Camel is a reliable and widely used framework that can help improve the efficiency and effectiveness of system integration in a variety of environments.
If you want to start using this framework you can access the documentation at the site. It’s my first post about the Apache Camel and will post more practical content about this amazing framework.
We have great news to share with you!
For the very first time at Devnexus 2023 we will have Jakarta EE track with 10 sessions and we will take this opportunity, to whenever possible, celebrate all we have accomplished in Jakarta EE community.
Jakarta EE track sessions
You may not be aware but this year (yes, time flies!!) marks 5 years of Jakarta EE, so we will be celebrating through out the year! Devnexus 2023, looks a great place to mark this milestone as well! So stay tuned for details, but in the meanwhile please help us out, register for the event come to see us and spread the word.
Help us out in spreading the word about Jakarta EE track @Devnexus 2023, just re-share posts you see from us on various social platforms!
To make it easier for you to spread the word on socials, we also have prepared a social kit document to help us with promotion of the Jakarta EE track @Devnexus 2023, sessions and speakers. The social kit document is going to be updated with missing sessions and speakers, so visit often and promote far and wide.
Note: Organizers wanted to do something for people impacted by the recent tech layoffs, and decided to offer a 50% discount for any conference pass (valid for a limited time). Please use code DN-JAKARTAEE for @JakartaEE Track to get additional 20% discount!
In addition, there will be an IBM workshop that will be highlighting Jakarta EE; look for "Thriving in the cloud: Venturing beyond the 12 factors". Please use the promo code ($100 off): JAKARTAEEATDEVNEXUS the organizers prepared for you (valid for a limited time).
I hope to see you all at Devnexus 2023!
Community Day at EclipseCon 2022 was held in person on Monday, October 24 in Ludwigsburg, Germany. Community Day has always been a great event for Eclipse working groups and project teams, including Jakarta EE/MicroProfile. This year was no exception. A number of great sessions were delivered from prominent folks in the community. The following are the details including session materials. The agenda can still be found here. All the materials can be found here.
Jakarta EE Community State of the Union
The first session of the day was a Jakarta EE community state of the union delivered by Tanja Obradovic, Ivar Grimstad and Shabnam Mayel. The session included a quick overview of Jakarta EE releases, how to get involved in the work of producing the specifications, a recap of the important Jakarta EE 10 release and as well as a view of what’s to come in Jakarta EE 11. The slides are embedded below and linked here.
Jakarta Concurrency – What’s Next
Payara CEO Steve Millidge covered Jakarta Concurrency. He discussed the value proposition of Jakarta Concurrency, the innovations delivered in Jakarta EE 10 (including CDI based @Asynchronous, @ManagedExecutorDefinition, etc) and the possibilities for the future (including CDI based @Schedule, @Lock, @MaxConcurrency, etc). The slides are embedded below and linked here. There are some excellent code examples included.
Jakarta Security – What’s Next
Werner Keil covered Jakarta Security. He discussed what’s already done in Jakarta EE 10 (including OpenID Connect support) and everything that’s in the works for Jakarta EE 11 (including CDI based @RolesAllowed). The slides are embedded below and linked here.
Jakarta Data – What’s Coming
IBM’s Emily Jiang kindly covered Jakarta Data. This is a brand new specification aimed towards Jakarta EE 11. It is a higher level data access abstraction similar to Spring Data and DeltaSpike Data. It encompasses both Jakarta Persistence (JPA) and Jakarta NoSQL. The slides are embedded below and linked here. There are some excellent code examples included.
MicroProfile Community State of the Union
Emily also graciously delivered a MicroProfile state of the union. She covered what was delivered in MicroProfile 5, including alignment with Jakarta EE 9.1. She also discussed what’s coming soon in MicroProfile 6 and beyond, including very clear alignment with the Jakarta EE 10 Core Profile. The slides are embedded below and linked here. There are some excellent technical details included.
MicroProfile Telemetry – What’s Coming
Red Hat’s Martin Stefanko covered MicroProfile Telemetry. Telemetry is a brand new specification being included in MicroProfile 6. The specification essentially supersedes MicroProfile Tracing and possibly MicroProfile Metrics too in the near future. This is because the OpenTracing and OpenCensus projects merged into a single project called OpenTelemetry. OpenTelemetry is now the de facto standard defining how to collect, process, and export telemetry data in microservices. It makes sense that MicroProfile moves forward with supporting OpenTelemetry. The slides are embedded below and linked here. There are some excellent technical details and code examples included.
See You There Next Time?
Overall, it was an honor to organize the Jakarta EE/MicroProfile agenda at EclipseCon Community Day one more time. All speakers and attendees should be thanked. Perhaps we will see you at Community Day next time? It is a great way to hear from some of the key people driving Jakarta EE and MicroProfile. You can attend just Community Day even if you don’t attend EclipseCon. The fee is modest and includes lunch as well as casual networking.
An impression of JFall by yours truly.
Sold out!
Packet room!
Very nice first keynote speaker by Saby Sengupta about the path to transform.
He is a really nice storyteller. He had us going.
Dutch people, wooden shoes, wooden hat, would not listen
- Saby
lol
Get the answer to three why questions. If the answers stop after the first why. It may not be a good idea.
This great first keynote is followed by the very well known Venkat Subramaniam about The Art of Simplicity.
The question is not what can we add? But What can we remove?
Simple fails less
Simple is elegant
All in al a great keynote! Loved it.
By Venkat Subramaniam
The GOF are kind of the grand parents of our industry. The worst thing they have done is write the damn book.
— Venkat
The quote is in the context of that writing down grandmas fantastic recipe does not work as it is based on the skill of grandma and not the exact amount of the ingredients.
The cleanup is the responsibility of the Resource class. Much better than asking developers to take care of it. It will be forgotten!
The more powerful a language becomes the less we need to talk about patterns. Patterns become practices we use. We do not need to put in extra effort.
I love his way of presenting, but this is the one of those times - I guess - that he is hampered by his own succes. The talk did not go deep into stuff. During his talk I just about covered 5 not too difficult subjects. I missed his speed and depth.
Still a great talk though.
Was actually very nice!
The Java Magazine was mentioned we (as Editors) had to shout for that!
Please contact me (@ivonet) if you have ambitions to either be an author or maybe even as a fellow editor of the magazine. We are searching for a new Editor now.
Then the voting for the Innovation Awards.
I kinda missed the next keynote by ING because I was playing with a rubix cube and I did not really like his talk
by Ivar Grimstad
Ivar talks about the specification of Jakarta EE.
To create a lite version of CDI it is possible to start doing things at build time and facilitate other tools like GraalVM and Quarkus.
He gives nice demos on how to migrate code to work in de jakarta namespace.
To start your own Jakarta EE application just go to start.jakarta.ee en follow the very simple UI instructions
I am very proud to be the creator of that UI. Thanks, Ivar for giving me a shoutout for that during your talk. More cool stuff will follow soon.
Be prepared to do some namespace changes when moving from Java EE 8 to Jakarta EE.
All slides here
I had a fantastic day. For me, it is mainly about the community and seeing all the people I know in the community. I totally love the vibe of the conference and I think it is one of the best organized venues.
See you at JSpring.
Ivo.
The results of the 2022 Jakarta EE Developer Survey are very telling about the current state of the enterprise Java developer community. They point to increased confidence about Jakarta EE and highlight how far Jakarta EE has grown over the past few years.
Strong Turnout Helps Drive Future of Jakarta EE
The fifth annual survey is one of the longest running and best-respected surveys of its kind in the industry. This year’s turnout was fantastic: From March 9 to May 6, a total of 1,439 developers responded.
This is great for two reasons. First, obviously, these results help inform the Java ecosystem stakeholders about the requirements, priorities and perceptions of enterprise developer communities. The more people we hear from, the better picture we get of what the community wants and needs. That makes it much easier for us to make sure the work we’re doing is aligned with what our community is looking for.
The other reason is that it helps us better understand how the cloud native Java world is progressing. By looking at what community members are using and adopting, what their top goals are and what their plans are for adoption, we can better understand not only what we should be working on today, but tomorrow and for the future of Jakarta EE.
Findings Indicate Growing Adoption and Rising Expectations
Some of the survey’s key findings include:
Two of the results, when combined, highlight something interesting:
After all, you wouldn’t wait for a later version and skip the one that’s already available, unless you were confident that the newer version was not only going to be coming out on a relatively reliable timeline, but that it was going to be an improvement.
And this growing hunger from the community for faster support really speaks to how far the ecosystem has come. When we release a new version, like when we released Jakarta EE 9, it takes some time for the technology implementers to build the product based on those standards or specifications. The community is becoming more vocal in requesting those implementers to be more agile and quickly pick up the new versions. That’s definitely an indication that developer demand for Jakarta EE products is growing in a healthy way.
Learn More
If you’d like to learn more about the project, there are several Jakarta EE mailing lists to sign up for. You can also join the conversation on Slack. And if you want to get involved, start by choosing a project, sign up for its mailing list and start communicating with the team.
The Jakarta EE Ambassadors are thrilled to see Jakarta EE 10 being released! This is a milestone release that bears great significance to the Java ecosystem. Jakarta EE 8 and Jakarta EE 9.x were important releases in their own right in the process of transitioning Java EE to a truly open environment in the Eclipse Foundation. However, these releases did not deliver new features. Jakarta EE 10 changes all that and begins the vital process of delivering long pending new features into the ecosystem at a regular cadence.
There are quite a few changes that were delivered – here are some key themes and highlights:
While there are many features that we identified in our Jakarta EE 10 Contribution Guide that did not make it yet, this is still a very solid release that everyone in the Java ecosystem will benefit from, including Spring, MicroProfile and Quarkus. You can see here what was delivered, what’s on the way and what gaps still remain. You can try Jakarta EE 10 out now using compatible implementations like GlassFish, Payara, WildFly and Open Liberty. Jakarta EE 10 is proof in the pudding that the community, including major stakeholders, has not only made it through the transition to the Eclipse Foundation but now is beginning to thrive once again.
Many Ambassadors helped make this release a reality such as Arjan Tijms, Werner Keil, Markus Karg, Otavio Santana, Ondro Mihalyi and many more. The Ambassadors will now focus on enabling the community to evangelize Jakarta EE 10 including speaking, blogging, trying out implementations, and advocating for real world adoption. We will also work to enable the community to continue to contribute to Jakarta EE by producing an EE 11 Contribution Guide in the coming months. Please stay tuned and join us.
Jakarta EE is truly moving forward – the next phase of the platform’s evolution is here!
Getting started with Jakarta EE just became even easier!
Moved from the Apache 2 license to the Eclipse Public License v2 for the newest version of the archetype as described below.
As a start for a possible collaboration with the Eclipse start project.
New Archetype with JakartaEE 9
JakartaEE 9 + Payara 5.2022.2 + MicroProfile 4.1 running on Java 17
FOSDEM took place February 5-6. The European based event is one of the most significant gatherings worldwide focused on all things Open Source. Named the “Friends of OpenJDK”, in recent years the event has added a devroom/track dedicated to Java. The effort is lead by my friend and former colleague Geertjan Wielenga. Due to the pandemic, the 2022 event was virtual once again. I delivered a couple of talks on Jakarta EE as well as Diversity & Inclusion.
Fundamentals of Diversity & Inclusion for Technologists
I opened the second day of the conference with my newest talk titled “Fundamentals of Diversity and Inclusion for Technologists”. I believe this is an overdue and critically important subject. I am very grateful to FOSDEM for accepting the talk. The reality for our industry remains that many people either have not yet started or are at the very beginning of their Diversity & Inclusion journey. This talk aims to start the conversation in earnest by explaining the basics. Concepts covered include unconscious bias, privilege, equity, allyship, covering and microaggressions. I punctuate the topic with experiences from my own life and examples relevant to technologists. The slides for the talk are available on SpeakerDeck. The video for the talk is now posted on YouTube.
Jakarta EE – Present and Future
Later the same day, I delivered my fairly popular talk – “Jakarta EE – Present and Future”. The talk is essentially a state of the union for Jakarta EE. It covers a little bit of history, context, Jakarta EE 8, Jakarta EE 9/9.1 as well as what’s ahead for Jakarta EE 10. One key component of the talk is the importance and ways of direct developer contributions into Jakarta EE, if needed with help from the Jakarta EE Ambassadors. Jakarta EE 10 and the Jakarta Core Profile should bring an important set of changes including to CDI, Jakarta REST, Concurrency, Security, Faces, Batch and Configuration. The slides for the talk are available on SpeakerDeck. The video for the talk is now posted on YouTube.
I am very happy to have had the opportunity to speak at FOSDEM. I hope to contribute again in the future.
Infinispan 10+ uses Log4j version 2.0+ and can be affected by vulnerability CVE-2021-44228, which has a 10.0 CVSS score. The first fixed Log4j version is 2.15.0.
So, until official patch is coming, - you can update used logger version to the latest in few simple steps
wget https://downloads.apache.org/logging/log4j/2.15.0/apache-log4j-2.15.0-bin.zip
unzip apache-log4j-2.15.0-bin.zip
cd /opt/infinispan-server-10.1.8.Final/lib/
rm log4j-*.jar
cp ~/Downloads/apache-log4j-2.15.0-bin/log4j-api-2.15.0.jar ./
cp ~/Downloads/apache-log4j-2.15.0-bin/log4j-core-2.15.0.jar ./
cp ~/Downloads/apache-log4j-2.15.0-bin/log4j-jul-2.15.0.jar ./
cp ~/Downloads/apache-log4j-2.15.0-bin/log4j-slf4j-impl-2.15.0.jar ./
Please, note - patch above is not official, but according to initial tests it works with no issues
This short 5-minute survey is being presented to the Eclipse Jetty user community to validate conjecture the Jetty developers have for how users will leverage JakartaEE servlets and the Jetty project. We have some features we are gauging interest in before supporting in Jetty 12 and your responses will help shape its forthcoming release.
We will summarize results in a future blog.
Disclaimer: I received this book as a collaboration with Packt and one of the authors (Thanks Emily!)
Year after year many enterprise companies are struggling to embrace Cloud Native practices that we tend to denominate as Microservices, however Microservices is a metapattern that needs to follow a well defined approach, like:
Many of these concepts require a considerable amount of context, but some books, tutorials, conferences and YouTube videos tend to focus on specific niche information, making difficult to have a "cold start" in the microservices space if you have been developing regular/monolithic software. For me, that's the best thing about this book, it provides a holistic view to understand microservices with Java and MicroProfile for "cold starter developers".
Using a software architect perspective, MicroProfile could be defined as a set of specifications (APIs) that many microservices chassis implement in order to solve common microservices problems through patterns, lessons learned from well known Java libraries, and proposals for collaboration between Java Enterprise vendors.
Subsequently if you think that it sounds a lot like Java EE, that's right, it's the same spirit but on the microservices space with participation for many vendors, including vendors from the Java EE space -e.g. Red Hat, IBM, Apache, Payara-.
The main value of this book is the willingness to go beyond the APIs, providing four structured sections that have different writing styles, for instance:
This was by far my favorite section. This section presents a well-balanced overview about Cloud Native practices like:
I enjoyed this section because my current role is to coach or act as a software architect at different companies, hence this is good material to explain the whole panorama to my coworkers and/or use this book as a quick reference.
My only concern with this section is about the final chapter, this chapter presents an application called IBM Stock Trader that (as you probably guess) IBM uses to demonstrate these concepts using MicroProfile with OpenLiberty. The chapter by itself presents an application that combines data sources, front/ends, Kubernetes; however the application would be useful only on Section 3 (at least that was my perception). Hence you will be going back to this section once you're executing the workshop.
This section divides the MicroProfile APIs in three levels, the division actually makes a lot of sense but was evident to me only during this review:
Additionally, section also describes the need for Docker and Kubernetes and how other common approaches -e.g. Service mesh- overlap with Microservice Chassis functionality.
Currently I'm a MicroProfile user, hence I knew most of the APIs, however I liked the actual description of the pattern/need that motivated the inclusion of the APIs, and the description could be useful for newcomers, along with the code snippets also available on GitHub.
If you're a Java/Jakarta EE developer you will find the CDI section a little bit superficial, indeed CDI by itself deserves a whole book/fascicle but this chapter gives the basics to start the development process.
This section switches the writing style to a workshop style. The first chapter is entirely focused on how to compile the sample microservices, how to fulfill the technical requirements and which MicroProfile APIs are used on every microservice.
You must notice that this is not a Java programming workshop, it's a Cloud Native workshop with ready to deploy microservices, hence the step by step guide is about compilation with Maven, Docker containers, scaling with Kubernetes, operators in Openshift, etc.
You could explore and change the source code if you wish, but the section is written in a "descriptive" way assuming the samples existence.
This section is pretty similar to the second section in the reference book style, hence it also describes the pattern/need that motivated the discussion of the API and code snippets. The main focus of this section is GraphQL, Reactive Approaches and distributed transactions with LRA.
This section will probably change in future editions of the book because at the time of publishing the Cloud Native Container Foundation revealed that some initiatives about observability will be integrated in the OpenTelemetry project and MicroProfile it's discussing their future approach.
As any review this is the most difficult section to write, but I think that a second edition should:
The last item is mostly a wish since I'm always in the need for better ways to integrate this common practices with buses like Kafka or Camel using MicroProfile. I know that some implementations -e.g. Helidon, Quarkus- already have extensions for Kafka or Camel, but the data consistency is an entire discussion about patterns, tools and best practices.
Today the Jakarta EE Ambassadors are announcing the start of the Jakarta EE Community Acceptance (JCAT) Testing initiative. The purpose of this initiative is to test Jakarta EE 9/9.1 implementations testing using your code and/or applications. Although Jakarta EE is extensively tested by the TCK, container specific tests, and QA, the purpose of JCAT is for developers to test the implementations.
Jakarta EE 9/9.1 did not introduce any new features. In Jakarta EE 9 the APIs changed from javax to jakarta. Jakarta EE 9.1 raised the supported floor to Java 11 for compatible implementations. So what are we testing?
Participating in this initiative is easy:
To join this initiative, please take a moment to fill-out the form:
To submit results or feedback on your experiences with Jakarta EE 9/9.1:
Jakarta EE 9 / 9.1 Feedback Form
Resources:
Start Date: July 28, 2021
End Date: December 31st, 2021
The Jakarta EE Developer Survey is in its fourth year and is the industry’s largest open source developer survey. It’s open until April 30, 2021. I am encouraging you to add your voice. Why should you do it? Because Jakarta EE Working Group needs your feedback. We need to know the challenges you facing and suggestions you have about how to make Jakarta EE better.
Last year’s edition surveyed developers to gain on-the-ground understanding and insights into how Jakarta solutions are being built, as well as identifying developers’ top choices for architectures, technologies, and tools. The 2021 Jakarta EE Developer Survey is your chance to influence the direction of the Jakarta EE Working Group’s approach to cloud native enterprise Java.
The results from the 2021 survey will give software vendors, service providers, enterprises, and individual developers in the Jakarta ecosystem updated information about Jakarta solutions and service development trends and what they mean for their strategies and businesses. Additionally, the survey results also help the Jakarta community at the Eclipse Foundation better understand the top industry focus areas and priorities for future project releases.
A full report from based on the survey results will be made available to all participants.
The survey takes less than 10 minutes to complete. We look forward to your input. Take the survey now!
Wildfly provides great out of the box load balancing support by Undertow and modcluster subsystems
Unfortunately, in case HTTP headers size is huge enough (close to 16K), which is so actual in JWT era - pity error happened:
ERROR [io.undertow.proxy] (default I/O-10) UT005028: Proxy request to /ee-jax-rs-examples/clusterdemo/serverinfo failed: java.io.IOException: java.nio.BufferOverflowException
at io.undertow.server.handlers.proxy.ProxyHandler$HTTPTrailerChannelListener.handleEvent(ProxyHandler.java:771)
at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction$1.completed(ProxyHandler.java:646)
at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction$1.completed(ProxyHandler.java:561)
at io.undertow.client.ajp.AjpClientExchange.invokeReadReadyCallback(AjpClientExchange.java:203)
at io.undertow.client.ajp.AjpClientConnection.initiateRequest(AjpClientConnection.java:288)
at io.undertow.client.ajp.AjpClientConnection.sendRequest(AjpClientConnection.java:242)
at io.undertow.server.handlers.proxy.ProxyHandler$ProxyAction.run(ProxyHandler.java:561)
at io.undertow.util.SameThreadExecutor.execute(SameThreadExecutor.java:35)
at io.undertow.server.HttpServerExchange.dispatch(HttpServerExchange.java:815)
...
Caused by: java.nio.BufferOverflowException
at java.nio.Buffer.nextPutIndex(Buffer.java:521)
at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:297)
at io.undertow.protocols.ajp.AjpUtils.putString(AjpUtils.java:52)
at io.undertow.protocols.ajp.AjpClientRequestClientStreamSinkChannel.createFrameHeaderImpl(AjpClientRequestClientStreamSinkChannel.java:176)
at io.undertow.protocols.ajp.AjpClientRequestClientStreamSinkChannel.generateSendFrameHeader(AjpClientRequestClientStreamSinkChannel.java:290)
at io.undertow.protocols.ajp.AjpClientFramePriority.insertFrame(AjpClientFramePriority.java:39)
at io.undertow.protocols.ajp.AjpClientFramePriority.insertFrame(AjpClientFramePriority.java:32)
at io.undertow.server.protocol.framed.AbstractFramedChannel.flushSenders(AbstractFramedChannel.java:603)
at io.undertow.server.protocol.framed.AbstractFramedChannel.flush(AbstractFramedChannel.java:742)
at io.undertow.server.protocol.framed.AbstractFramedChannel.queueFrame(AbstractFramedChannel.java:735)
at io.undertow.server.protocol.framed.AbstractFramedStreamSinkChannel.queueFinalFrame(AbstractFramedStreamSinkChannel.java:267)
at io.undertow.server.protocol.framed.AbstractFramedStreamSinkChannel.shutdownWrites(AbstractFramedStreamSinkChannel.java:244)
at io.undertow.channels.DetachableStreamSinkChannel.shutdownWrites(DetachableStreamSinkChannel.java:79)
at io.undertow.server.handlers.proxy.ProxyHandler$HTTPTrailerChannelListener.handleEvent(ProxyHandler.java:754)
The same request directly to backend server works well. Tried to play with ajp-listener and mod-cluster filter "max-*" parameters, but have no luck.
Possible solution here is switch protocol from AJP to HTTP which can be bit less effective, but works well with big headers:
/profile=full-ha/subsystem=modcluster/proxy=default:write-attribute(name=listener, value=default)
I am very pleased to announce that since the beginning of 2021 Oracle is officially a part of MicroProfile Working Group.
In Oracle we believe in standards and supporting them in our products. Standards are born in blood, toil, tears, and sweat. Standards are a result of collaboration of experts, vendors, customers and users. Standards bring the advantages of portability between different implementations that make standard-based solutions vendor-neutral.
We created Java EE which was the first enterprise Java standard. We opened it and moved it to the Eclipse Foundation to make its development truly open source and vendor neutral. Now we are joining MicroProfile which in the last few years has become a leading standard for cloud-native solutions.
We’ve been supporting MicroProfile for years before officially joining the Working Group. We created project Helidon which has supported MicroProfile APIs since MicroProfile version 1.1. Contributing to the evolution and supporting new versions of MicroProfile is one of our strategic goals.
I like the community driven and enjoyable approach of creating cloud-native APIs invented by MicroProfile. I believe that our collaboration will be effective and together we will push MicroProfile forward to a higher level.
The purpose of this article is to consolidate all difficulties and solutions that I've encountered while updating Java EE projects from Java 8 to Java 11 (and beyond). It's a known fact that Java 11 has a lot of new characteristics that are revolutionizing how Java is used to create applications, despite being problematic under certain conditions.
This article is focused on Java/Jakarta EE but it could be used as basis for other enterprise Java frameworks and libraries migrations.
Yes, absolutely. My team has been able to bump at least two mature enterprise applications with more than three years in development, being:
As everything in IT the answer is "It depends . . .". However there are a couple of good reasons to do it:
From my experience with many teams, because of this:
Currently, there are two big branches in JVMs release model:
The rationale behind this decision is that Java needed dynamism in providing new characteristics to the language, API and JVM, which I really agree.
Nevertheless, it is a know fact that most enterprise frameworks seek and use Java for stability. Consequently, most of these frameworks target Java 11 as "certified" Java Virtual Machine for deployments.
Errata: I fixed and simplified this section following an interesting discussion on reddit :)
Java 9 introduced changes in internal classes that weren't meant for usage outside JVM, preventing/breaking the functionality of popular libraries that made use of these internals -e.g. Hibernate, ASM, Hazelcast- to gain performance.
Hence to avoid it, internal APIs in JDK 9 are inaccessible at compile time (but accesible with --add-exports), remaining accessible if they were in JDK 8 but in a future release they will become inaccessible, in the long run this change will reduce the costs borne by the maintainers of the JDK itself and by the maintainers of libraries and applications that, knowingly or not, make use of these internal APIs.
Finally, during the introduction of JEP-260 internal APIs were classified as critical and non-critical, consequently critical internal APIs for which replacements are introduced in JDK 9 are deprecated in JDK 9 and will be either encapsulated or removed in a future release.
However, you are inside the danger zone if:
Any of these situations means that your application has a probability of not being compatible with JVMs above Java 8. At least not without updating your dependencies, which also could uncover breaking changes in library APIs creating mandatory refactors.
Also during Java 9 release, many Java EE and CORBA modules were marked as deprecated, being effectively removed at Java 11, specifically:
As JEP-320 states, many of these modules were included in Java 6 as a convenience to generate/support SOAP Web Services. But these modules eventually took off as independent projects already available at Maven Central. Therefore it is necessary to include these as dependencies if our project implements services with JAX-WS and/or depends on any library/utility that was included previously.
In the same way as libraries, Java IDEs had to catch-up with the introduction of Java 9 at least in three levels:
Overall, none of the Java IDEs guaranteed that plugins will work in JVMs above Java 8. Therefore you could possibly run your IDE over Java 11 but a legacy/deprecated plugin could prevent you to run your application.
You must notice that Java 9 launched three years ago, hence the situations previously described are mostly covered. However you should do the following verifications and actions to prevent failures in the process:
Mike Luikides from O'Reilly affirms that there are two types of programmers. In one hand we have the low level programmers that create tools as libraries or frameworks, and on the other hand we have developers that use these tools to create experience, products and services.
Java Enterprise is mostly on the second hand, the "productive world" resting in giant's shoulders. That's why you should check first if your runtime or framework already has a version compatible with Java 11, and also if you have the time/decision power to proceed with an update. If not, any other action from this point is useless.
The good news is that most of the popular servers in enterprise Java world are already compatible, like:
If you happen to depend on non compatible runtimes, this is where the road ends unless you support the maintainer to update it.
On a non-technical side, under support contract conditions you could be obligated to use an specific JVM version.
OpenJDK by itself is an open source project receiving contributions from many companies (being Oracle the most active contributor), but nothing prevents any other company to compile, pack and TCK other JVM distribution as demonstrated by Amazon Correto, Azul Zulu, Liberica JDK, etc.
In short, there is software that technically could run over any JVM distribution and version, but the support contract will ask you for a particular version. For instance:
Since the jump from Java 8 to Java 11 is mostly an experimentation process, it is a good idea to install multiple JVMs on the development computer, being SDKMan and jEnv the common options:
SDKMan is available for Unix-Like environments (Linux, Mac OS, Cygwin, BSD) and as the name suggests, acts as a Java tools package manager.
It helps to install and manage JVM ecosystem tools -e.g. Maven, Gradle, Leiningen- and also multiple JDK installations from different providers.
Also available for Unix-Like environments (Linux, Mac OS, Cygwin, BSD), jEnv is basically a script to manage and switch multiple JVM installations per system, user and shell.
If you happen to install JDKs from different sources -e.g Homebrew, Linux Repo, Oracle Technology Network- it is a good choice.
Finally, if you use Windows the common alternative is to automate the switch using .bat files however I would appreciate any other suggestion since I don't use Windows so often.
Please remember that any IDE ecosystem is composed by three levels:
After updating your IDE, you should also verify if all of the plugins that make part of your development cycle work fine under Java 11.
Probably the most common choice in Enterprise Java is Maven, and many IDEs use it under the hood or explicitly. Hence, you should update it.
Besides installation, please remember that Maven has a modular architecture and Maven modules version could be forced on any project definition. So, as rule of thumb you should also update these modules in your projects to the latest stable version.
To verify this quickly, you could use versions-maven-plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>versions-maven-plugin</artifactId>
<version>2.8.1</version>
</plugin>
Which includes a specific goal to verify Maven plugins versions:
mvn versions:display-plugin-updates
After that, you also need to configure Java source and target compatibility, generally this is achieved in two points.
As properties:
<properties>
...
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
As configuration on Maven plugins, specially in maven-compiler-plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
Finally, some plugins need to "break" the barriers imposed by Java Modules and Java Platform Teams knows about it. Hence JVM has an argument called illegal-access to allow this, at least during Java 11.
This could be a good idea in plugins like surefire and failsafe which also invoke runtimes that depend on this flag (like Arquillian tests):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<argLine>
--illegal-access=permit
</argLine>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.22.0</version>
<configuration>
<argLine>
--illegal-access=permit
</argLine>
</configuration>
</plugin>
As mentioned before, you need to check for compatible versions on your Java dependencies. Sometimes these libraries could introduce breaking changes on each major version -e.g. Flyway- and you should consider a time to refactor this changes.
Again, if you use Maven versions-maven-plugin has a goal to verify dependencies version. The plugin will inform you about available updates.:
mvn versions:display-dependency-updates
In the particular case of Java EE, you already have an advantage. If you depend only on APIs -e.g. Java EE, MicroProfile- and not particular implementations, many of these issues are already solved for you.
Probably modern REST based services won't need this, however in projects with heavy usage of SOAP and XML marshalling is mandatory to include the Java EE modules removed on Java 11. Otherwise your project won't compile and run.
You must include as dependency:
At this point is also a good idea to evaluate if you could move to Jakarta EE, the evolution of Java EE under Eclipse Foundation.
Jakarta EE 8 is practically Java EE 8 with another name, but it retains package and features compatibility, most of application servers are in the process or already have Jakarta EE certified implementations:
We could swap the Java EE API:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>8.0.1</version>
<scope>provided</scope>
</dependency>
For Jakarta EE API:
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>8.0.0</version>
<scope>provided</scope>
</dependency>
After that, please include any of these dependencies (if needed):
Java EE
<dependency>
<groupId>javax.activation</groupId>
<artifactId>javax.activation-api</artifactId>
<version>1.2.0</version>
</dependency>
Jakarta EE
<dependency>
<groupId>jakarta.activation</groupId>
<artifactId>jakarta.activation-api</artifactId>
<version>1.2.2</version>
</dependency>
Java EE
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
Jakarta EE
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.3</version>
</dependency>
Implementation
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
Java EE
<dependency>
<groupId>javax.xml.ws</groupId>
<artifactId>jaxws-api</artifactId>
<version>2.3.1</version>
</dependency>
Jakarta EE
<dependency>
<groupId>jakarta.xml.ws</groupId>
<artifactId>jakarta.xml.ws-api</artifactId>
<version>2.3.3</version>
</dependency>
Implementation (runtime)
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-rt</artifactId>
<version>2.3.3</version>
</dependency>
Implementation (standalone)
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-ri</artifactId>
<version>2.3.2-1</version>
<type>pom</type>
</dependency>
Java EE
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
Jakarta EE
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
</dependency>
Java EE
<dependency>
<groupId>javax.transaction</groupId>
<artifactId>javax.transaction-api</artifactId>
<version>1.3</version>
</dependency>
Jakarta EE
<dependency>
<groupId>jakarta.transaction</groupId>
<artifactId>jakarta.transaction-api</artifactId>
<version>1.3.3</version>
</dependency>
In the particular case of CORBA, I'm aware of its adoption. There is an independent project in eclipse to support CORBA, based on Glassfish CORBA, but this should be investigated further.
If everything compiles, tests and executes. You did a successful migration.
Some deployments/environments run multiple application servers over the same Linux installation. If this is your case it is a good idea to install multiple JVMs to allow stepped migrations instead of big bang.
For instance, RHEL based distributions like CentOS, Oracle Linux or Fedora include various JVM versions:
Most importantly, If you install JVMs outside directly from RPMs(like Oracle HotSpot), Java alternatives will give you support:
However on modern deployments probably would be better to use Docker, specially on Windows which also needs .bat script to automate this task. Most of the JVM distributions are also available on Docker Hub:
About one month ago I had the pleasure to announce the release of the second edition of my book, now called “Jakarta EE Cookbook”. By that time I had recorded a video about and you can watch it here:
And then came a crazy month and just now I had the opportunity to write a few lines about it!
So, straight to the point, what you should know about the book (in case you have any interest in it).
Java developers working on enterprise applications and that would like to get the best from the Jakarta EE platform.
I’m sure this is one of the most complete books of this field, and I’m saying it based on the covered topics:
The book has the word “cookbook” on its name for a reason: it follows a 100% practical approach, with almost all working code available in the book (we only omitted the imports for the sake of the space).
And talking about the source code being available, it is really available on my Github: https://github.com/eldermoraes/javaee8-cookbook
PRs and Stars are welcomed!
The book has an appendix that would be worthy of another book! I tell the readers how sharing knowledge has changed my career for good and how you can apply what I’ve learned in your own career.
In the first 24 hours of its release, this book simply reached the 1st place at Amazon among other Java releases! Wow!
Of course, I’m more than happy and honored for such a warm welcome given to my baby…
If you are interested in it, we are in the very last days of the special price in celebration of its release. You can take a look here http://book.eldermoraes.com
Leave your comments if you need any clarification about it. See you!
The JDK Flight Recorder (JFR) is an invaluable tool for gaining deep insights into the performance characteristics of Java applications. Open-sourced in JDK 11, JFR provides a low-overhead framework for collecting events from Java applications, the JVM and the operating system.
In this blog post we’re going to explore how custom, application-specific JFR events can be used to monitor a REST API, allowing to track request counts, identify long-running requests and more. We’ll also discuss how the JFR Event Streaming API new in Java 14 can be used to export live events, making them available for monitoring and alerting via tools such as Prometheus and Grafana.