The Evolution Continues. GlassFish, which used to be a popular application server, free to use and reliable, is evolving again. If you’ve been holding onto your old GlassFish instances, there’s good news—things have gotten a lot more exciting recently.
Since we created the OmniFish company and started improving GlassFish in 2022 (read about that story in Oh, What Did You Do to GlassFish?!), a lot has happened around GlassFish. We joined the Eclipse GlassFish project and joined the Jakarta EE Working Group as well. We announced the start of our enterprise support services for Eclipse GlassFish and have been helping our customers and the community of GlassFish users since then. So you may wonder, what’s been happening in the past 2 years and what’s up with GlassFish right now?
The startserv script is a streamlined command-line tool in GlassFish designed to simplify how the server is started in the foreground. The script accepts the same arguments as the asadmin start-domain command. It starts a single JVM, unlike the asadmin start-domain -v command, which does the same but starts 2 JVMs, the main one in the background and another one that remains in the foreground as a proxy. The optimized startserv script is used by the official GlassFish Docker image. This makes running GlassFish in Docker much easier and more resource-efficient, as it consumes less memory by starting a single Java process instead of two.
In this article, we’ll dive into the details of how the startserv script works, its benefits, and how it compares to other GlassFish start and stop methods.
Start GlassFish with the “startserv” script
The startserv script is located in the bin directory in the GlassFish Server installation.
Using the startserv script is very simple. Just run it without any arguments to start GlassFish in foreground:
bin/startserv
It accepts the same arguments as the asadmin start-domain script. So, for example, we can use it to start use a custom myDomain configuration:
bin/startserv myDomain
To start GlassFish in debug mode:
bin/startserv -d
That’s it. This will start GlassFish in foreground, printing all the log messages to the standard output. It reacts on Ctrl+C keyboard instruction to stop the process cleanly – GlassFish will handle the signal, initiate a shutdown and will stop the server in a clean way soon after.
Now, let’s compare this to other ways of starting and stopping GlassFish, and clarify how the startserv script works. Or, more exactly, how it has been optimized recently.
Starting GlassFish in the Background
When you want to start GlassFish in the background, the common command used is:
bin/asadmin start-domain
This command works in the following manner:
It initiates the AsAdmin CLI tool, which reads the JVM options to start GlassFish from the domain.xml configuration file.
This process, in turn, starts a new JVM process in the background that uses the options specified.
Once the second JVM process (which is the main GlassFish process) is up and running, the AsAdmin process terminates, leaving GlassFish running independently in the background.
This approach provides a clean way to start GlassFish in a background process, allowing the user to continue working in the same terminal or shell. After the command completes, it’s guaranteed that GlassFish server is running and can respond to further commands or requests.
Stopping GlassFish
When it’s time to stop GlassFish, there are multiple equivalent commands you can use. Depending on your GlassFish version and installation setup, you can stop the server with any of the following commands:
bin/asadmin stop-domain
glassfish/bin/asadmin stop-domain
glassfish/bin/stopserv
bin/stopserv # Available since GlassFish 7.0.6
These commands function identically and accept the same arguments, such as the domain name. The stopserv script, starting with GlassFish 7.0.6, has been copied to the bin directory for easier access.
Starting GlassFish in the Foreground
Running GlassFish in the foreground is particularly useful in a Docker container or when running GlassFish for debugging or monitoring purposes.
As described above, since GlassFish 7.0.6, you can start GlassFish in foreground simply with:
bin/startserv
To stop it, just press Ctrl+C.
Before GlassFish 7.0.6, if you wanted to start GlassFish in the foreground (so that you can see its output in real-time), several commands would get the job done:
Notice that even before GlassFish 7.0.6, there was a startserv script. However, this script simply delegated to bin/asadmin start-domain --verbose.
These commands not only start GlassFish but also ensure that output from the server is printed directly to the terminal. Let’s take a closer look at what happens behind the scenes (it’s very similar to the steps for running GlassFish in the background):
AsAdmin JVM Process: The first step involves the AsAdmin Java process reading the JVM options from the domain.xml file.
Main JVM Process: A new JVM process is then started in the background, and this is where the main GlassFish process runs.
Terminal Output: The twist here is that the standard output of the second JVM process (the main GlassFish process) cannot be directly displayed in the terminal. Instead, the first AsAdmin process reads the output of the main process and prints it to the terminal.
Perception of a Single Process: From the user’s perspective, it looks like a single GlassFish process is running and producing output in the terminal. In reality, two JVM processes are running simultaneously, with one relaying the output of the other and also reacting to the Ctrl+C keyboard shortcut and delegating the signal.
The optimized “startserv” Script
The new startserv script still starts 2 JVM processes, but stops the first one before the second one is executed. That remains a single main Java process running. Let’s take a closer look at what happens:
AsAdmin JVM Process: The first step involves the AsAdmin Java process reading the JVM options from the domain.xml file. The difference here is that the startserv script instructs it to output the command line to start the Main JVM process instead of launching it.
Main JVM Process: A new JVM process is then started using the command line provided by the AsAdmin JVM Process, and this is where the main GlassFish process runs. This command runs directly in the foreground. The startserv script leaves all interactions with input and output to this JVM process.
A Single Process running: From the user’s perspective, nothing changes. However, now we really get a single JVM running. In fact, even the original startserv script is stopped and everything works in the same way as if you executed the plain java command on command line.
The “startserv” Script in Docker
In the context of Docker, the “startserv” script is a major advantage. The official GlassFish Docker container now uses this script by default, which simplifies the process of launching GlassFish in containers. Unlike older methods that required two Java processes, “startserv” reduces memory consumption by running only a single JVM. This makes it much more efficient for cloud and containerized environments, where memory and resource management are critical.
Conclusion
The “startserv” script and the other associated commands in GlassFish offer flexibility in how you manage server processes across different platforms. Whether you are starting GlassFish in the background for production use or running it in the foreground for debugging and monitoring, the available commands provide comprehensive control over the server’s lifecycle. Its adoption in Docker containers further streamlines operations, making GlassFish easier to manage in resource-constrained environments.
How to: Apache Server as a Load Balancer for your GlassFish Cluster
Setting up a GlassFish server cluster with an Apache HTTP server as a load balancer involves several steps:
Configuring GlassFish for clustering
Setting up the Apache HTTP Server as a load balancer
Enabling sticky sessions for session persistence
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
Step 2: Enable Proxy Modules in Apache HTTP Server
Enable the necessary proxy modules (proxy, proxy_http, proxy_balancer, and lbmethod_byrequests modules) in Apache server:
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:
GlassFish instances must be configured with the jvmRoute system property to add GlassFish instance name to the session cookie
Values in the 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.
With the configuration 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 BalancerMember
The example configuration doesn’t contain HTTPS configuration. We strongly recommend using HTTPS for the Apache virtual host in production, signed with an SSL/TLS certificate, and redirect all plain HTTP requests to equivalent HTTPS requests
If you use a different session cookie name, replace JSESSIONID with your custom cookie name
Step 4: Verify firewall configuration
Verify that:
Apache server can access the HTTP port of each GlassFish instance (port 28080 by default )
GlassFish instances should not be accessible from a public network for security reasons, they should only be accessible from the Apache server
Step 5: Restart Apache HTTP Server
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
Step 6: Verify the Sticky Session routing
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.
With these steps, you should have a basic setup of a GlassFish server cluster
with an Apache HTTP Server acting as a load balancer
sticky session routing for session persistence across requests
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.
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.
Click on the “New…” button to create a new cluster.
Enter a name for the cluster (e.g., myCluster)
In the “Server Instances to Be Created” table, click “New…”, and then fill in instance1 as an instance name, keep “Node” selected to the default “localhost-domain1”
Click “OK”
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).
Step 3: Add routing config for sticky sessions
Navigate to Clusters → myCluster
Click on the “myCluster-config” link in the “Configuration” field
Click on “System Properties” to open the “System Properies” configuration for the cluster
Click on “Add Property” button
In the new row, set the value in the “Instance Variable Name” column to “jvmRoute”
Set “Default Value” to “${com.sun.aas.instanceName}” so that it’s set to the actual instance name for every cluster instance
This configuration is needed to simplify the sticky session routing mechanism in load balancers, e.g. in Apache HTTP server.
Step 4: Start the cluster
Navigate to “Clusters”
Click the checkbox in the “Select” column next to your cluster
Click “Start Cluster” button and wait until the cluster is started
Right 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.
Step 6: Add an SSH Node
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:
In GlassFish Admin Console, navigate to Nodes. There’s always at least 1 node, e.g. localhost-domain1, which represents the local machine
Click on the “New…” button to add a new SSH node.
Enter a name for the SSH node (e.g., sshNode1).
Set the “Type” to “SSH”
Set the “Host” to the IP address of the remote machine.
If you want to install GlassFish on the remote machine, enable the ckeckbox “Install GlassFish Server”
Set the “SSH User” to a user with sufficient privileges on the remote machine. Set to `${user.name} if it’s the same user as the one running the GlassFish admin server
Set the “SSH User Authentication” based on your authentication method. Fill in the authentication details, e.g. “SSH User Password” for “Password” authentication
Click “OK” to add the SSH node.
Step 7: Create an Instance on the SSH Node
Navigate to Clusters → myCluster.
Select the “Instances” tab.
Click on the “New…” button to create a new instance.
Enter a name for the new instance (e.g., remoteInstance) and select the SSH node (sshNode1) as the target “Node”.
Click “OK” to create the instance.
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:
Navigate to Clusters → myCluster, the tab “Instances”
Click on “remoteInstance” in the “Name” column
The admin port number is the first port in the “HTTP Port(s)” field
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.
Step 8: Start the remote instance
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.
Navigate to “Clusters”
Click the checkbox in the “Select” column next to your cluster
Click “Start Cluster” button and wait until the cluster is started
Alternatively, you can start the remoteInstance individually:
Navigate to the “Instances” tab
Select remoteInstance and click on the “Start” button.
Step 9: Verify Load Balancing
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:
Replace load-balancer-ip and load-balancer-port with the appropriate values for your load balancer server.
Verify that after an HTTP session is created, your requests are served by the same GlassFish instance and your session data remains in the session.
After you reset the session, it’s possible that your future requests will be served by a different GlassFish instance
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.
Step 10: Deploy your application to 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:
In GlassFish Admin Console, navigate to Applications and click the “Deploy…” button
In the “Targets” section, click on your cluster in the “Available Targets” column and click the “Add >” button
Configure other deployment properties and click “OK”
Summary
That’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.
In this article, we’ll address upgrading individual libraries used by your applications. This solves two problems. First, it improves the build time of your application during development and reduces the build time introduced by transforming the final binary after each build. And second, it solves compilation problems you can face with some libraries after you adjust the source code of your application for Jakarta EE 10.
In our previous article, we explored the initial steps of migrating Java EE 8 or Jakarta EE 8 applications to Jakarta EE 10. We transformed the final binary application using the Eclipse Transformer to deploy it on a Jakarta EE 10 runtime. Building upon that foundation, we now dive deeper into the next crucial phase of the upgrade process: transforming the application’s source code to use the Jakarta EE 10 APIs. This will enable you to use new features in Jakarta EE 10 as well as newer versions of external libraries that require Jakarta EE 10.
As we described in the introductory article, migrating your existing Java EE 8 or Jakarta EE 8 applications to Jakarta EE 10 can be streamlined by a few existing tools. In this article, we’ll explore the first crucial step in upgrading to Jakarta EE 10: using the Eclipse Transformer to transform your final binary application so that it can be deployed to a Jakarta EE runtime like Eclipse GlassFish 7.
Upgrading to Jakarta EE 10 from an older version of Jakarta EE or Java EE can be a bit tricky and may require some extra attention to detail. One of the main things you may encounter is making sure your existing code and libraries are compatible. Some libraries may still be using the javax package, which can cause conflicts when trying to run your applications on a Jakarta EE server like Eclipse GlassFish 7. You might also run into problems with some deprecated APIs that were removed in Jakarta EE 10.
But don’t worry, we’ve got you covered! In this post and the future posts in this series, we’ll explain everything you need to know to upgrade to Jakarta EE 10 successfully and almost in no time.
Jakarta EE is an open source platform for developing enterprise Java applications. It is the successor to the popular Java EE platform, and provides an extensive set of APIs and tools for building enterprise applications.
In this article, we’ll provide some of the most helpful resources for getting started or becoming highly productive with this powerful platform. Let’s dive in!
Do you want to have a say in what happens for the next version of Jakarta EE? Check out the new edition of the Jakarta EE Survey 2022 by OmniFish, which follows the tradition of the bi-annual OmniFaces surveys. The purpose of the survey is to help everybody understand the current status of the Jakarta EE ecosystem, what we as a community represent, which parts of Jakarta EE we all use the most and what we all expect from Jakarta EE in the future.
We’d like to invite all Jakarta EE users to participate in the survey here:
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Duration
Description
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.