So far, we have covered many Java Enterprise examples and deployed them on the application server. We will now dive headlong into the vast and varied ocean of instruments that are available to manage the application server. The purpose of this chapter is to teach you how to use these instruments to administer and monitor all the resources available on the application server.
Here is the list of topics we will cover in this chapter:
A CLI is a complete management tool that can be used to start and stop servers, deploy and undeploy applications, configure system resources, and perform other administrative tasks. Operations in it can be executed in an atomic way or in batch modes, allowing you to run multiple tasks as a group.
If you are using Windows, you can start the CLI by entering the following command from the JBOSS_HOME/bin
folder using the Command Prompt:
jboss-cli.bat
Alternatively, enter the following command if you are using Linux:
./jboss-cli.sh
Once the CLI has started, you can connect to the managed server instance using the connect
command, which by default connects to localhost
and the 9990
port:
[disconnected /] connect [standalone@localhost:9990 /]
If you want to connect to another address or port, you can simply pass it to the connect
command, as follows:
[disconnected /] connect 192.168.1.1 [[email protected]:9990 /]
It is also possible to launch a CLI in the connected mode; this allows it to be connected automatically and to possibly specify the commands to be executed. For example, the following shell
command automatically connects to a WildFly instance and issues a shutdown
command:
> jboss-cli.bat --connect command=:shutdown {"outcome" => "success"}
CLI is especially useful for the automation of your software development process—Continuous Integration (CI) and production environment management systems can automatically control the life cycle of your application server with tools such as Chef (https://www.getchef.com/) or Puppet (http://puppetlabs.com/). It might be handy if you would like to minimize the number of manual tasks that are required to be done to deploy an application.
Starting from the 7.1.0 Beta release of the application server, security is enabled on AS management interfaces by default to prevent unauthorized remote access to the application server. Although local clients of the application server are still allowed to access management interfaces without any authentication, remote clients need to enter a username/password pair to access a CLI. Here's an example session that successfully connects to a remote host with the IP address 10.13.2.255
:
[disconnected /] connect 10.13.2.255 Authenticating against security realm: ManagementRealm Username: administrator Password: [[email protected]:9990 /]
Please refer to Chapter 2, Your First Java EE Application on WildFly, for more information about creating a user with the add-user.sh
shell command.
An interesting option available for the command-line interface is the graphical mode, which can be activated by adding the --gui
parameter to the shell script:
jboss-cli.bat --gui
Here's how CLI looks in the graphical mode:
As described in the label, the resource will expand when you click on a folder; on the other hand, if you right-click on a node, you can fire an operation on it. The graphical mode could be useful to explore the possible configuration values or if you are not a big fan of console tools.
The next section discusses how to construct CLI commands, which can be executed either in the terminal mode or the graphical mode.
All CLI operation requests allow you to have low-level interactions with the server management model. They provide a controlled way to edit the server configurations. An operation request consists of three parts:
/
:
()
The server configuration is presented as a hierarchical tree of addressable resources. Each resource node offers a different set of operations. The address specifies the resource node on which to perform the operation. An address uses the following syntax:
/node-type=node-name
The notations are explained as follows:
Separate each level of the resource tree with a slash (/
). So, for example, the following CLI expression identifies the ExampleDS data source registered in the data source subsystem:
/subsystem=datasources/data-source=ExampleDS
Once you have identified a resource, you can perform operations on the resource. An operation uses the following syntax:
:operation-name
So in the previous example, you can query the list of available resources for your nodes by adding the read-resource
command at the end of it:
/subsystem=datasources/:read-resource { "outcome" => "success", "result" => { "data-source" => {"ExampleDS" => undefined}, "jdbc-driver" => {"h2" => undefined}, "xa-data-source" => undefined } }
If you want to query for a specific attribute of your node, you can use the read-attribute
operation instead. For example, the following code shows how to read the enabled attribute from the data source:
/subsystem=datasources/data-source=ExampleDS/:read-attribute(name=enabled) { "outcome" => "success", "result" => false }
Apart from the operations on a specific resource, you can also perform a set of commands that are available on every path of your WildFly subsystem, such as cd
or ls
commands. These commands are pretty much equivalent to their Unix shell counterparts, and they allow you to navigate through the WildFly subsystems. Other important additions are the deploy
and undeploy
commands that, as you might guess, allow you to manage the deployment of applications. These key commands are discussed in the Deploying applications using the CLI section of this chapter.
The CLI, however, is not just about querying attributes from the WildFly subsystems; you can also set attributes or create resources. For example, if you were to set the HTTP port of the HTTP connector, you will have to use the corresponding write
attribute on HTTP's socket binding interface, shown as follows:
/socket-binding-group=standard-sockets/socket-binding=http/:write-attribute(name=port,value=8080) { "outcome" => "success","response-headers" => { "operation-requires-reload" => true, "process-state" => "reload-required" } }
Apart from the operations that we have seen so far, which can be performed on every resource of your subsystems, there can be special operations that can be performed exclusively on one resource. For example, within the naming subsystem, you will be able to issue a jndi-view
operation that will display the list of JNDI bindings, as shown in the following code snippet:
/subsystem=naming/:jndi-view { "outcome" => "success", "result" => {"java: contexts" => { "java:" => { "TransactionManager" => { "class-name" => "com.arjuna.ats.jbossatx.jta.TransactionManagerDelegate","value" => "com.arjuna.ats.jbossatx.jta.TransactionManagerDelegate@afd978" }, . . . }
Getting to know all the available commands in the CLI is a pretty hard task; this management interface includes an essential feature, the tab completion. Suppose the cursor is positioned at the beginning of an empty line; now if you type in /
and press the Tab key, you will get the following list of all the available node types:
[standalone@localhost:9990 /] / core-service extension socket-binding-group deployment interface subsystem deployment-overlay path system-property
After selecting the node type, you want to enter into the tree of resources, so type =
and press the Tab key again. This will result in a list of all the following node names available for the chosen node type:
[standalone@localhost:9990 /] /subsystem= batch jdr resource-adapters datasources jmx sar deployment-scanner jpa security ee jsf threads ejb3 logging transactions infinispan mail undertow io naming webservices jaxrs pojo weld jca remoting
After you have finished with the node path, adding a colon (:
) at the end of the node path and pressing the Tab key will display all the available operation names for the selected node, which is shown as follows:
[standalone@localhost:9990 /] /subsystem=deployment-scanner/scanner=default: add read-resource read-attribute read-resource-description read-children-names remove read-children-resources resolve-path read-children-types undefine-attribute read-operation-description whoami read-operation-names write-attribute
To see all the parameters of the add
operation (after the operation name), press the Tab key:
[standalone@localhost:9990 /] /subsystem=deployment-scanner/scanner=default:read-attribute( include-defaults= name=
Choose the parameter you want and specify its value after =
:
[standalone@localhost:9990 /] /subsystem=deployment-scanner/scanner=default:read-attribute(name= runtime-failure-causes-rollback scan-enabled relative-to scan-interval path auto-deploy-zipped auto-deploy-exploded deployment-timeout auto-deploy-xml
Finally, when all the parameters have been specified, add )
and press Enter to issue the following command:
[standalone@localhost:9990 /] /subsystem=deployment- scanner/scanner=default:read-attribute(name=scan-enabled) { "outcome" => "success", "result" => true }
Deploying an application (in the standalone mode) can be easily performed by copying the application's archives into the deployment
folder of your server distribution. That's a pretty handy option; however, we would like to stress the advantage of using a CLI, which offers a wide choice of additional options when deploying and also provides the opportunity to deploy applications remotely.
All it takes to deploy an application's archive is a connection to the management instance, either local or remote, and by issuing of the deploy
shell command. When used without arguments, the
deploy
command provides a list of applications that are currently deployed, as shown in the following command:
[disconnected /] connect [standalone@localhost:9990 /] deploy ExampleApp.war
If you feed a resource archive such as a WAR
file to the shell, it will deploy it on the standalone server right away, as shown in the following command:
[standalone@localhost:9990 /] deploy ../MyApp.war
By default, a CLI uses the JBOSS_HOME/bin
file as a source for your deployment archives. You can, however, use absolute paths when specifying the location of your archives; the CLI expansion facility (using the Tab key) makes this option fairly simple:
[standalone@localhost:9990 /] deploy c:deploymentsMyApp.war
Redeploying the application requires an additional flag to be added to the deploy
command. Use the -f
argument to force the application's redeployment:
[standalone@localhost:9990 /] deploy -f ../MyApp.war
Undeploying the application can be done through the undeploy
command, which takes the application that is deployed as an argument. This is shown in the following command:
[standalone@localhost:9990 /] undeploy MyApp.war
By checking the WildFly configuration file (for example, standalone.xml
or domain.xml
), you will notice that the deployment element for your application has been removed.
When you are deploying an application using the domain mode, you will have to specify to which server group the deployment is associated with. The CLI lets you choose between the following two options:
If this option is chosen, the application will be deployed to all the available server groups. The --all-server-groups
flag can be used for this purpose. For example, refer to the following code:
[domain@localhost:9990 /] deploy ../application.ear --all-server-groups
If, on the other hand, you want to undeploy an application from all the server groups that belong to a domain, you will have to issue the undeploy
command as shown in the following command:
[domain@localhost:9990 /] undeploy application.ear --all-relevant-server-groups
You might have noticed that the undeploy
command uses the --all-relevant-server
-group instead of the --all-server-
group. The reason for this difference is that the deployment might not be enabled on all the server groups; therefore, by using this option, you will actually undeploy it from all the server groups in which the deployment is enabled.
The other option lets you perform a selective deployment of your application only on the server groups you indicate:
[domain@localhost:9990 /] deploy application.ear --server-groups=main-server-group
You are not limited to a single server group, and you can separate multiple server groups with a comma (,
). For example, refer to the following code:
[domain@localhost:9990 /] deploy application.ear --server-groups=main-server-group,other-server-group Successfully deployed application.ear
The tab completion feature will help you to complete the value for the list of --server-groups
selected for deployment.
Now, suppose we want to undeploy the application from just one server group. In this case, there can be two possible outcomes. If the application is available just on that server group, you will successfully complete the undeployment as shown in the following command:
[domain@localhost:9990 /] undeploy wflyproject.war --server-groups=main-server-group
On the other hand, if your application is available on other server groups, the following error will be returned by the CLI:
Undeploy failed: {"domain-failure-description" => {"Composite operation failed and was rolled back. Steps that failed:" => {"Operation step-3" => "Cannot remove deployment wflyproject.war from the domain as it is still used by server groups [other-server-group]"}}}
It seems that something went wrong. As a matter of fact, when you are removing an application from a server group, the domain controller will verify that any other server group will not refer to the application; otherwise, the previous command will fail.
You can, however, instruct the domain controller to undeploy the application without deleting the content as well. This is shown in the following command:
[domain@localhost:9990 /] undeploy application.ear --server-groups=main-server-group --keep-content
As a program developer, you might be interested to know that a CLI can execute commands in a non-interactive way by adding them to a file, just as a shell script. In order to execute the script, you can launch the CLI with the --file
parameter as in the following example (for Windows):
jboss-cli.bat --file=test.cli
The equivalent command for Unix users will be as follows:
./jboss-cli.sh --file=test.cli
In the next section, we will look at some useful scripts that can be added to your administrator toolbox.
The earlier JBoss AS releases used to ship with a farm
folder, which would trigger a deployment to all the nodes that are part of a JBoss cluster. This option is not included anymore with JBoss AS7 and WildFly, but resurrecting a farm deployment is just a matter of following a few CLI instructions.
In the following example, we are deploying an application to the default server address (127.0.0.1
and port 9990
) and to another server instance that is bound to the same address but to port 10190
:
connect deploy /usr/data/example.war connect 127.0.0.1:10190 deploy /usr/data/example.war
A common requirement for the domain administrator is to restart the application server nodes, for example, when some server libraries are updated. CLI provides a handy shortcut to stop and start all the servers that are part of a server group:
connect /server-group=main-server-group:start-servers /server-group=main-server-group:stop-servers
If you prefer a more granular approach, you can start the single server nodes as shown in the following example, which shows how you can apply conditional execution logic in your CLI scripts:
connect if (result == "STARTED") of /host=master/server-config=server-one:read-attribute(name=status) /host=master/server-config=server-one:stop end-if if (result == "STARTED") of /host=master/server-config=server-two:read-attribute(name=status) /host=master/server-config=server-two:stop end-if /host=master/server-config=server-one:start /host=master/server-config=server-two:start
In the if end-if
part of the code, we are checking for the server's status attribute. If the status is STARTED, the application servers are stopped and then restarted.
In WildFly, you can use the module
command in order to install a new module. We already did something similar in Chapter 5, Combining Persistence with CDI. Now, you can fully automate a data source creation as shown in the following example:
connect module add --name=org.postgresql --resources= postgresql-9.3-1101.jdbc41.jar --dependencies=javax.api,javax.transaction.api /subsystem=datasources/jdbc-driver=postgresql:add(driver-module-name=org.postgresql,driver-name=postgresql,driver-class-name=org.postgresql.Driver) /subsystem=datasources/data-source=PostgreSQLDS:add(jndi-name=java:jboss/datasources/PostgreSQLDS , driver-name=postgresql, connection-url=jdbc:postgresql://localhost:5432/ticketsystem,user-name=jboss,password=jboss)
The first line of the script, after the connection, installs a new module named org.postgresql
in your server modules' directory, including the PostgreSQL JDBC driver and the required dependencies.
The second line installs the JDBC driver for the org.postgresql
module into the datasources/jdbc-driver
subsystem.
Finally, a data source is added to jndi java:jboss/datasources/PostgreSQLDS
with the required URL and credentials.
Adding a new JMS destination is quite easy since it does not require a lengthy set of commands. However, it is sometimes your application that needs to set up lots of JMS destinations in order to work, so why not create a script for it too? The following is a tiny script that adds a JMS queue to the server configuration:
connect jms-queue add --queue-address=queue1 --entries=queues/queue1
The following is the corresponding script you can use to create a JMS topic:
connect jms-topic add --topic-address=topic1 --entries=topics/topic1
18.227.161.225