Featured Posts
  • A Successful Year of MiddlewareMagic

    A Successful Year of MiddlewareMagic

    Hi All, Middleware Magic has completed it's 1-year today (7-Nov_2011). It was a great learning for us and your contribution and interest for this Community of Middleware guys are really appreciated. A year back we wanted to start a platform/community where Middleware guys can discuss their issues and can learn new ...

    Read More

  • How To Pause and Resume A Queue Using WLST

    How To Pause and Resume A Queue Using WLST

    Today one of our subscribers Pavan had asked us by using comment , Here based on the query of Pavan we are writing the following article, which would Pause the Queue at Runtime even when the AdminServer/AdminConsole  is unavailable, thus we took out sometime and just now created a WLST ...

    Read More

  • Tune the JVM that runs Coherence Revisited

    Tune the JVM that runs Coherence Revisited

    In this post we present steps and considerations involved when tuning the HotSpot JVM that runs an application that uses Coherence. In a previous post we already outlined the steps involved in tuning the JRockit JVM. Basically, we can follow the same steps, i.e., tune the heap size and select ...

    Read More

  • Changing WebLogic’s WebServer Log Settings using WLST

    Changing WebLogic's WebServer Log Settings using WLST

    Hi, Based on the  Comment/Query of one of our Magic Subscriber "Kimjim" (http://middlewaremagic.com/weblogic/?p=1473#comment-4594) , We are going to see how we can edit the WebServer Logging like displaying the Client IP Adddress in the access Log of a Server by adding (Extended Loging Formats  c-ip) and changing the various attribute of ...

    Read More

  • Fun with Spring

    In this post we are going to have a little fun with Spring. We show how dependency injection works, how to provide aspects to beans, see how to integrate Hibernate, how to obtain resources such as data sources, JMS connection factories and JMS queues from JNDI, how to create message-driven ...

    Read More

  • Target and Untargeting of Multiple DataSources using WLST

    Target and Untargeting of Multiple DataSources using WLST

    Yesterday one of our subscribers Ravi Shankar Kumar had asked us using comment how to target and untarget multiple datasources in the same domian using a single generic WLST script, as they have total 5 clusters and want to target each cluster to different datasources and as per his requirement we created this simple ...

    Read More

  • Fun with Coherence

    In this post we present some Coherence goodies, which might come in handy when developing with Coherence. As it is supposed to be a fun post, there will be lots of code examples and less text. We start of with preparing our objects for caching. Next we show an example ...

    Read More

  • WebLogic Server is in ADMIN State ?

    WebLogic Server is in ADMIN State ?

    Hi, In Response to Mr. Chris Giddings.. Comment/Query on ADMIN State. Here we are going to see a Scenario which is very common but troublesome. Many times we observe that while trying to restart the Managed Servers the Servers move to ADMIN State rather than moving to the RUNNING State.  This usually ...

    Read More

  • Fast, Faster, JRockit

    Fast, Faster, JRockit

    In this post we are going to tell you everything you ever wanted to know about the JRockit JVM, well quite a lot anyway. First we dive into the JRockit fundamentals, like code generation, memory management and threading. Next we use these fundamentals in the tuning section. We end this ...

    Read More

  • Setting-up a High Available Tuned Java EE environment using WebLogic

    Setting-up a High Available Tuned Java EE environment using WebLogic

    In this post we show a step-by-step example of how to set-up a high available tuned Java EE environment. We start with installing a Java Virtual Machine (in this case JRockit) and WebLogic. We continue with configuring a domain and tune the Java Virtual Machine for the admin server. Next, ...

    Read More

1 2 3 4 5 6 7 8 9 10

Automate WebLogic 12c Deployment

In this post we show a step-by-step example of how to set-up a high available tuned Java EE environment by using scripts. We start with installing a Java Virtual Machine (in this case JRockit) and WebLogic 12c. We continue with configuring a domain and tune the Java Virtual Machine. Next, we show the steps involved in setting up a cluster (with machines, managed servers and resource such data sources and Java Messaging). When running on a WebLogic environment (without fusion middleware components of which an example can be found here) we can proceed as follows.

First, we have to decide which directory structure we are going to use. Below an example is given in which the binaries (that create the WebLogic run-time) are separated from the configuration.

/home/weblogic
	/jrockit-jdk1.6.0_29-R28.2.2-4.1.0 (created during the installation of JRockit)
	/weblogic12.1.1
		/installation (directory which will contain all the software)
			/coherence_3.7 (created during the installation of WebLogic Server)
			/wlserver_12.1 (created during the installation of WebLogic Server)
		/configuration
			/applications
				/base_domain (created during the configuration of WebLogic Server)
			/domains
				/base_domain (created during the configuration of WebLogic Server)
			/nodemanagers
				/base_domain (created during the configuration of WebLogic Server)

To install WebLogic (that uses JRockit as the Java Virtual Machine) we can use the following script

#!/bin/bash

SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/SetEnvironmentVariables.sh

create_silent_install_files() {
	echo 'CREATING SILENT INSTALL FILES'
	echo '<?xml version="1.0" encoding="UTF-8" ?>
<domain-template-descriptor>
	<input-fields>
		<!-- Installation directory -->
		<data-value name="USER_INSTALL_DIR" value="'${JAVA_HOME}'"/>
		<!-- Optional installation of Demos and Samples -->
		<data-value name="INSTALL_DEMOS_AND_SAMPLES" value="false"/>
		<!-- Optional installation of Source Code -->
		<data-value name="INSTALL_SOURCE_CODE" value="false"/>
		<!-- Optional installation of Public JRE -->
		<data-value name="INSTALL_PUBLIC_JRE" value="false"/>
	</input-fields>
</domain-template-descriptor>' > ${SCRIPT_PATH}/silent-jrockit.xml

	echo '<?xml version="1.0" encoding="UTF-8"?>
<bea-installer>
	<input-fields>
		<!-- BEAHOME: The full path for the middleware home directory. -->
		<data-value name="BEAHOME" value="'${MIDDLEWARE_HOME}'"/>
		<!-- WLS_INSTALL_DIR: The full path for the directory where to install WebLogic Server. -->
		<data-value name="WLS_INSTALL_DIR" value="'${WEBLOGIC_HOME}'"/>
		<!-- OCP_INSTALL_DIR: The full path for the directory where to install Coherence. -->
		<data-value name="OCP_INSTALL_DIR" value="'${COHERENCE_HOME}'"/>
		<!-- COMPONENT_PATHS: Specify the components and subcomponents to install. -->
		<data-value name="COMPONENT_PATHS" value="WebLogic Server/Core Application Server|WebLogic Server/Administration Console|WebLogic Server/Configuration Wizard and Upgrade Framework|WebLogic Server/Web 2.0 HTTP Pub-Sub Server|WebLogic Server/WebLogic SCA|WebLogic Server/WebLogic JDBC Drivers|WebLogic Server/Third Party JDBC Drivers|WebLogic Server/WebLogic Server Clients|WebLogic Server/Xquery Support|Oracle Coherence/Coherence Product Files"/>
		<!-- INSTALL_NODE_MANAGER_SERVICE: Install Node Manager as a Windows service. -->
		<data-value name="INSTALL_NODE_MANAGER_SERVICE" value="no"/>
		<!-- LOCAL_JVMS: Select JVMs which are already installed. -->
		<data-value name="LOCAL_JVMS" value="'${JAVA_HOME}'"/>
		<!-- BEA_BUNDLED_JVMS: Option to select BEA bundled JVMS -->
                <data-value name="BEA_BUNDLED_JVMS" value=""/>
	</input-fields>
</bea-installer>' > ${SCRIPT_PATH}/silent-weblogic.xml
}

install_jrockit() {
	echo 'INSTALLING JAVA VIRTUAL MACHINE'
	${SOFTWARE_DIRECTORY}/${JVM_FILE_NAME} -mode=silent -silent_xml=${SCRIPT_PATH}/silent-jrockit.xml -log=${SCRIPT_PATH}/logs/jrockit-install.log

	echo 'ADJUST ENTROPY GATHERING DEVICE SETTINGS'
	sed '/securerandom/ s_file:/dev/urandom_file:/dev/./urandom_' ${JAVA_HOME}/jre/lib/security/java.security > ${SCRIPT_PATH}/java.security
	mv ${SCRIPT_PATH}/java.security ${JAVA_HOME}/jre/lib/security/java.security
}

install_weblogic() {
	echo 'INSTALLING WEBLOGIC SERVER'
	${JAVA_HOME}/bin/java -Xms512m -Xmx512m -jar ${SOFTWARE_DIRECTORY}/${WEBLOGIC_FILE_NAME} -mode=silent -silent_xml=${SCRIPT_PATH}/silent-weblogic.xml -log=${SCRIPT_PATH}/logs/weblogic-install.log
}

copy_endorse_jars() {
	echo 'COPY ENDORSE JARS'
	mkdir -p ${JAVA_HOME}/jre/lib/endorsed
	cp ${MIDDLEWARE_HOME}/wlserver_12.1/endorsed/*.jar ${JAVA_HOME}/jre/lib/endorsed
}

create_silent_install_files

install_jrockit

install_weblogic

copy_endorse_jars

Note that the ‘copy endorse jars’ is necessary in the case of JRockit as this is based on JDK6 and not JDK7. When running on multiple machines the script has to be executed on every machine where WebLogic is going to run. In this case it is beneficiary to use a shared storage as a place to keep the software that has to be installed (such as the jrockit-jdk1.6.0_29-R28.2.2-4.1.0-linux-x64.bin file and the wls1211_generic.jar file) In the script above we set the essential variables, such as MIDDLEWARE_HOME, in a file called SetEnvironmentVariables.sh which in our case has the following contents

#!/bin/sh

# Directory where the software to be installed is located
SOFTWARE_DIRECTORY="/home/weblogic/temp/install_files"
export SOFTWARE_DIRECTORY

# Name of JVM file
JVM_FILE_NAME="jrockit-jdk1.6.0_29-R28.2.2-4.1.0-linux-x64.bin"
export JVM_FILE_NAME

# Name of the WebLogic file
WEBLOGIC_FILE_NAME="wls1211_generic.jar"
export WEBLOGIC_FILE_NAME

# Directory base that will be used for the JVM and WebLogic
BASE_DIRECTORY="/home/weblogic"
export BASE_DIRECTORY

# Directory where the JVM will be installed
JAVA_HOME="${BASE_DIRECTORY}/jrockit-jdk1.6.0_29"
export JAVA_HOME

# Directory where WebLogic will be installed
MIDDLEWARE_HOME="${BASE_DIRECTORY}/weblogic12.1.1/installation"
export MIDDLEWARE_HOME

# Depending on the WebLogic version to be installed, edit the wlserver_major.minor version
WEBLOGIC_HOME="${MIDDLEWARE_HOME}/wlserver_12.1"
export WEBLOGIC_HOME

# Depending on the Coherence version to be installed, edit the coherence_major.minor version
COHERENCE_HOME="${MIDDLEWARE_HOME}/coherence_3.7"
export COHERENCE_HOME

Note that these settings are used to create response files, which are used by the JRockit and WebLogic installers (and reflect our directory structure presented above).

[weblogic@middleware-magic setup]$ ./InstallSoftwareService.sh
CREATING SILENT INSTALL FILES
INSTALLING JAVA VIRTUAL MACHINE
Extracting 0%....................................................................................................100%
ADJUST ENTROPY GATHERING DEVICE SETTINGS
INSTALLING WEBLOGIC SERVER
Extracting 0%....................................................................................................100%
COPY ENDORSE JARS

Once the software is installed we continue with creating a domain. We split the creation of the domain in two phases. The first phase creates a basic domain (with an Admin Server) and sets up the node manager on the machine where the Admin Server is running. The second phase creates the deployment environment, such as clusters, machines, managed servers, messaging resource etcetera. In this manner we create different building blocks to set-up different domains. To set-up a basic domain (Node Manager plus AdminServer) we can use the following WLST script

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

def createFile(directory_name, file_name, content):
	dedirectory = java.io.File(directory_name);
	defile = java.io.File(directory_name + '/' + file_name);

	writer = None;
	try:
		dedirectory.mkdirs();
		defile.createNewFile();
		writer = java.io.FileWriter(defile);
		writer.write(content);
	finally:
		try:
			print 'WRITING FILE ' + file_name;
			if writer != None:
				writer.flush();
				writer.close();
		except java.io.IOException, e:
			e.printStackTrace();

print 'CREATE DOMAIN';
readTemplate(weblogic_template);
setOption('DomainName', domain_name);
setOption('OverwriteDomain', 'true');
setOption('JavaHome', jvm_directory);
setOption('ServerStartMode', 'prod');
cd('/Security/base_domain/User/weblogic');
cmo.setName(admin_username);
cmo.setUserPassword(admin_password);
cd('/');

print "SAVE DOMAIN";
writeDomain(domain_home);
closeTemplate();

print 'READ DOMAIN';
readDomain(domain_home);

print "SET NODE MANAGER CREDENTIALS";
cd("/SecurityConfiguration/" + domain_name);
cmo.setNodeManagerUsername(node_manager_username);
cmo.setNodeManagerPasswordEncrypted(node_manager_password);

print "DISABLE HOSTNAME VERIFICATION";
cd('/Server/AdminServer');
create('AdminServer','SSL');
cd('SSL/AdminServer');
cmo.setHostnameVerificationIgnored(true);
cmo.setHostnameVerifier(None);
cmo.setTwoWaySSLEnabled(false);
cmo.setClientCertificateEnforced(false);

print 'SAVE CHANGES';
updateDomain();
closeDomain();

print 'CREATE FILES';
directory_name = domain_home + '/servers/AdminServer/security';
file_name = 'boot.properties';
content = 'username=' + admin_username + '\npassword=' + admin_password;
createFile(directory_name, file_name, content);

directory_name = domain_application_home;
file_name = 'readme.txt';
content = 'This directory contains deployment files and deployment plans.\nTo set-up a deployment, create a directory with the name of the application.\nSubsequently, create two sub-directories called app and plan.\nThe app directory contains the deployment artifact.\nThe plan directory contains the deployment plan.';
createFile(directory_name, file_name, content);

directory_name = node_manager_home;
file_name = 'nodemanager.properties';
content='DomainsFile=' + node_manager_home + '/nodemanager.domains\nLogLimit=0\nPropertiesVersion=10.3\nDomainsDirRemoteSharingEnabled=false\njavaHome=' + jvm_directory + '\nAuthenticationEnabled=true\nNodeManagerHome=' + node_manager_home + '\nJavaHome=' + jvm_directory + '/jre\nLogLevel=INFO\nDomainsFileEnabled=true\nStartScriptName=startWebLogic.sh \nListenAddress=\nNativeVersionEnabled=true\nListenPort=5556\nLogToStderr=true\nSecureListener=true\nLogCount=1\nDomainRegistrationEnabled=false\nStopScriptEnabled=false\nQuitEnabled=false\nLogAppend=true\nStateCheckInterval=500\nCrashRecoveryEnabled=false\nStartScriptEnabled=true\nLogFile=' + node_manager_home + '/nodemanager.log\nLogFormatter=weblogic.nodemanager.server.LogFormatter\nListenBacklog=50';
createFile(directory_name, file_name, content);

To enroll the node manager we can use

import socket;
admin_server_listen_address = socket.gethostname();
admin_server_url = 't3://' + admin_server_listen_address + ':' + admin_server_listen_port;

print 'START ADMIN SERVER';
startServer(admin_server_name, domain_name, admin_server_url, admin_username, admin_password, domain_home);

print 'CONNECT TO ADMIN SERVER';
connect(admin_username, admin_password, admin_server_url);

print 'ENROLL NODE MANAGER AND CREATE NODEMANAGER.DOMAINS';
nmEnroll(domain_home,node_manager_home);

print 'SHUTDOWN ADMIN SERVER';
shutdown(admin_server_name,'Server','true',1000,'true');

Now, we can use the start and stop scripts presented in the post WLST Starting and Stopping a WebLogic Environment, in order to test the set-up, i.e., start the AdminServer by using the Node Manager.

To set-up our deployment environment (cluster, machines, managed servers, data source, and JMS) we can use something like

import socket;

cluster_name='cluster';
machine_listen_addresses=['middleware-magic.com'];
machine_user_id='weblogic';
machine_group_id='weblogic';
number_of_managed_servers_per_machine=2;
managed_server_listen_port_start=9001;
jvm_parameters='-jrockit -Xms1024m -Xmx1024m -Xgc:throughput';

sub_deployment_name='SubDeployment';
connection_factory_name='ConnectionFactory';
connection_factory_jndi_name='jms/ConnectionFactory';
distributed_queue_name='DistributedQueue';
distributed_queue_jndi_name='jms/CompanyQueue';

data_source_name='DataSource';
data_source_jndi_name='jdbc/exampleDS';
data_source_url='jdbc:oracle:thin:@192.168.1.60:1521:orcl11';
data_source_driver='oracle.jdbc.OracleDriver';
data_source_user='example';
data_source_password='example';
data_source_test='SQL SELECT 1 FROM DUAL';

def connect_to_admin_server():
	print 'CONNECT TO ADMIN SERVER';
	admin_server_listen_address = socket.gethostname();
	admin_server_url = 't3://' + admin_server_listen_address + ':' + admin_server_listen_port;
	connect(admin_username, admin_password, admin_server_url);

def create_cluster():
	print 'CREATE CLUSTER';
	cluster = cmo.createCluster(cluster_name);
	cluster.setClusterMessagingMode('unicast');
	return cluster;

def create_machines_and_servers(cluster):
	print 'CREATE MACHINES AND SERVERS';
	for i in range(len(machine_listen_addresses)):
		machine = cmo.createUnixMachine('machine_' + machine_listen_addresses[i]);
		machine.setPostBindUIDEnabled(java.lang.Boolean('true'));
		machine.setPostBindUID(machine_user_id);
		machine.setPostBindGIDEnabled(java.lang.Boolean('true'));
		machine.setPostBindGID(machine_group_id);
		machine.getNodeManager().setListenAddress(machine_listen_addresses[i]);
		machine.getNodeManager().setNMType(node_manager_mode);
		for j in range(number_of_managed_servers_per_machine):
			managed_server_listen_port = managed_server_listen_port_start + j;
			managed_server_server_name = 'server_' + machine_listen_addresses[i] + '_' + repr(managed_server_listen_port);
			server = cmo.createServer(managed_server_server_name);
			server.setListenPort(managed_server_listen_port);
			server.setListenAddress(machine_listen_addresses[i]);
			server.getServerStart().setJavaHome(jvm_directory);
			server.getServerStart().setJavaVendor(jvm_vendor);
			server.getServerStart().setArguments(jvm_parameters);
			server.setCluster(cluster);
			server.setMachine(machine);	

def create_messaging_resources(targets):
	print 'CREATE JMS SYSTEM MODULE';
	module = cmo.createJMSSystemResource('SystemModule');
	module_targets = module.getTargets();
	module_targets.append(targets);
	module.setTargets(module_targets);
	module.createSubDeployment('SubDeployment');
	resource = module.getJMSResource();

	print 'CREATE CONNECTION FACTORY';
	resource.createConnectionFactory(connection_factory_name);
	connection_factory = resource.lookupConnectionFactory(connection_factory_name);
	connection_factory.setJNDIName(connection_factory_jndi_name);
	connection_factory.setDefaultTargetingEnabled(true);
	connection_factory.getTransactionParams().setTransactionTimeout(3600);
	connection_factory.getTransactionParams().setXAConnectionFactoryEnabled(true);

	print 'CREATE UNIFORM DISTRIBUTED QUEUE';
	resource.createUniformDistributedQueue(distributed_queue_name);
	distributed_queue = resource.lookupUniformDistributedQueue(distributed_queue_name);
	distributed_queue.setJNDIName(distributed_queue_jndi_name);
	distributed_queue.setLoadBalancingPolicy('Round-Robin');
	distributed_queue.setSubDeploymentName(sub_deployment_name);

	print 'CREATE FILE STORES AND JMS SERVERS';
	servers = cmo.getServers();
	sub_deployment_targets = [];
	for server in servers:
		if (server.getName() != admin_server_name):
			file_store = cmo.createFileStore('filestore_' + server.getName());
			file_store.setDirectory(domain_application_home);
			singleton_target = file_store.getTargets();
			singleton_target.append(server);
			file_store.setTargets(singleton_target);
			jms_server = cmo.createJMSServer('jmsserver_' + server.getName());
			jms_server.setPersistentStore(file_store);
			jms_server.setTargets(singleton_target);
			sub_deployment_targets.append(ObjectName(repr(jms_server.getObjectName())));

	cd('/JMSSystemResources/SystemModule/SubDeployments/' + sub_deployment_name);
	set('Targets', jarray.array(sub_deployment_targets, ObjectName));
	cd('/');

def create_data_source(targets):
	print 'CREATE DATA SOURCE';
	data_source = cmo.createJDBCSystemResource(data_source_name);
	data_source_targets = data_source.getTargets();
	data_source_targets.append(targets);
	data_source.setTargets(data_source_targets);

	jdbc_resource = data_source.getJDBCResource();
	jdbc_resource.setName(data_source_name);

	data_source_params = jdbc_resource.getJDBCDataSourceParams();
	names = [data_source_jndi_name];
	data_source_params.setJNDINames(names);
	data_source_params.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit');

	driver_params = jdbc_resource.getJDBCDriverParams();
	driver_params.setUrl(data_source_url);
	driver_params.setDriverName(data_source_driver);
	driver_params.setPassword(data_source_password);
	driver_properties = driver_params.getProperties();
	driver_properties.createProperty('user');
	user_property = driver_properties.lookupProperty('user');
	user_property.setValue(data_source_user);

	connection_pool_params = jdbc_resource.getJDBCConnectionPoolParams();
	connection_pool_params.setTestTableName(data_source_test);
	connection_pool_params.setConnectionCreationRetryFrequencySeconds(3600);

def start_edit_mode():
	print 'START EDIT MODE';
	edit();
	startEdit();

def save_and_active_changes():
	print 'SAVE AND ACTIVATE CHANGES';
	save();
	activate(block='true');

connect_to_admin_server();

start_edit_mode();

cluster = create_cluster();

create_machines_and_servers(cluster);

save_and_active_changes();

start_edit_mode();

create_messaging_resources(cluster);

create_data_source(cluster);

save_and_active_changes();

print 'DISCONNECT FROM THE ADMIN SERVER';
disconnect();

Here, the array containing the listen addresses determines how many machines will be created. Every machine will have a number of managed servers per machine set by the number_of_managed_servers_per_machine parameter (in the example above two managed servers are created for each machine). To run the script, we can use

#!/bin/sh

SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/SetEnvironmentVariables.sh

${WEBLOGIC_HOME}/common/bin/wlst.sh -loadProperties ${SCRIPT_PATH}/environment.properties ${SCRIPT_PATH}/create_deployment_environment.py

in which environment.properties has the following contents

jvm_directory=/home/weblogic/temp/jrockit-jdk1.6.0_29
jvm_vendor=Oracle
weblogic_template=/home/weblogic/temp/weblogic12.1.1/installation/wlserver_12.1/common/templates/domains/wls.jar
domain_name=some_domain
domain_home=/home/weblogic/temp/weblogic12.1.1/configuration/domains/some_domain
domain_application_home=/home/weblogic/temp/weblogic12.1.1/configuration/applications/some_domain
node_manager_username=nodemanager
node_manager_password=magic12c
node_manager_home=/home/weblogic/temp/weblogic12.1.1/configuration/nodemanagers/some_domain
node_manager_listen_port=5556
node_manager_mode=ssl
admin_server_name=AdminServer
admin_username=weblogic
admin_password=magic12c
admin_server_listen_port=7001

When the create_deployment_environment script is run, the following output is observed

[weblogic@middleware-magic setup]$ ./CreateDeploymentEnvironmentService.sh 

CLASSPATH=/home/weblogic/temp/weblogic12.1.1/installation/patch_wls1211/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/weblogic/temp/weblogic12.1.1/installation/patch_ocp371/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/weblogic/temp/jrockit-jdk1.6.0_29/lib/tools.jar:/home/weblogic/temp/weblogic12.1.1/installation/wlserver_12.1/server/lib/weblogic_sp.jar:/home/weblogic/temp/weblogic12.1.1/installation/wlserver_12.1/server/lib/weblogic.jar:/home/weblogic/temp/weblogic12.1.1/installation/modules/features/weblogic.server.modules_12.1.1.0.jar:/home/weblogic/temp/weblogic12.1.1/installation/wlserver_12.1/server/lib/webservices.jar:/home/weblogic/temp/weblogic12.1.1/installation/modules/org.apache.ant_1.7.1/lib/ant-all.jar:/home/weblogic/temp/weblogic12.1.1/installation/modules/net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar::/home/weblogic/temp/weblogic12.1.1/installation/utils/config/10.3/config-launch.jar::/home/weblogic/temp/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbynet.jar:/home/weblogic/temp/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbyclient.jar:/home/weblogic/temp/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbytools.jar::

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

CONNECT TO ADMIN SERVER
Connecting to t3://middleware-magic.com:7001 with userid weblogic ...
Successfully connected to Admin Server 'AdminServer' that belongs to domain 'some_domain'.

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

START EDIT MODE
Location changed to edit tree. This is a writable tree with
DomainMBean as the root. To make changes you will need to start
an edit session via startEdit(). 

For more help, use help(edit)

Starting an edit session ...
Started edit session, please be sure to save and activate your
changes once you are done.
CREATE CLUSTER
CREATE MACHINES AND SERVERS
SAVE AND ACTIVATE CHANGES
Saving all your changes ...
Saved all your changes successfully.
Activating all your changes, this may take a while ...
The edit lock associated with this edit session is released
once the activation is completed.
Activation completed
START EDIT MODE
Already in Edit Tree

Starting an edit session ...
Started edit session, please be sure to save and activate your
changes once you are done.
CREATE JMS SYSTEM MODULE
CREATE CONNECTION FACTORY
CREATE UNIFORM DISTRIBUTED QUEUE
CREATE FILE STORES AND JMS SERVERS
CREATE DATA SOURCE
SAVE AND ACTIVATE CHANGES
Saving all your changes ...
Saved all your changes successfully.
Activating all your changes, this may take a while ...
The edit lock associated with this edit session is released
once the activation is completed.
Activation completed
DISCONNECT FROM THE ADMIN SERVER
Disconnected from weblogic server: AdminServer

References

[1] WebLogic Scripting Tool Command Reference.
[2] WebLogic Server MBean Reference.
[3] WebLogic Scripting Tool.


Liferay on JBoss EAP6

First things first. So what is Liferay? From the documentation summary “As you can see, it’s hard to describe, because it does so much. What we’ve essentially done is say it’s a totally awesome content and document managing, user collaborating, socially enabling, application developing, corporate integrating, completely customizable platform for building the Internet. If we’d said that up front, you’d probably have doubted us. Hopefully now, you can see that it’s true.”

What we are going to do in this post is set-up Liferay on a JBoss EAP6 cluster. We will use the JBoss set-up presented in the post Setting-up a High Available Tuned Java EE environment using JBoss EAP6.

Modify the domain.xml file

Insert a configuration element and disable the welcome root of the web subsystem’s virtual server default host by specifying enable-welcome-root="false", i.e.,

<subsystem xmlns="urn:jboss:domain:web:1.2" default-virtual-server="default-host" native="false">
	<configuration>
		<jsp-configuration development="true"/>
	</configuration>
	<!-- THE FOLLOWING IS ALREADY PRESENT -->
	<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
	<connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>
	<virtual-server name="default-host" enable-welcome-root="false">
		<alias name="localhost"/>
		<alias name="example.com"/>
	</virtual-server>
</subsystem>

Add a JAAS security domain to the security subsystem

<subsystem xmlns="urn:jboss:domain:security:1.2">
	<security-domains>
		<security-domain name="PortalRealm">
			<authentication>
			    <login-module code="com.liferay.portal.security.jaas.PortalLoginModule" flag="required"/>
			</authentication>
		</security-domain>
		<!-- THE FOLLOWING IS ALREADY PRESENT -->
		<security-domain name="other" cache-type="default">
			<authentication>
				<login-module code="Remoting" flag="optional">
					<module-option name="password-stacking" value="useFirstPass"/>
				</login-module>
				<login-module code="RealmDirect" flag="required">
					<module-option name="password-stacking" value="useFirstPass"/>
				</login-module>
			</authentication>
		</security-domain>
		<security-domain name="jboss-web-policy" cache-type="default">
			<authorization>
				<policy-module code="Delegating" flag="required"/>
			</authorization>
		</security-domain>
		<security-domain name="jboss-ejb-policy" cache-type="default">
			<authorization>
				<policy-module code="Delegating" flag="required"/>
			</authorization>
		</security-domain>
	</security-domains>
</subsystem>

Add a data source (in this case we will use the Oracle database) with JNDI name: java:/jdbc/LiferayPool

<subsystem xmlns="urn:jboss:domain:datasources:1.1">
	<datasources>
		<datasource jta="true" jndi-name="java:/jdbc/LiferayPool" pool-name="LiferayPool" enabled="true" use-java-context="true" use-ccm="true">
			<connection-url>jdbc:oracle:thin:@hostname:1521:SID</connection-url>
			<driver>oracle</driver>
			<pool>
				<min-pool-size>1</min-pool-size>
				<max-pool-size>15</max-pool-size>
				<prefill>true</prefill>
				<use-strict-min>true</use-strict-min>
			</pool>
			<security>
				<user-name>liferay</user-name>
				<password>liferay</password>
			</security>
		</datasource>
		<drivers>
			<driver name="oracle" module="com.oracle.database">
				<driver-class>oracle.jdbc.OracleDriver</driver-class>
				<xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
			</driver>
		</drivers>
	</datasources>
</subsystem>

Add a mail session with JNDI name: java:/mail/MailSession

<subsystem xmlns="urn:jboss:domain:mail:1.0">
    ...
	<mail-session jndi-name="java:/mail/MailSession" >
		<smtp-server outbound-socket-binding-ref="mail-gmail-smtp">
			<login name="username" password="password"/>
		</smtp-server>
		<pop3-server outbound-socket-binding-ref="mail-gmail-pop"/>
		<imap-server outbound-socket-binding-ref="mail-gmail-imap">
			<login name="username" password="password"/>
		</imap-server>
	</mail-session>
</subsystem>

<socket-binding-groups>
	<socket-binding-group name="cluster-sockets" default-interface="public">
		...
		<outbound-socket-binding name="mail-gmail-smtp">
			<remote-destination host="smtp.gmail.com" port="465"/>
		</outbound-socket-binding>
		<outbound-socket-binding name="mail-gmail-pop">
			<remote-destination host="pop.gmail.com" port="110"/>
		</outbound-socket-binding>
		<outbound-socket-binding name="mail-gmail-imap">
			<remote-destination host="imap.gmail.com" port="993"/>
		</outbound-socket-binding>
	</socket-binding-group>
</socket-binding-groups>

Modify the host.xml file

In the host XML set the file encoding, the user time-zone and the preferred protocol stack (note that the latter is also set in the domain.xml file)

<jvms>
	<jvm name="default">
		<heap size="512m" max-size="512m"/>
		<permgen size="256m" max-size="256m"/>
		<jvm-options>
			<option value="-server"/>
			<option value="-XX:NewRatio=2"/>
			<option value="-XX:SurvivorRatio=128"/>
			<option value="-XX:MaxTenuringThreshold=0"/>
			<option value="-XX:+UseParallelGC"/>
			<option value="-XX:MaxGCPauseMillis=200"/>
			<option value="-XX:GCTimeRatio=19"/>
			<option value="-XX:+UseParallelOldGC"/>
			<option value="-XX:+UseTLAB"/>
			<option value="-XX:LargePageSizeInBytes=2048k"/>
			<option value="-XX:+UseLargePages"/>
			<!-- The following three options are added for Liferay purposes -->
			<option value="-Dfile.encoding=UTF-8"/>
			<option value="-Duser.timezone=GMT"/>
			<option value="-Djava.net.preferIPv4Stack=true"/>
		</jvm-options>
	</jvm>
</jvms>

Directory structure that will be used for the deployment

/home/jboss
	/deploy
		/liferay
			/app
				/liferay-portal-6.1.1-ce-ga2.war (exploded war)
			/config (this will be used as the ${LIFERAY_HOME} directory)
				portal-ext.properties
			/modules
				/com/liferay/portal/main
					module.xml
					database-driver.jar (the jar file that contains the driver for the database to be used)
					portal-service.jar (included in liferay-portal-dependencies-6.1.1-ce-ga2.zip)
					portal.jar (included in liferay-portal-dependencies-6.1.1-ce-ga2.zip)
				/sun/jdk/main
					module.xml
	/eap/jboss-eap-6.0 (${JBOSS_HOME})
		/domain
			/configuration
				domain.xml
				host.xml

Note that in the case on multiple hosts the $LIFERAY_HOME} directory must be on a shared storage (as it will contain a repository). It is also handy to put the exploded war on shared storage such that multiple JBoss Server instances from different hosts can access it.

Class loading

The module.xml for the Liferay module has the following contents

<?xml version="1.0"?>
<module xmlns="urn:jboss:module:1.0" name="com.liferay.portal">
	<resources>
		<resource-root path="ojdbc6.jar"/>
		<resource-root path="portal-service.jar"/>
		<resource-root path="portlet.jar"/>
	</resources>
	<dependencies>
		<module name="javax.api"/>
		<module name="javax.mail.api"/>
		<module name="javax.servlet.api"/>
		<module name="javax.servlet.jsp.api"/>
		<module name="javax.transaction.api"/>
	</dependencies>
</module>

Note that we use ojdbc6.jar as the database driver. The jar files portal-service.jar and portlet.jar can be obtained here (the Liferay dependencies). Copy the liferay module /com/liferay/portal/main to the ${JBOSS_HOME}/modules directory.

To resolve the following class loading error

12:48:43,923 ERROR [MSC service thread 1-3][PortalInstances:375] com.liferay.portal.kernel.exception.SystemException: com.liferay.util.EncryptorException: java.lang.ClassNotFoundException: com.sun.crypto.provider.SunJCE from [Module "deployment.liferay-portal-6.1.1-ce-ga2.war:main" from Service Module Loader]
com.liferay.portal.kernel.exception.SystemException: com.liferay.util.EncryptorException: java.lang.ClassNotFoundException: com.sun.crypto.provider.SunJCE from [Module "deployment.liferay-portal-6.1.1-ce-ga2.war:main" from Service Module Loader]
	at com.liferay.portal.service.impl.CompanyLocalServiceImpl.checkCompany(CompanyLocalServiceImpl.java:203)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:122)
	at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:71)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.security.pacl.PACLAdvice.invoke(PACLAdvice.java:51)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:211)
	at sun.proxy.$Proxy44.checkCompany(Unknown Source)
	at com.liferay.portal.service.impl.CompanyLocalServiceImpl.checkCompany(CompanyLocalServiceImpl.java:157)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:122)
	at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:71)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.security.pacl.PACLAdvice.invoke(PACLAdvice.java:51)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:211)
	at sun.proxy.$Proxy44.checkCompany(Unknown Source)
	at com.liferay.portal.service.CompanyLocalServiceUtil.checkCompany(CompanyLocalServiceUtil.java:308)
	at com.liferay.portal.util.PortalInstances._initCompany(PortalInstances.java:370)
	at com.liferay.portal.util.PortalInstances.initCompany(PortalInstances.java:92)
	at com.liferay.portal.servlet.MainServlet.initCompanies(MainServlet.java:798)
	at com.liferay.portal.servlet.MainServlet.init(MainServlet.java:355)
	at javax.servlet.GenericServlet.init(GenericServlet.java:242)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1202)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1102)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3655)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:3873)
	at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:89)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:722)
Caused by: com.liferay.util.EncryptorException: java.lang.ClassNotFoundException: com.sun.crypto.provider.SunJCE from [Module "deployment.liferay-portal-6.1.1-ce-ga2.war:main" from Service Module Loader]
	at com.liferay.util.Encryptor.generateKey(Encryptor.java:201)
	at com.liferay.util.Encryptor.generateKey(Encryptor.java:185)
	at com.liferay.portal.service.impl.CompanyLocalServiceImpl.checkCompany(CompanyLocalServiceImpl.java:200)
	... 55 more
Caused by: java.lang.ClassNotFoundException: com.sun.crypto.provider.SunJCE from [Module "deployment.liferay-portal-6.1.1-ce-ga2.war:main" from Service Module Loader]
	at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
	at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
	at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
	at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
	at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:188)
	at com.liferay.util.Encryptor.getProvider(Encryptor.java:212)
	at com.liferay.util.Encryptor.generateKey(Encryptor.java:190)
	... 57 more
12:48:43,967 ERROR [MSC service thread 1-3][PortalInstances:468] com.liferay.portal.kernel.events.ActionException: com.liferay.portal.NoSuchGroupException: No Group exists with the key {companyId=0, classNameId=10021, classPK=0}
com.liferay.portal.kernel.events.ActionException: com.liferay.portal.NoSuchGroupException: No Group exists with the key {companyId=0, classNameId=10021, classPK=0}
	at com.liferay.portal.events.AddDefaultDocumentLibraryStructuresAction.run(AddDefaultDocumentLibraryStructuresAction.java:64)
	at com.liferay.portal.events.AddDefaultDataAction.run(AddDefaultDataAction.java:30)
	at com.liferay.portal.events.EventsProcessorImpl.processEvent(EventsProcessorImpl.java:106)
	at com.liferay.portal.events.EventsProcessorImpl.process(EventsProcessorImpl.java:58)
	at com.liferay.portal.events.EventsProcessorUtil.process(EventsProcessorUtil.java:53)
	at com.liferay.portal.util.PortalInstances._initCompany(PortalInstances.java:462)
	at com.liferay.portal.util.PortalInstances.initCompany(PortalInstances.java:92)
	at com.liferay.portal.servlet.MainServlet.initCompanies(MainServlet.java:798)
	at com.liferay.portal.servlet.MainServlet.init(MainServlet.java:355)
	at javax.servlet.GenericServlet.init(GenericServlet.java:242)
	at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1202)
	at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1102)
	at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:3655)
	at org.apache.catalina.core.StandardContext.start(StandardContext.java:3873)
	at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:89)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:722)
Caused by: com.liferay.portal.NoSuchGroupException: No Group exists with the key {companyId=0, classNameId=10021, classPK=0}
	at com.liferay.portal.service.persistence.GroupPersistenceImpl.findByC_C_C(GroupPersistenceImpl.java:2180)
	at com.liferay.portal.service.impl.GroupLocalServiceImpl.getCompanyGroup(GroupLocalServiceImpl.java:836)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:122)
	at com.liferay.portal.spring.transaction.TransactionInterceptor.invoke(TransactionInterceptor.java:71)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ChainableMethodAdvice.invoke(ChainableMethodAdvice.java:57)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.security.pacl.PACLAdvice.invoke(PACLAdvice.java:51)
	at com.liferay.portal.spring.aop.ServiceBeanMethodInvocation.proceed(ServiceBeanMethodInvocation.java:118)
	at com.liferay.portal.spring.aop.ServiceBeanAopProxy.invoke(ServiceBeanAopProxy.java:211)
	at sun.proxy.$Proxy52.getCompanyGroup(Unknown Source)
	at com.liferay.portal.service.GroupLocalServiceUtil.getCompanyGroup(GroupLocalServiceUtil.java:436)
	at com.liferay.portal.events.AddDefaultDocumentLibraryStructuresAction.doRun(AddDefaultDocumentLibraryStructuresAction.java:263)
	at com.liferay.portal.events.AddDefaultDocumentLibraryStructuresAction.run(AddDefaultDocumentLibraryStructuresAction.java:61)
	... 19 more

We need to edit the ${JBOSS_HOME}/modules/sun/jdk/main/module.xml file and add the following

<module xmlns="urn:jboss:module:1.1" name="sun.jdk">
	...
    <dependencies>
        <system export="true">
            <paths>
				...
				<!-- THE FOLLOWING TWO LINES NEED TO BE ADDED -->
				<path name="com/sun/crypto"/>
				<path name="com/sun/crypto/provider"/>
            </paths>
			...
        </system>
    </dependencies>
</module>

Remove eclipselink.jar from .../liferay-portal-6.1.1-ce-ga2.war/WEB-INF/lib to assure the Hibernate persistence provider is used instead of the one provided in the eclipselink.jar.

Edit ${LIFERAY_HOME}

To override the liferay.home default, create a file called portal-ext.properties in the .../liferay-portal-6.1.1-ce-ga2.war/WEB-INF/classes directory with the following contents

liferay.home=/home/jboss/deploy/liferay/config
include-and-override=/home/jboss/deploy/liferay/config/portal-ext.properties

In the ${LIFERAY_HOME} directory, also create a file called portal-ext.properties, and add the following contents

jdbc.default.jndi.name=java:jdbc/LiferayPool
mail.session.jndi.name=java:mail/MailSession
setup.wizard.enabled=false

which sets the JNDI names for the data source and the mail session to be used by Liferay.

Deployment

Deploy the Liferay distribution as an exploded war (note that the exploded war must be present on all the hosts Liferay will be running on). Deploy the application with only one server running (as it looks like Liferay is not aware that it is deployed to a cluster and initializes the database multiple times, probably better to execute the SQL by hand – the SQL scripts can be downloaded here)

12:21:06,650 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/lib/portal-impl.jar/system.properties
12:21:07,327 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/lib/portal-impl.jar/portal.properties
12:21:07,327 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/classes/portal-ext.properties
12:21:07,328 INFO  [stdout] (MSC service thread 1-1) Loading file:/home/jboss/deploy/liferay/config/portal-ext.properties
12:21:12,604 INFO  [stdout] (MSC service thread 1-1) 12:21:12,601 INFO  [MSC service thread 1-1][DialectDetector:71] Determine dialect for Oracle 11
12:21:12,654 INFO  [stdout] (MSC service thread 1-1) 12:21:12,654 INFO  [MSC service thread 1-1][DialectDetector:136] Found dialect org.hibernate.dialect.Oracle10gDialect
12:21:40,121 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-1) Initializing Mojarra 2.1.13-jbossorg-1 20121010-0442 for context ''
12:21:49,220 INFO  [stdout] (MSC service thread 1-1) Starting Liferay Portal Community Edition 6.1.1 CE GA2 (Paton / Build 6101 / July 31, 2012)
12:21:49,396 INFO  [stdout] (MSC service thread 1-1) 12:21:49,392 ERROR [MSC service thread 1-1][FileChecker:123] com.liferay.portal.kernel.exception.SystemException: com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.exception.SQLGrammarException: could not execute query
...
12:21:49,898 INFO  [stdout] (MSC service thread 1-1) 12:21:49,898 INFO  [MSC service thread 1-1][ReleaseLocalServiceImpl:84] Create tables and populate with default data
12:21:50,083 INFO  [stdout] (MSC service thread 1-1) 12:21:50,083 WARN  [MSC service thread 1-1][BaseDB:428] ORA-00955: name is already used by an existing object: create table Address (	addressId number(30,0) not null primary key,	companyId number(30,0),	userId number(30,0),	userName VARCHAR2(75 CHAR) null,	createDate timestamp null,	modifiedDate timestamp null,	classNameId number(30,0),	classPK number(30,0),	street1 VARCHAR2(75 CHAR) null,	street2 VARCHAR2(75 CHAR) null,	street3 VARCHAR2(75 CHAR) null,	city VARCHAR2(75 CHAR) null,	zip VARCHAR2(75 CHAR) null,	regionId number(30,0),	countryId number(30,0),	typeId number(30,0),	mailing number(1, 0),	primary_ number(1, 0));
...
12:22:03,198 INFO  [stdout] (MSC service thread 1-1) 12:22:03,198 INFO  [MSC service thread 1-1][BaseDB:452] Database supports case sensitive queries
12:22:04,779 INFO  [stdout] (MSC service thread 1-1) 12:22:04,777 ERROR [MSC service thread 1-1][MainServlet:217] com.liferay.portal.kernel.events.ActionException: com.liferay.portal.kernel.exception.SystemException: com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
12:22:04,780 INFO  [stdout] (MSC service thread 1-1) com.liferay.portal.kernel.events.ActionException: com.liferay.portal.kernel.exception.SystemException: com.liferay.portal.kernel.dao.orm.ORMException: org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
...
12:22:04,795 INFO  [stdout] (MSC service thread 1-1) Stopping the server due to unexpected startup errors

To deploy an exploded war by using CLI, we can use the following

[jboss@machine1 scripts]$ jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect machine1.com:9999
[domain@machine1.com:9999/] /deployment=liferay-portal-6.1.1-ce-ga2.war:add(runtime-name="liferay-portal-6.1.1-ce-ga2.war",content=[{"path"=>"/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war","archive"=>false}])
[domain@machine1.com:9999 /] /server-group=cluster-group/deployment=liferay-portal-6.1.1-ce-ga2.war:add(enabled=true)
{
    "outcome" => "success",
    "result" => undefined,
    "server-groups" => {"cluster-group" => {"host" => {"machine1" => {"cluster-server1" => {"response" => {"outcome" => "success"}}}}}}
}

When everything went alright, the following is observed in the liferay logging ($LIFERAY_HOME/logs)

13:20:03,549 INFO  [MSC service thread 1-4][DialectDetector:71] Determine dialect for Oracle 11
13:20:03,581 INFO  [MSC service thread 1-4][DialectDetector:136] Found dialect org.hibernate.dialect.Oracle10gDialect
13:20:25,972 INFO  [MSC service thread 1-4][BaseDB:452] Database supports case sensitive queries
13:20:26,385 INFO  [MSC service thread 1-4][ServerDetector:157] Server does not support hot deploy
13:20:26,392 INFO  [MSC service thread 1-4][PluginPackageUtil:1030] Reading plugin package for the root context
13:20:28,393 INFO  [MSC service thread 1-4][AutoDeployDir:106] Auto deploy scanner started for /home/jboss/deploy/liferay/config/deploy

In the JBoss Server logging the following is observed

#CLUSTER-SERVER1
13:45:06,242 INFO  [org.jboss.as.osgi] (MSC service thread 1-4) JBAS011907: Register module: Module "deployment.liferay-portal-6.1.1-ce-ga2.war:main" from Service Module Loader
13:45:06,422 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/lib/portal-impl.jar/system.properties
13:45:06,682 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/lib/portal-impl.jar/portal.properties
13:45:06,683 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/classes/portal-ext.properties
13:45:06,683 INFO  [stdout] (MSC service thread 1-1) Loading file:/home/jboss/deploy/liferay/config/portal-ext.properties
13:45:10,036 INFO  [stdout] (MSC service thread 1-1) 13:45:10,033 INFO  [MSC service thread 1-1][DialectDetector:71] Determine dialect for Oracle 11
13:45:10,052 INFO  [stdout] (MSC service thread 1-1) 13:45:10,052 INFO  [MSC service thread 1-1][DialectDetector:136] Found dialect org.hibernate.dialect.Oracle10gDialect
13:45:25,173 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-1) Initializing Mojarra 2.1.13-jbossorg-1 20121010-0442 for context ''
13:45:30,451 INFO  [stdout] (MSC service thread 1-1) Starting Liferay Portal Community Edition 6.1.1 CE GA2 (Paton / Build 6101 / July 31, 2012)
13:45:31,229 INFO  [stdout] (MSC service thread 1-1) 13:45:31,227 INFO  [MSC service thread 1-1][BaseDB:452] Database supports case sensitive queries
13:45:32,581 INFO  [stdout] (MSC service thread 1-1) 13:45:32,580 INFO  [MSC service thread 1-1][ServerDetector:157] Server does not support hot deploy
13:45:32,589 INFO  [stdout] (MSC service thread 1-1) 13:45:32,589 INFO  [MSC service thread 1-1][PluginPackageUtil:1030] Reading plugin package for the root context
13:45:34,501 INFO  [stdout] (MSC service thread 1-1) 13:45:34,501 INFO  [MSC service thread 1-1][AutoDeployDir:106] Auto deploy scanner started for /home/jboss/deploy/liferay/config/deploy
13:45:36,579 INFO  [stdout] (liferay/scheduler_dispatch-5) 13:45:36,568 INFO  [liferay/scheduler_dispatch-5][PluginPackageUtil:1292] Reloading repositories
13:45:40,023 INFO  [org.jboss.web] (MSC service thread 1-1) JBAS018210: Registering web context:
13:45:40,053 INFO  [org.jboss.as.server] (Controller Boot Thread) JBAS018559: Deployed "liferay-portal-6.1.1-ce-ga2.war"
13:45:40,054 INFO  [org.jboss.as.server] (Controller Boot Thread) JBAS018559: Deployed "SessionTest.war"
13:45:40,068 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4) started in 50099ms - Started 1331 of 1491 services (158 services are passive or on-demand)
13:56:21,743 INFO  [org.jboss.as.clustering] (Incoming-1,null) JBAS010225: New cluster view for partition web (id: 1, delta: 1, merge: false) : [machine1:cluster-server1/web, machine1:cluster-server2/web]
13:56:21,745 INFO  [org.infinispan.remoting.transport.jgroups.JGroupsTransport] (Incoming-1,null) ISPN000094: Received new cluster view: [machine1:cluster-server1/web|1] [machine1:cluster-server1/web, machine1:cluster-server2/web]

#CLUSTER-SERVER2 IS STARTED LATER
13:56:34,286 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/lib/portal-impl.jar/system.properties
13:56:34,576 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/lib/portal-impl.jar/portal.properties
13:56:34,576 INFO  [stdout] (MSC service thread 1-1) Loading vfs:/home/jboss/deploy/liferay/app/liferay-portal-6.1.1-ce-ga2.war/WEB-INF/classes/portal-ext.properties
13:56:34,576 INFO  [stdout] (MSC service thread 1-1) Loading file:/home/jboss/deploy/liferay/config/portal-ext.properties
13:56:38,156 INFO  [stdout] (MSC service thread 1-1) 13:56:38,154 INFO  [MSC service thread 1-1][DialectDetector:71] Determine dialect for Oracle 11
13:56:38,170 INFO  [stdout] (MSC service thread 1-1) 13:56:38,170 INFO  [MSC service thread 1-1][DialectDetector:136] Found dialect org.hibernate.dialect.Oracle10gDialect
13:56:53,057 INFO  [javax.enterprise.resource.webcontainer.jsf.config] (MSC service thread 1-1) Initializing Mojarra 2.1.13-jbossorg-1 20121010-0442 for context ''
13:56:58,516 INFO  [stdout] (MSC service thread 1-1) Starting Liferay Portal Community Edition 6.1.1 CE GA2 (Paton / Build 6101 / July 31, 2012)
13:57:00,450 INFO  [stdout] (MSC service thread 1-1) 13:57:00,448 INFO  [MSC service thread 1-1][BaseDB:452] Database supports case sensitive queries
13:57:01,479 INFO  [stdout] (MSC service thread 1-1) 13:57:01,478 INFO  [MSC service thread 1-1][ServerDetector:157] Server does not support hot deploy
13:57:01,484 INFO  [stdout] (MSC service thread 1-1) 13:57:01,484 INFO  [MSC service thread 1-1][PluginPackageUtil:1030] Reading plugin package for the root context
13:57:03,675 INFO  [stdout] (MSC service thread 1-1) 13:57:03,675 INFO  [MSC service thread 1-1][AutoDeployDir:106] Auto deploy scanner started for /home/jboss/deploy/liferay/config/deploy
13:57:06,091 INFO  [stdout] (liferay/scheduler_dispatch-1) 13:57:06,068 INFO  [liferay/scheduler_dispatch-1][PluginPackageUtil:1292] Reloading repositories
13:57:09,549 INFO  [org.jboss.web] (MSC service thread 1-1) JBAS018210: Registering web context:
13:57:09,573 INFO  [org.jboss.as.server] (Controller Boot Thread) JBAS018559: Deployed "liferay-portal-6.1.1-ce-ga2.war"
13:57:09,573 INFO  [org.jboss.as.server] (Controller Boot Thread) JBAS018559: Deployed "SessionTest.war"
13:57:09,622 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4) started in 54555ms - Started 1331 of 1491 services (158 services are passive or on-demand)

Load balancing

As Liferay is deployed in the context root (‘/’) we need to edit the mod-cluster-config and add the excluded-contexts attribute (the default contains the value ROOT as well)

<subsystem xmlns="urn:jboss:domain:modcluster:1.1">
	<mod-cluster-config advertise-socket="modcluster" connector="ajp" excluded-contexts="admin-console, invoker, bossws, jmx-console, juddi, web-console">
		<dynamic-load-provider>
			<load-metric type="busyness"/>
		</dynamic-load-provider>
	</mod-cluster-config>
</subsystem>

Also make sure there is no index.html in the DocumentRoot "/home/jboss/apache/htdocs" directory. By accessing http://hostname:8888/mod_cluster-manager we see the context root is picked-up

By accessing http://hostname:8888/, we see the Liferay welcome page

References

[1] Liferay User Guide.
[2] Liferay download.


Setting-up a High Available Tuned Java EE environment using JBoss EAP6

In this post we show a step-by-step example of how to set-up a high available tuned Java EE environment. We start with tuning the operating system. Next, we install the Java Virtual Machine and JBoss EAP6. We continue with configuring a domain and tune the Java Virtual Machine. Next, we show the steps involved in setting up a cluster. Subsequently, we show how to create resources needed for Java messaging and database communication. Once the resources are configured, we deploy a Spring Hibernate application that uses these resources.

Operating System Tuning

We start by adding a user under which we will install the necessary software

[root@machine1 ~]# groupadd javainstall -g 500
[root@machine1 ~]# useradd -g javainstall jboss
[root@machine1 ~]# passwd jboss
Changing password for user jboss.
New password: jbosseap6
Retype new password: jbosseap6
passwd: all authentication tokens updated successfully.

Some operating system tweaks are worth considering when we do not want to run against system restrictions:

  • Packet loss minimization – The operating system buffers must be large enough to handle incoming network traffic while the application is paused during garbage collection. Usually UDP (User Datagram Protocol) is used in order to transmit multicast messages to server instances in a cluster; to limit the need to retransmit UDP messages the size of the operating system buffers must be set appropriately to avoid excessive UDP datagram loss.
  • TCP/IP – On some systems the default value for the time wait interval is too high and needs to be adjusted. When the number approaches the maximum number of file descriptors per process, the application’s throughput will degrade, i.e., new connections have to wait for a free space in the application’s file descriptor table.
  • Swapping – Swapping, also known as paging, is the use of secondary storage to store and retrieve data for use in RAM. Swapping is automatically performed by the operating system and typically occurs when the available RAM memory is depleted. Swapping can have a significant impact on the performance and should thus be avoided.
  • Network interface card (NIC) – Configure the network card at it’s maximum link speed and at full duplex.
  • Maximum number of open file descriptors – Most operating systems handle sockets as a form of file access and use file descriptors to keep track of which sockets are open. To contain the resources per process, the operating system restricts the number of file descriptors per process. Linux limits the number of open file descriptors per process, by default this is equal to 1024. It could be that the 1024 limit does not offer optimal performance.
  • Large pages – Large pages are essentially blocks of contiguous physical memory addresses that are reserved for a process. Large pages improve performance of applications that access memory frequently. When large pages are used the application uses the translation look-aside buffer (TLB) in the processor more effectively. The TLB is a cache of recently used virtual-to-physical address space translations stored in the processor memory. To obtain data from memory, the processor looks up the TLB to find out the physical addresses (RAM or hard disk) that hold the required data. In the case of large pages, a single entry in the TLB could represent a large contiguous address space and thereby potentially reducing the TLB look-up frequency and avoiding frequent look-ups in the hierarchical page table stored in-memory.

The contents of /etc/sysctl.conf look as follows

# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled.  See sysctl(8) and
# sysctl.conf(5) for more details.

# Controls IP packet forwarding
net.ipv4.ip_forward = 0

# Controls source route verification
net.ipv4.conf.default.rp_filter = 1

# Do not accept source routing
net.ipv4.conf.default.accept_source_route = 0

# Controls the System Request debugging functionality of the kernel
kernel.sysrq = 0

# Controls whether core dumps will append the PID to the core filename.
# Useful for debugging multi-threaded applications.
kernel.core_uses_pid = 1

# Controls the use of TCP syncookies
net.ipv4.tcp_syncookies = 1

# Disable netfilter on bridges.
#net.bridge.bridge-nf-call-ip6tables = 0
#net.bridge.bridge-nf-call-iptables = 0
#net.bridge.bridge-nf-call-arptables = 0

# Controls the default maxmimum size of a mesage queue
kernel.msgmnb = 65536

# Controls the maximum size of a message, in bytes
kernel.msgmax = 65536

# Controls the maximum shared segment size, in bytes
kernel.shmmax = 68719476736

# Controls the maximum number of shared memory segments, in pages
kernel.shmall = 4294967296

# increase TCP max buffer size (depending on the type of NIC and the round-trip time these values can be changed)
# Maximum TCP Receive Window
net.core.rmem_max = 8388608
net.core.rmem_default = 8388608
# Maximum TCP Send Window
net.core.wmem_max = 8388608
net.core.wmem_default = 8388608
#  memory reserved for TCP receive buffers (vector of 3 integers: [min, default, max])
net.ipv4.tcp_rmem = 4096 87380 8388608
# memory reserved for TCP send buffers (vector of 3 integers: [min, default, max])
net.ipv4.tcp_wmem = 4096 87380 8388608

# increase the length of the processor input queue
net.core.netdev_max_backlog = 30000
# maximum amount of memory buffers (could be set equal to net.core.rmem_max and net.core.wmem_max)
net.core.optmem_max = 20480
# socket of the listen backlog
net.core.somaxconn = 1024

# tcp selective acknowledgements (disable them on high-speed networks)
net.ipv4.tcp_sack = 1
net.ipv4.tcp_dsack = 1
# Timestamps add 12 bytes to the TCP header
net.ipv4.tcp_timestamps = 1
# Support for large TCP Windows - Needs to be set to 1 if the Max TCP Window is over 65535
net.ipv4.tcp_window_scaling = 1
# The interval between the last data packet sent (simple ACKs are not considered data) and the first keepalive probe
net.ipv4.tcp_keepalive_time = 1800
# The interval between subsequential keepalive probes, regardless of what the connection has exchanged in the meantime
net.ipv4.tcp_keepalive_intvl = 30
# The number of unacknowledged probes to send before considering the connection dead and notifying the application layer
net.ipv4.tcp_keepalive_probes = 5
# The time that must elapse before TCP/IP can release a closed connection and reuse its resources.
net.ipv4.tcp_fin_timeout = 30
# Size of the backlog connections queue.
net.ipv4.tcp_max_syn_backlog=4096
# The tcp_tw_reuse setting is particularly useful in environments where numerous short connections are open and left in TIME_WAIT state, such as web servers.
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_tw_recycle=1

# The percentage of how aggressively memory pages are swapped to disk
vm.swappiness = 0
# The percentage of main memory the pdflush daemon should write data out to the disk.
vm.dirty_background_ratio=25
# The percentage of main memory the actual disk writes will take place.
vm.dirty_ratio=20

# set the number of huge pages based on the Hugepagesize, i.e., 2048kB
# when we want to reserve 1GB in huge pages we have to set the number of huge pages to:
# (1024*1024*1024*1)/(1024*1024*2) = 1073741824/2097152 = 512
vm.nr_hugepages = 512

# give permission to the group that runs the process to access the shared memory segment
# to this end open the /etc/group file and retrieve the group-id (javainstall:x:500:)
vm.hugetlb_shm_group = 500

The contents of /etc/security/limits.conf look as follows

# /etc/security/limits.conf
#
#Each line describes a limit for a user in the form:
#
#<domain>        <type>  <item>  <value>
#
#Where:
#<domain> can be:
#        - an user name
#        - a group name, with @group syntax
#        - the wildcard *, for default entry
#        - the wildcard %, can be also used with %group syntax,
#                 for maxlogin limit
#
#<type> can have the two values:
#        - "soft" for enforcing the soft limits
#        - "hard" for enforcing hard limits
#
#<item> can be one of the following:
#        - core - limits the core file size (KB)
#        - data - max data size (KB)
#        - fsize - maximum filesize (KB)
#        - memlock - max locked-in-memory address space (KB)
#        - nofile - max number of open files
#        - rss - max resident set size (KB)
#        - stack - max stack size (KB)
#        - cpu - max CPU time (MIN)
#        - nproc - max number of processes
#        - as - address space limit (KB)
#        - maxlogins - max number of logins for this user
#        - maxsyslogins - max number of logins on the system
#        - priority - the priority to run user process with
#        - locks - max number of file locks the user can hold
#        - sigpending - max number of pending signals
#        - msgqueue - max memory used by POSIX message queues (bytes)
#        - nice - max nice priority allowed to raise to values: [-20, 19]
#        - rtprio - max realtime priority
#
#<domain>      <type>  <item>         <value>
#

#*               soft    core            0
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#@student        -       maxlogins       4

# open file descriptors
@javainstall soft nofile 8192
@javainstall hard nofile 8192

# memlock - maximum locked in-memory address space (kB), we set this equal to:
# number_of_huge_pages * huge_page_size = 512 * 2048 = 1048576
@javainstall soft memlock 1048576
@javainstall hard memlock 1048576
# End of file

Configure networking

To set-up a static ip-address we can follow these steps. Edit /etc/sysconfig/network, the following gives an example

NETWORKING=yes
NETWORKING_IPV6=no
HOSTNAME=machine1.com

To have a static ip address we edit /etc/sysconfig/network-scripts/ifcfg-eth0 as follows:

DEVICE=eth0
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.1.155
NETMASK=255.255.255.0
TYPE=Ethernet
GATEWAY=192.168.1.1
IPV6INIT=no
USERCTL=no
DNS1=192.168.1.1

When one or more DNS servers are available, enter DN2, DNS3 etcetera. To see if the servers are resolved check the /etc/resolv.conf file

# Generated by NetworkManager
search com
nameserver 192.168.1.1

Note that the settings can be changed by using system-config-network. Finally, map the hostname to the IP-address. To this end, edit the /etc/hosts, for example,

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.155    machine1.com machine1

Restart the network service and check the configuration

[root@machine1 ~]# service network restart
Shutting down loopback interface:                          [  OK  ]
Bringing up loopback interface:                            [  OK  ]
Bringing up interface eth0:  Active connection state: activated
Active connection path: /org/freedesktop/NetworkManager/ActiveConnection/2
                                                           [  OK  ]
[root@machine1 ~]# ifconfig
eth1      Link encap:Ethernet  HWaddr 00:0C:29:9D:E0:3B
          inet addr:192.168.1.155  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe9d:e03b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1665 errors:0 dropped:0 overruns:0 frame:0
          TX packets:963 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1826803 (1.7 MiB)  TX bytes:72314 (70.6 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:960 (960.0 b)  TX bytes:960 (960.0 b)

Verify the static ip configuration by using, for example,

[root@machine1 ~]# ping -c 3 -M do -s 1468 192.168.1.60
PING 192.168.1.60 (192.168.1.60) 1468(1496) bytes of data.
1476 bytes from 192.168.1.60: icmp_seq=1 ttl=128 time=0.412 ms
1476 bytes from 192.168.1.60: icmp_seq=2 ttl=128 time=0.426 ms
1476 bytes from 192.168.1.60: icmp_seq=3 ttl=128 time=0.558 ms

--- 192.168.1.60 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.412/0.465/0.558/0.068 ms

Install the Java Virtual Machine

Before we start with the installation we first define our directory structure

/home/jboss
	/deploy
		/springhibernate
			/app
			/config
			/modules
	/eap/jboss-eap-6.0 (${JBOSS_HOME})
		/bin (contains scripts to run the domain controller and command-line interface)
		/domain/configuration
			domain.xml (domain configuration file)
			host.xml (host configuration file)
			mgmt-users.properties (this file contains the admin user and host users)
		/modules
			/com/oracle/database/main
			/org/springframework/main
	/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64 (${JAVA_HOME})
	/scripts (contains script to start the environment)

We are going to use openjdk. To install openjdk, we can use yum install java-1.7.0-openjdk-devel. Unfortunately, this is installed in the /usr/lib/jvm/java-1.6.0-openjdk-1.6.0.version.x86_64 directory. As we want to control the location (and update process) we are going to tar the mentioned directory, and extract it in our preferred location. When the openjdk distribution has been extracted to the preferred location, edit the bash profile (vi ~/.bash_profile) and set the JAVA_HOME and PATH variable

# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

JBOSS_HOME="/home/jboss/eap/jboss-eap-6.0"
export JBOSS_HOME

APACHE_HOME="/home/jboss/apache"
export APACHE_HOME

JAVA_HOME="/home/jboss/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64"
export JAVA_HOME

PATH=$JAVA_HOME/bin:$JBOSS_HOME/bin:$PATH:$HOME/bin
export PATH

Log out and in again to make the changes effective.

Install JBoss EAP

To install JBoss EAP run the following command java -Xms512m -Xmx512m -jar jboss-eap-6.0.1-installer.jar. This opens the graphical installer

  • Choose your language, for example, English and click ok
  • Accept the licence agreement, and click next
  • Select the installation path, for example, /home/jboss/eap and click next (click ok in the pop-up)
  • Create an admin user, for example, admin with password jbosseap6! and click next
  • We choose not to install quickstarts and click next
  • Select all the packages (default) and click next
  • Choose default as the socket binding set-up and click next
  • Choose not to start the server and click next
  • Click next on the installation summary
  • Click next twice and choose not to create shortcuts and click next
  • Generate an automatic install file and click done

The automatic install file has the following contents

<AutomatedInstallation langpack="eng">
	<com.izforge.izpack.panels.HTMLLicencePanel id="HTMLLicencePanel"/>
	<com.izforge.izpack.panels.TargetPanel id="DirectoryPanel">
		<installpath>/home/jboss/eap</installpath>
	</com.izforge.izpack.panels.TargetPanel>
	<com.izforge.izpack.panels.UserInputPanel id="Userinputpanel.0">
		<userInput>
			<entry key="adminPassword" value="4f0d0c202a4aadd1b8c25276f18be512"/>
			<entry key="adminUser" value="admin"/>
		</userInput>
	</com.izforge.izpack.panels.UserInputPanel>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.1">
		<userInput>
			<entry key="installQuickStarts" value="false"/>
		</userInput>
	</com.izforge.izpack.panels.UserInputPanel>
	<com.izforge.izpack.panels.JDKCheckPanel id="JDKCheckPanel"/>
	<com.izforge.izpack.panels.MavenRepoCheckPanel id="MavenRepoCheckPanel"/>
	<com.izforge.izpack.panels.TreePacksPanel id="TreePacksPanel">
		<pack index="0" name="eap-core" selected="true"/>
		<pack index="1" name="JBossEAP AppClient" selected="true"/>
		<pack index="2" name="JBossEAP Bin" selected="true"/>
		<pack index="3" name="JBossEAP Bundles" selected="true"/>
		<pack index="4" name="JBossEAP Docs" selected="true"/>
		<pack index="5" name="JBossEAP Domain" selected="true"/>
		<pack index="6" name="JBossAS Domain Shell Scripts" selected="true"/>
		<pack index="7" name="JBossEAP Modules" selected="true"/>
		<pack index="8" name="JBossEAP Standalone" selected="true"/>
		<pack index="9" name="JBossAS Standalone Shell Scripts" selected="true"/>
		<pack index="10" name="JBossEAP Welcome Content" selected="true"/>
		<pack index="11" name="JBossEAP Quickstarts" selected="false"/>
		<pack index="12" name="icons" selected="true"/>
		<pack index="13" name="Native Zips" selected="true"/>
		<pack index="14" name="Native RHEL6-x86_64" selected="true"/>
		<pack index="15" name="Native Utils RHEL6-x86_64" selected="true"/>
		<pack index="16" name="Native Webserver RHEL6-x86_64" selected="true"/>
	</com.izforge.izpack.panels.TreePacksPanel>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.2">
		<userInput>
			<entry key="portDecision" value="off"/>
		</userInput>
	</com.izforge.izpack.panels.UserInputPanel>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.3"/>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.4"/>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.5"/>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.6"/>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.7"/>
	<com.izforge.izpack.panels.UserInputPanel id="UserInputPanel.8">
		<userInput>
			<entry key="serverStartup" value="none"/>
		</userInput>
	</com.izforge.izpack.panels.UserInputPanel>
	<com.izforge.izpack.panels.SummaryPanel id="SummaryPanel"/>
	<com.izforge.izpack.panels.InstallPanel id="InstallPanel"/>
	<com.izforge.izpack.panels.ProcessPanel id="ProcessPanel"/>
	<com.izforge.izpack.panels.ShortcutPanel id="ShortcutPanel"/>
	<com.izforge.izpack.panels.FinishPanel id="FinishPanel"/>
</AutomatedInstallation>

To install JBoss on other machines we can use

[jboss@machine2 temp]$ java -Xms512m -Xmx512m -jar jboss-eap-6.0.1-installer.jar installscript.xml
[ Starting automated installation ]
Read pack list from xml definition.
Try to add to selection [Name: eap-core and Index: 0]
Try to add to selection [Name: JBossEAP AppClient and Index: 1]
Try to add to selection [Name: JBossEAP Bin and Index: 2]
Try to add to selection [Name: JBossEAP Bundles and Index: 3]
Try to add to selection [Name: JBossEAP Docs and Index: 4]
Try to add to selection [Name: JBossEAP Domain and Index: 5]
Try to add to selection [Name: JBossAS Domain Shell Scripts and Index: 6]
Try to add to selection [Name: JBossEAP Modules and Index: 7]
Try to add to selection [Name: JBossEAP Standalone and Index: 8]
Try to add to selection [Name: JBossAS Standalone Shell Scripts and Index: 9]
Try to add to selection [Name: JBossEAP Welcome Content and Index: 10]
Try to remove from selection [Name: JBossEAP Quickstarts and Index: 11]
Try to add to selection [Name: icons and Index: 12]
Try to add to selection [Name: Native Zips and Index: 13]
Try to add to selection [Name: Native RHEL6-x86_64 and Index: 14]
Try to add to selection [Name: Native Utils RHEL6-x86_64 and Index: 15]
Try to add to selection [Name: Native Webserver RHEL6-x86_64 and Index: 16]
Modify pack selection.
Pack [Name: JBossEAP Quickstarts and Index: 11] must be installed because it is required!
[ Starting to unpack ]
[ Processing package: eap-core (1/17) ]
[ Processing package: JBossEAP AppClient (2/17) ]
[ Processing package: JBossEAP Bin (3/17) ]
[ Processing package: JBossEAP Bundles (4/17) ]
[ Processing package: JBossEAP Docs (5/17) ]
[ Processing package: JBossEAP Domain (6/17) ]
[ Processing package: JBossAS Domain Shell Scripts (7/17) ]
[ Processing package: JBossEAP Modules (8/17) ]
[ Processing package: JBossEAP Standalone (9/17) ]
[ Processing package: JBossAS Standalone Shell Scripts (10/17) ]
[ Processing package: JBossEAP Welcome Content (11/17) ]
[ Processing package: icons (13/17) ]
[ Processing package: Native Zips (14/17) ]
[ Processing package: Native RHEL6-x86_64 (15/17) ]
[ Processing package: Native Utils RHEL6-x86_64 (16/17) ]
[ Processing package: Native Webserver RHEL6-x86_64 (17/17) ]
[ Unpacking finished ]
[ Starting processing ]
Starting process Running Password Script (1/2)
Starting process Unpacking natives (2/2)
[ Processing finished ]
[ Creating shortcuts  done. ]
[ Add shortcuts to uninstaller  done. ]
[ Writing the uninstaller data ... ]
[ Automated installation done ]

Test the installation by running domain.sh (located in ${JBOSS_HOME}/bin/).

JBoss Configuration

To configure the domain we can use the following

<domain xmlns="urn:jboss:domain:1.3">

    <extensions>
        <extension module="org.jboss.as.clustering.infinispan"/>
        <extension module="org.jboss.as.clustering.jgroups"/>
        <extension module="org.jboss.as.cmp"/>
        <extension module="org.jboss.as.configadmin"/>
        <extension module="org.jboss.as.connector"/>
        <extension module="org.jboss.as.ee"/>
        <extension module="org.jboss.as.ejb3"/>
        <extension module="org.jboss.as.jacorb"/>
        <extension module="org.jboss.as.jaxr"/>
        <extension module="org.jboss.as.jaxrs"/>
        <extension module="org.jboss.as.jdr"/>
        <extension module="org.jboss.as.jmx"/>
        <extension module="org.jboss.as.jpa"/>
        <extension module="org.jboss.as.jsr77"/>
        <extension module="org.jboss.as.logging"/>
        <extension module="org.jboss.as.mail"/>
        <extension module="org.jboss.as.messaging"/>
        <extension module="org.jboss.as.modcluster"/>
        <extension module="org.jboss.as.naming"/>
        <extension module="org.jboss.as.osgi"/>
        <extension module="org.jboss.as.pojo"/>
        <extension module="org.jboss.as.remoting"/>
        <extension module="org.jboss.as.sar"/>
        <extension module="org.jboss.as.security"/>
        <extension module="org.jboss.as.threads"/>
        <extension module="org.jboss.as.transactions"/>
        <extension module="org.jboss.as.web"/>
        <extension module="org.jboss.as.webservices"/>
        <extension module="org.jboss.as.weld"/>
    </extensions>

    <system-properties>
        <property name="java.net.preferIPv4Stack" value="true"/>
    </system-properties>

    <profiles>
        <profile name="cluster">
            <subsystem xmlns="urn:jboss:domain:logging:1.1">...</subsystem>
			...
            <subsystem xmlns="urn:jboss:domain:datasources:1.1">
                <datasources>
                    <datasource jta="true" jndi-name="java:/jdbc/OracleDS" pool-name="OracleDS" enabled="true" use-java-context="true" use-ccm="true">
                        <connection-url>jdbc:oracle:thin:@192.168.1.60:1521:orcl11</connection-url>
                        <driver>oracle</driver>
                        <pool>
                            <min-pool-size>1</min-pool-size>
                            <max-pool-size>15</max-pool-size>
                            <prefill>true</prefill>
                            <use-strict-min>true</use-strict-min>
                        </pool>
                        <security>
                            <user-name>example</user-name>
                            <password>example</password>
                        </security>
                        <timeout>
                            <idle-timeout-minutes>0</idle-timeout-minutes>
                            <query-timeout>600</query-timeout>
                        </timeout>
                        <statement>
                            <prepared-statement-cache-size>10</prepared-statement-cache-size>
                        </statement>
                    </datasource>
                    <drivers>
                        <driver name="oracle" module="com.oracle.database">
                            <driver-class>oracle.jdbc.OracleDriver</driver-class>
                            <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
                        </driver>
                    </drivers>
                </datasources>
            </subsystem>
			...
            <subsystem xmlns="urn:jboss:domain:messaging:1.2">
                <hornetq-server>
                    <persistence-enabled>true</persistence-enabled>
                    <security-enabled>false</security-enabled>
                    <create-journal-dir>true</create-journal-dir>
                    <journal-type>ASYNCIO</journal-type>
                    <journal-buffer-timeout>500000</journal-buffer-timeout>
                    <journal-buffer-size>1048576</journal-buffer-size>
                    <journal-sync-transactional>true</journal-sync-transactional>
                    <journal-sync-non-transactional>true</journal-sync-non-transactional>
                    <journal-file-size>10485760</journal-file-size>
                    <journal-min-files>2</journal-min-files>
                    <journal-compact-min-files>10</journal-compact-min-files>
                    <journal-compact-percentage>30</journal-compact-percentage>
                    <journal-max-io>1024</journal-max-io>

                    <connectors>
                        <netty-connector name="netty" socket-binding="messaging"/>
                        <netty-connector name="netty-throughput" socket-binding="messaging-throughput">
                            <param key="batch-delay" value="50"/>
                        </netty-connector>
                        <in-vm-connector name="in-vm" server-id="0"/>
                    </connectors>

                    <acceptors>
                        <netty-acceptor name="netty" socket-binding="messaging"/>
                        <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
                            <param key="batch-delay" value="50"/>
                            <param key="direct-deliver" value="false"/>
                        </netty-acceptor>
                        <in-vm-acceptor name="in-vm" server-id="0"/>
                    </acceptors>

                    <broadcast-groups>
                        <broadcast-group name="bg-group1">
                            <socket-binding>messaging-group</socket-binding>
                            <broadcast-period>5000</broadcast-period>
                            <connector-ref>
                                netty
                            </connector-ref>
                        </broadcast-group>
                    </broadcast-groups>

                    <discovery-groups>
                        <discovery-group name="dg-group1">
                            <socket-binding>messaging-group</socket-binding>
                            <refresh-timeout>10000</refresh-timeout>
                        </discovery-group>
                    </discovery-groups>

                    <cluster-connections>
                        <cluster-connection name="my-cluster">
                            <address>jms</address>
                            <connector-ref>netty</connector-ref>
                            <discovery-group-ref discovery-group-name="dg-group1"/>
                        </cluster-connection>
                    </cluster-connections>

                    <security-settings>
                        <security-setting match="#">
                            <permission type="send" roles="guest"/>
                            <permission type="consume" roles="guest"/>
                            <permission type="createNonDurableQueue" roles="guest"/>
                            <permission type="deleteNonDurableQueue" roles="guest"/>
                        </security-setting>
                    </security-settings>

                    <address-settings>
                        <address-setting match="#">
                            <dead-letter-address>jms.queue.DLQ</dead-letter-address>
                            <expiry-address>jms.queue.ExpiryQueue</expiry-address>
                            <redelivery-delay>0</redelivery-delay>
                            <max-size-bytes>10485760</max-size-bytes>
                            <address-full-policy>BLOCK</address-full-policy>
                            <message-counter-history-day-limit>10</message-counter-history-day-limit>
                            <redistribution-delay>1000</redistribution-delay>
                        </address-setting>
                        <address-setting match="jms.queue.testQueue">
                            <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
                            <expiry-address>jms.queue.expiryQueue</expiry-address>
                            <redelivery-delay>5000</redelivery-delay>
                            <max-delivery-attempts>3</max-delivery-attempts>
                            <max-size-bytes>104857600</max-size-bytes>
                            <address-full-policy>BLOCK</address-full-policy>
                            <last-value-queue>true</last-value-queue>
                            <redistribution-delay>0</redistribution-delay>
                            <send-to-dla-on-no-route>true</send-to-dla-on-no-route>
                        </address-setting>
                    </address-settings>

                    <jms-connection-factories>
                        <connection-factory name="InVmConnectionFactory">
                            <connectors>
                                <connector-ref connector-name="in-vm"/>
                            </connectors>
                            <entries>
                                <entry name="java:/ConnectionFactory"/>
                            </entries>
                        </connection-factory>
                        <connection-factory name="RemoteConnectionFactory">
                            <connectors>
                                <connector-ref connector-name="netty"/>
                            </connectors>
                            <entries>
                                <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                            </entries>
                        </connection-factory>
                        <pooled-connection-factory name="hornetq-ra">
                            <transaction mode="xa"/>
                            <connectors>
                                <connector-ref connector-name="in-vm"/>
                            </connectors>
                            <entries>
                                <entry name="java:/JmsXA"/>
                            </entries>
                        </pooled-connection-factory>
                    </jms-connection-factories>

                    <jms-destinations>
                        <jms-queue name="testQueue">
                            <entry name="java:/queue/test"/>
                            <entry name="java:jboss/exported/jms/queue/test"/>
                        </jms-queue>
                        <jms-queue name="deadLetterQueue">
                            <entry name="java:/queue/deadLetterQueue"/>
                            <entry name="java:jboss/exported/jms/queue/deadLetterQueue"/>
                            <durable>false</durable>
                        </jms-queue>
                        <jms-queue name="expiryQueue">
                            <entry name="java:/queue/expiryQueue"/>
                            <entry name="java:jboss/exported/jms/queue/expiryQueue"/>
                            <durable>false</durable>
                        </jms-queue>
                        <jms-topic name="testTopic">
                            <entry name="java:/topic/test"/>
                            <entry name="java:jboss/exported/jms/topic/test"/>
                        </jms-topic>
                    </jms-destinations>
                </hornetq-server>
            </subsystem>
			...
            <subsystem xmlns="urn:jboss:domain:weld:1.0"/>
        </profile>
    </profiles>

    <interfaces>
        <interface name="management"/>
        <interface name="public"/>
        <interface name="unsecure"/>
    </interfaces>

    <socket-binding-groups>
        <socket-binding-group name="cluster-sockets" default-interface="public">
            <socket-binding name="ajp" port="8009"/>
            <socket-binding name="http" port="8080"/>
            <socket-binding name="https" port="8443"/>
            <socket-binding name="jacorb" interface="unsecure" port="3528"/>
            <socket-binding name="jacorb-ssl" interface="unsecure" port="3529"/>
            <socket-binding name="jgroups-mping" port="0" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45700"/>
            <socket-binding name="jgroups-tcp" port="7600"/>
            <socket-binding name="jgroups-tcp-fd" port="57600"/>
            <socket-binding name="jgroups-udp" port="55200" multicast-address="${jboss.default.multicast.address:230.0.0.4}" multicast-port="45688"/>
            <socket-binding name="jgroups-udp-fd" port="54200"/>
            <socket-binding name="messaging" port="5445"/>
            <socket-binding name="messaging-group" port="0" multicast-address="${jboss.messaging.group.address:231.7.7.7}" multicast-port="${jboss.messaging.group.port:9876}"/>
            <socket-binding name="messaging-throughput" port="5455"/>
            <socket-binding name="modcluster" port="0" multicast-address="224.0.1.105" multicast-port="23364"/>
            <socket-binding name="osgi-http" interface="management" port="8090"/>
            <socket-binding name="remoting" port="4447"/>
            <socket-binding name="txn-recovery-environment" port="4712"/>
            <socket-binding name="txn-status-manager" port="4713"/>
            <outbound-socket-binding name="mail-smtp">
                <remote-destination host="localhost" port="25"/>
            </outbound-socket-binding>
        </socket-binding-group>
    </socket-binding-groups>

    <server-groups>
        <server-group name="cluster-group" profile="cluster">
            <jvm name="default"/>
            <socket-binding-group ref="cluster-sockets"/>
        </server-group>
    </server-groups>

</domain>

In the example above, we have configured one profile (cluster), and a socket-binding-group. Finally, we have defined a server-group, that uses the profile and socket-binding-group. Note that the configuration above is default except for the messaging and the data-source. When using the Linux firewall (disabled in our case), we must configure the iptables appropriately. The servers that belong to the server-group, will be defined in the host configuration below.

Host Configuration

First, we create two management users called machine1 and machine2. To this end run the add-user.sh script located in the ${JBOSS_HOME}/bin directory. Next, we create host.xml files for each host, i.e., on machine1 we have

<host name="machine1" xmlns="urn:jboss:domain:1.3">

    <management>
        <security-realms>
            <security-realm name="ManagementRealm">
				<!-- Needs to be added to hosts that are not the domain controller -->
				<!--server-identities>
					<secret value="amJvc3NlYXA2IQ==" />
				</server-identities-->
                <authentication>
                    <local default-user="$local" />
                    <properties path="mgmt-users.properties" relative-to="jboss.domain.config.dir"/>
                </authentication>
            </security-realm>
            <security-realm name="ApplicationRealm">
                <authentication>
                    <local default-user="$local" allowed-users="*" />
                    <properties path="application-users.properties" relative-to="jboss.domain.config.dir" />
                </authentication>
                <authorization>
                    <properties path="application-roles.properties" relative-to="jboss.domain.config.dir"/>
                </authorization>
            </security-realm>
        </security-realms>
        <management-interfaces>
            <native-interface security-realm="ManagementRealm">
                <socket interface="management" port="${jboss.management.native.port:9999}"/>
            </native-interface>
            <http-interface security-realm="ManagementRealm">
                <socket interface="management" port="${jboss.management.http.port:9990}"/>
            </http-interface>
        </management-interfaces>
    </management>

    <domain-controller>
       <local/>
    </domain-controller>

    <interfaces>
        <interface name="management">
            <nic name="eth1"/>
        </interface>
        <interface name="public">
            <nic name="eth1"/>
        </interface>
        <interface name="unsecure">
            <inet-address value="127.0.0.1"/>
        </interface>
    </interfaces>

    <jvms>
    	<jvm name="default">
            <heap size="512m" max-size="512m"/>
            <permgen size="256m" max-size="256m"/>
            <jvm-options>
                <option value="-server"/>
                <option value="-XX:NewRatio=2"/>
				<option value="-XX:SurvivorRatio=128"/>
				<option value="-XX:MaxTenuringThreshold=0"/>
                <option value="-XX:+UseParallelGC"/>
                <option value="-XX:ParallelGCThreads=2"/>
                <option value="-XX:MaxGCPauseMillis=200"/>
                <option value="-XX:GCTimeRatio=19"/>
                <option value="-XX:+UseParallelOldGC"/>
                <option value="-XX:+UseTLAB"/>
                <option value="-XX:LargePageSizeInBytes=2048k"/>
                <option value="-XX:+UseLargePages"/>
            </jvm-options>
        </jvm>
    </jvms>

    <servers>
        <server name="cluster-server1" group="cluster-group" auto-start="false"/>
        <server name="cluster-server2" group="cluster-group" auto-start="false">
            <socket-bindings port-offset="1"/>
        </server>
    </servers>
</host>

Note the local for the domain controller, this means that machine1 will act as our domain controller. We have used the following JVM parameters

  • -server – select the JIT compiler.
  • -Xms – initial heap size.
  • -Xmx – maximum heap size.
  • -XX:PermSize and -XX:MaxPermSize – size of the permanent generation.
  • -XX:NewRatio=N – sets the young generation to heap size / (1 + N).
  • -XX:SurvivorRatio – ratio of eden/survivor space size.
  • -XX:MaxTenuringThreshold – sets the maximum tenuring threshold (above we assume that objects that are not collected in the eden space are objects that will live for a long time).
  • -XX:+UseParallelGC – select the parallel collector.
  • -XX:ParallelGCThreads – sets the number of garbage collector threads, i.e., the number of CPUs to be used.
  • -XX:MaxGCPauseMillis – sets the maximum pause time goal.
  • -XX:GCTimeRatio=N – sets the throughput goal that is measured in terms of the time spent doing garbage collection versus the time spent outside of garbage collection. In the case above with N=19, the garbage collection time to application time is set to 1 / (1+N) = 1 / 20, i.e., 5% of the total time is spent in garbage collection.
  • -XX:-UseParallelOldGC – selects the parallel collector for major collections.
  • -XX:+UseTLAB – enables thread-local object allocation. More information on thread local allocation can be found in the ‘Compaction and Thread Local Area’ section of the Tune the JVM that runs Coherence post.
  • -XX:LargePageSizeInBytes – sets the large page size used for the Java heap. We set this equal to the operating system parameter: Hugepagesize, which in our case is 2048kB
  • -XX:+UseLargePages – use large page memory. The steps involved on how to configure large pages in the operating system can be found in the ‘Call profiling and large pages’ section of the Tune the JVM that runs Coherence post.

On the machine2 host we use the following host.xml file

<host name="machine2" xmlns="urn:jboss:domain:1.3">

    <management>
        <security-realms>
            <security-realm name="ManagementRealm">
                <server-identities>
					<secret value="amJvc3NlYXA2IQ=="/>
                </server-identities>
                <authentication>
                    <local default-user="$local" />
                    <properties path="mgmt-users.properties" relative-to="jboss.domain.config.dir"/>
                </authentication>
            </security-realm>
            <security-realm name="ApplicationRealm">
                <authentication>
                    <local default-user="$local" allowed-users="*" />
                    <properties path="application-users.properties" relative-to="jboss.domain.config.dir" />
                </authentication>
                <authorization>
                    <properties path="application-roles.properties" relative-to="jboss.domain.config.dir"/>
                </authorization>
            </security-realm>
        </security-realms>
        <management-interfaces>
            <native-interface security-realm="ManagementRealm">
                <socket interface="management" port="${jboss.management.native.port:9999}"/>
            </native-interface>
            <http-interface security-realm="ManagementRealm">
                <socket interface="management" port="${jboss.management.http.port:9990}"/>
            </http-interface>
        </management-interfaces>
    </management>

    <domain-controller>
       <remote host="machine1.com" port="9999" security-realm="ManagementRealm"/>
    </domain-controller>

    <interfaces>
        <interface name="management">
            <nic name="eth2"/>
        </interface>
        <interface name="public">
            <nic name="eth2"/>
        </interface>
        <interface name="unsecure">
            <inet-address value="127.0.0.1"/>
        </interface>
    </interfaces>

    <jvms>
    	<jvm name="default">
            <heap size="512m" max-size="512m"/>
            <permgen size="256m" max-size="256m"/>
            <jvm-options>
                <option value="-server"/>
                <option value="-XX:NewRatio=2"/>
				<option value="-XX:SurvivorRatio=128"/>
				<option value="-XX:MaxTenuringThreshold=0"/>
                <option value="-XX:+UseParallelGC"/>
                <option value="-XX:ParallelGCThreads=2"/>
                <option value="-XX:MaxGCPauseMillis=200"/>
                <option value="-XX:GCTimeRatio=19"/>
                <option value="-XX:+UseParallelOldGC"/>
                <option value="-XX:+UseTLAB"/>
                <option value="-XX:LargePageSizeInBytes=2048k"/>
                <option value="-XX:+UseLargePages"/>
            </jvm-options>
        </jvm>
    </jvms>

    <servers>
        <server name="cluster-server3" group="cluster-group" auto-start="false"/>
        <server name="cluster-server4" group="cluster-group" auto-start="false">
            <socket-bindings port-offset="1"/>
        </server>
    </servers>
</host>

The choice of the name of the host is very important, as a corresponding user name must be present in the mgmt-users.properties file on the host where the domain controller runs. Note that we tell this host where to find the domain controller, by using the remote element.

To test the set-up, we first start the domain controller on machine1

[jboss@machine1 bin]$ ./domain.sh
=========================================================================

  JBoss Bootstrap Environment

  JBOSS_HOME: /home/jboss/eap/jboss-eap-6.0

  JAVA: /home/jboss/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/bin/java

  JAVA_OPTS: -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.domain.default.config=domain.xml -Djboss.host.default.config=host.xml

=========================================================================

10:03:24,645 INFO  [org.jboss.modules] (main) JBoss Modules version 1.1.3.GA-redhat-1
10:03:24,784 INFO  [org.jboss.as.process.Host Controller.status] (main) JBAS012017: Starting process 'Host Controller'
[Host Controller] 10:03:25,189 INFO  [org.jboss.modules] (main) JBoss Modules version 1.1.3.GA-redhat-1
[Host Controller] 10:03:25,364 INFO  [org.jboss.msc] (main) JBoss MSC version 1.0.2.GA-redhat-2
[Host Controller] 10:03:25,455 INFO  [org.jboss.as] (MSC service thread 1-2) JBAS015899: JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4) starting
[Host Controller] 10:03:25,979 INFO  [org.xnio] (MSC service thread 1-2) XNIO Version 3.0.7.GA-redhat-1
[Host Controller] 10:03:25,984 INFO  [org.xnio.nio] (MSC service thread 1-2) XNIO NIO Implementation Version 3.0.7.GA-redhat-1
[Host Controller] 10:03:25,990 INFO  [org.jboss.as] (Controller Boot Thread) JBAS010902: Creating http management service using network interface (management) port (9990) securePort (-1)
[Host Controller] 10:03:26,012 INFO  [org.jboss.remoting] (MSC service thread 1-2) JBoss Remoting version 3.2.14.GA-redhat-1
[Host Controller] 10:03:26,084 INFO  [org.jboss.as.remoting] (MSC service thread 1-1) JBAS017100: Listening on 192.168.1.155:9999
[Host Controller] 10:03:27,326 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://192.168.1.155:9990/management
[Host Controller] 10:03:27,328 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015951: Admin console listening on http://192.168.1.155:9990
[Host Controller] 10:03:27,331 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4) (Host Controller) started in 2457ms - Started 11 of 11 services (0 services are passive or on-demand)
[Host Controller] 10:04:07,114 INFO  [org.jboss.as.domain] (slave-request-threads - 1) JBAS010918: Registered remote slave host "machine2", JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4)

Next, we start the domain controller on machine2 (note the last log line above that the host has been registered)

[jboss@machine2 bin]$ ./domain.sh
=========================================================================

  JBoss Bootstrap Environment

  JBOSS_HOME: /home/jboss/eap/jboss-eap-6.0

  JAVA: /home/jboss/jvm/java-1.7.0-openjdk-1.7.0.9.x86_64/bin/java

  JAVA_OPTS: -Xms64m -Xmx512m -XX:MaxPermSize=256m -Djava.net.preferIPv4Stack=true -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.modules.system.pkgs=org.jboss.byteman -Djava.awt.headless=true -Djboss.domain.default.config=domain.xml -Djboss.host.default.config=host.xml

=========================================================================

10:03:55,491 INFO  [org.jboss.modules] (main) JBoss Modules version 1.1.3.GA-redhat-1
10:03:56,433 INFO  [org.jboss.as.process.Host Controller.status] (main) JBAS012017: Starting process 'Host Controller'
[Host Controller] 10:03:58,033 INFO  [org.jboss.modules] (main) JBoss Modules version 1.1.3.GA-redhat-1
[Host Controller] 10:03:58,431 INFO  [org.jboss.msc] (main) JBoss MSC version 1.0.2.GA-redhat-2
[Host Controller] 10:03:58,874 INFO  [org.jboss.as] (MSC service thread 1-1) JBAS015899: JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4) starting
[Host Controller] 10:04:00,638 INFO  [org.xnio] (MSC service thread 1-3) XNIO Version 3.0.7.GA-redhat-1
[Host Controller] 10:04:00,655 INFO  [org.jboss.as] (Controller Boot Thread) JBAS010902: Creating http management service using network interface (management) port (9990) securePort (-1)
[Host Controller] 10:04:00,656 INFO  [org.xnio.nio] (MSC service thread 1-3) XNIO NIO Implementation Version 3.0.7.GA-redhat-1
[Host Controller] 10:04:00,727 INFO  [org.jboss.remoting] (MSC service thread 1-3) JBoss Remoting version 3.2.14.GA-redhat-1
[Host Controller] 10:04:00,957 INFO  [org.jboss.as.remoting] (MSC service thread 1-4) JBAS017100: Listening on 192.168.1.160:9999
[Host Controller] 10:04:07,563 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015961: Http management interface listening on http://192.168.1.160:9990/management
[Host Controller] 10:04:07,565 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015954: Admin console is not enabled
[Host Controller] 10:04:07,567 INFO  [org.jboss.as] (Controller Boot Thread) JBAS015874: JBoss EAP 6.0.1.GA (AS 7.1.3.Final-redhat-4) (Host Controller) started in 10950ms - Started 11 of 11 services (0 services are passive or on-demand)

Deployment

The application to be deployed, uses Spring and Hibernate (details can be found in the Spring and Hibernate4 post). To deploy the application we are going to use a custom module, i.e.,

${JBOSS_HOME}/modules
	/org/springframework
		/main
			aopalliance-1.0.jar
			cglib-2.2.2.jar
			commons-logging-1.0.4.jar
			module.xml
			org.springframework.aop-3.1.2.RELEASE.jar
			org.springframework.asm-3.1.2.RELEASE.jar
			org.springframework.beans-3.1.2.RELEASE.jar
			org.springframework.context-3.1.2.RELEASE.jar
			org.springframework.core-3.1.2.RELEASE.jar
			org.springframework.expression-3.1.2.RELEASE.jar
			org.springframework.jdbc-3.1.2.RELEASE.jar
			org.springframework.jms-3.1.2.RELEASE.jar
			org.springframework.orm-3.1.2.RELEASE.jar
			org.springframework.transaction-3.1.2.RELEASE.jar
			org.springframework.web-3.1.2.RELEASE.jar

where module.xml has the following contents

<module xmlns="urn:jboss:module:1.1" name="org.springframework">
    <resources>
		<resource-root path="aopalliance-1.0.jar"/>
		<resource-root path="cglib-2.2.2.jar"/>
		<resource-root path="commons-logging-1.0.4.jar"/>
		<resource-root path="org.springframework.aop-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.asm-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.beans-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.context-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.core-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.expression-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.jdbc-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.jms-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.orm-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.transaction-3.1.2.RELEASE.jar"/>
		<resource-root path="org.springframework.web-3.1.2.RELEASE.jar"/>
    </resources>
    <dependencies>
        <module name="javax.api" export="true"/>
        <module name="org.apache.log4j" export="true"/>
        <module name="org.antlr" export="true"/>
        <module name="org.dom4j" export="true"/>
        <module name="org.hibernate" export="true"/>
        <module name="javax.persistence.api" export="true"/>
		<module name="javax.servlet.api" export="true"/>
        <module name="org.javassist" export="true"/>
        <module name="org.jboss.logging" export="true"/>
        <module name="javax.transaction.api" export="true"/>
    </dependencies>
</module>

Note that we also have included a Hibernate dependency (as this is needed by Spring when using Hibernate with it). Next, we are going to start the servers by using the command-line interface

[jboss@machine1 ~]$ cd eap/jboss-eap-6.0/bin/
[jboss@machine1 bin]$ ./jboss-cli.sh
You are disconnected at the moment. Type 'connect' to connect to the server or 'help' for the list of supported commands.
[disconnected /] connect machine1.com:9999
[domain@machine1.com:9999 /] /host=machine1/server-config=cluster-server1:start
{
    "outcome" => "success",
    "result" => "STARTING"
}
[domain@machine1.com:9999 /] /host=machine1/server-config=cluster-server2:start
{
    "outcome" => "success",
    "result" => "STARTING"
}
[domain@machine1.com:9999 /] /host=machine2/server-config=cluster-server3:start
{
    "outcome" => "success",
    "result" => "STARTING"
}
[domain@machine1.com:9999 /] /host=machine2/server-config=cluster-server4:start
{
    "outcome" => "success",
    "result" => "STARTING"
}
[domain@machine1.com:9999 /] deploy /home/jboss/deploy/springhibernate/SpringHibernate.war --server-groups=ccluster-group
[domain@machine1.com:9999 /]

Load balancing

We are going to use mod_cluster for the load balancing. First, we need to install the Apache HTTP server

  • Unpack the httpd-2.2.21.tar.gz file:
    • gzip -d httpd-2.2.21.tar.gz
    • tar xvf httpd-2.2.21.tar
    • cd httpd-2.2.21
  • The next step is to configure:
    • ./configure –with-mpm=worker –with-included-apr –prefix=/home/jboss/apache
  • Next, compile the various parts for the Apache HTTP Server by using:
    • make
  • To install the Apache HTTP Server we use:
    • make install
  • Open the httpd.conf (/home/jboss/apache/conf) file and adjust the following directives:
    • Listen 8888
    • ServerName machine1.com
  • To test the set-up, start the Apache HTTP Server:
    • Navigate to /home/jboss/apache/bin.
    • Run: ./apachectl -k start (To stop the Apache HTTP Server we can use: ./apachectl -k stop).
    • Open a browser en type the following URL: http://hostname:8888.

A mod_cluster distribution can be downloaded here. We will use mod_cluster 1.2.0.Final. Note that the binaries (for example, binaries linux2-x64) contain a full Apache distribution, while the dynamic libraries (for example, dynamic libraries linux2-x64) contain only the modules for mod_cluster (excluding mod_proxy.so, mod_proxy_ajp.so and mod_proxy_http.so). As we already have an Apache installed we will use the dynamic libraries distribution. To configure mod_cluster we first copy the libraries into ${APACHE_HOME}/modules, i.e.,

${APACHE_HOME}
	/conf
		httpd.conf
		jboss-workers.properties
		mod_jk.conf
		mod_cluster.conf
	/modules
		mod_advertise.so
		mod_jk.so
		mod_manager.so
		mod_proxy.so
		mod_proxy_ajp.so
		mod_proxy_http.so
		mod_proxy_cluster.so
		mod_slotmem.so

To configure mod_cluster, we create a mod_cluster configuration file, for example mod_cluster.conf. The configuration has the following contents

LoadModule proxy_module "/home/jboss/apache/modules/mod_proxy.so"
LoadModule proxy_ajp_module "/home/jboss/apache/modules/mod_proxy_ajp.so"
LoadModule proxy_http_module "/home/jboss/apache/modules/mod_proxy_http.so"
LoadModule slotmem_module "/home/jboss/apache/modules/mod_slotmem.so"
LoadModule manager_module "/home/jboss/apache/modules/mod_manager.so"
LoadModule proxy_cluster_module "/home/jboss/apache/modules/mod_proxy_cluster.so"
LoadModule advertise_module "/home/jboss/apache/modules/mod_advertise.so"

NameVirtualHost machine1.com:8888

<VirtualHost machine1.com:8888>
	EnableMCPMReceive
	ManagerBalancerName mycluster

	AllowDisplay On

	KeepAliveTimeout 60
	MaxKeepAliveRequests 0

	ServerAdvertise On
	AdvertiseGroup 224.0.1.105:23364
	AdvertiseFrequency 10

	<Directory />
		Order deny,allow
		Deny from all
	       Allow from 192.168.1.
	</Directory>

	<Location /mod_cluster-manager>
		SetHandler mod_cluster-manager
		Order deny,allow
   		Deny from all
   		Allow from 192.168.1.
	</Location>
</VirtualHost>

The used directives are explained here. Next, add the following Include directive to httpd.conf

# put it near the end of the file where all the other includes are present
# mod_cluster configuration
Include conf/mod_cluster.conf

The protocol used by mod_cluster to communicate with the servers in based on the connectors configured in domain.xml. When an AJP connector is configured it will be used, otherwise an HTTP connector will be used. While AJP is generally faster, an HTTP connector can optionally be secured via SSL.

<subsystem xmlns="urn:jboss:domain:web:1.2" default-virtual-server="default-host" native="false">
	<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
	<connector name="ajp" protocol="AJP/1.3" scheme="http" socket-binding="ajp"/>
	<virtual-server name="default-host" enable-welcome-root="true">
		<alias name="localhost"/>
		<alias name="example.com"/>
	</virtual-server>
</subsystem>

Restart the Apache HTTP Server. By accessing the URL: http://hostname:8888/mod_cluster-manager, we get an overview of the configuration.

Start and stop scripts

First, we are going to set-up ssh, such that we can execute commands from machine1 on machine2. Make sure sshd is running on machine2. To this end execute the following commands on machine2

[jboss@machine2 ~]$ su - root
Password:
[root@machine2 ~]# yum install openssh-server
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
 * base: mirror.proserve.nl
 * extras: ftp.nluug.nl
 * updates: ftp.nluug.nl
Setting up Install Process
Package openssh-server-5.3p1-84.1.el6.x86_64 already installed and latest version
Nothing to do
[root@machine2 ~]# yum install openssh-clients
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
 * base: mirror.proserve.nl
 * extras: ftp.nluug.nl
 * updates: ftp.nluug.nl
Setting up Install Process
Package openssh-clients-5.3p1-84.1.el6.x86_64 already installed and latest version
Nothing to do
[root@machine2 ~]# chkconfig sshd on
[root@machine2 ~]# service sshd start

When we want to execute commands from machine1 on machine2 without entering a password, we have to follow the steps below (these are executed on machine1)

[jboss@machine1 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/jboss/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/jboss/.ssh/id_rsa.
Your public key has been saved in /home/jboss/.ssh/id_rsa.pub.
The key fingerprint is:
03:58:ca:81:ad:0f:c6:45:2c:aa:ba:c1:d5:90:36:8b jboss@machine1.com
The key's randomart image is:
+--[ RSA 2048]----+
|   =o .          |
|  o.==           |
| o O+ .          |
|. B =  .         |
|.E = .  S        |
|o . .    .       |
|o.               |
|..               |
|..               |
+-----------------+
[jboss@machine1 ~]$ ssh jboss@machine2.com mkdir -p .ssh
jboss@machine2.com's password:
[jboss@machine1 ~]$ cat .ssh/id_rsa.pub | ssh jboss@machine2.com 'cat >> .ssh/authorized_keys'
jboss@machine2.com's password:
[jboss@machine1 ~]$ ssh jboss@machine2.com hostname
machine2.com

To start the environment we can use

#!/bin/bash

SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/jboss-functions

start_all_domain_controllers

start_all_servers

start_apache

in which jboss-functions has the following contents

# -*-Shell-script-*-
#
# jboss-functions	This file contains functions to be used by shell scripts in the JBOSS_HOME/scripts directory
#

start_apache() {
	echo "starting Apache HTTP Server"
	${APACHE_HOME}/bin/apachectl -k start
}

stop_apache() {
	echo "stopping Apache HTTP Server"
	${APACHE_HOME}/bin/apachectl -k stop
}

# Starts the domain controller only on the machine where the script is run
start_domain_controller() {
	echo "starting process controller and host controller"
	${JBOSS_HOME}/bin/domain.sh >/dev/null 2>/dev/null &
}

# Stops the domain controller and servers only on the machine where the script is run
stop_domain_controller_and_local_servers() {
	echo "stopping process controller and host controler"
	${JBOSS_HOME}/bin/jboss-cli.sh --user=machine1 --password=jbosseap6! --file=${JBOSS_HOME}/scripts/stop-domain-controller-and-local-servers.cli
}

# This function starts domain controllers on multiple machines by using ssh
start_all_domain_controllers() {
	echo "starting process controller and host controller"
	${JBOSS_HOME}/bin/domain.sh >/dev/null 2>/dev/null &
	echo "waiting a little for the host controller to finish starting"
	sleep 15
	echo "starting process controller and host controller on other machines"
	ssh jboss@machine2.com ${JBOSS_HOME}/bin/domain.sh >/dev/null 2>/dev/null &
	echo "waiting a little for the host controller to finish starting"
	sleep 15
}

# When the start_all_domain_controllers has finished, this function can be called to start all the server
# Note that only the servers defined in start-all-server.cli are started
start_all_servers() {
	echo "starting servers"
	${JBOSS_HOME}/bin/jboss-cli.sh --file=${JBOSS_HOME}/scripts/start-all-servers.cli
}

# Based on what is defined in the stop-all-domain-controllers-and-servers.cli script, domain controllers and servers are stopped
stop_all_domain_controllers_and_servers() {
	echo "stopping JBoss processes"
	${JBOSS_HOME}/bin/jboss-cli.sh --file=${JBOSS_HOME}/scripts/stop-all-domain-controllers-and-servers.cli
}

The start-servers.cli script has the following contents

connect machine1.com:9999
/host=machine1/server-config=cluster-server1:start
/host=machine1/server-config=cluster-server2:start
/host=machine2/server-config=cluster-server3:start
/host=machine2/server-config=cluster-server4:start

When the script is executed the following is observed

[jboss@machine1 scripts]$ ./start-environment.sh
starting process controller and host controller
waiting a little for the host controller to finish starting
starting process controller and host controller on other machines
waiting a little for the host controller to finish starting
starting servers
{
    "outcome" => "success",
    "result" => "STARTING"
}
{
    "outcome" => "success",
    "result" => "STARTING"
}
{
    "outcome" => "success",
    "result" => "STARTING"
}
{
    "outcome" => "success",
    "result" => "STARTING"
}
starting Apache HTTP Server

To stop the environment, we can use

#!/bin/bash

SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/jboss-functions

stop_apache

stop_all_domain_controllers_and_servers

in which stop-servers.cli has the following contents

connect machine1.com:9999
/host=machine1/server-config=cluster-server1:stop
/host=machine1/server-config=cluster-server2:stop
/host=machine2/server-config=cluster-server3:stop
/host=machine2/server-config=cluster-server4:stop
/host=machine2:shutdown
/host=machine1:shutdown

When the script is run the following is observed

[jboss@machine1 scripts]$ ./stop-environment.sh
stopping Apache HTTP Server
stopping JBoss processes
{
    "outcome" => "success",
    "result" => "STOPPING"
}
{
    "outcome" => "success",
    "result" => "STOPPING"
}
{
    "outcome" => "success",
    "result" => "STOPPING"
}
{
    "outcome" => "success",
    "result" => "STOPPING"
}
{
    "outcome" => "success",
    "result" => undefined
}
{"outcome" => "success"}

In general, it is recommended to start the domain controller when the machine boots. In this case, we need to know where to put our custom commands that will be called when the system boots. Note that Linux has a /etc/rc.d/rc.local file, that can be used to put custom commands in. Let us do it in the recommended script-based way. Note that Unix-based systems specify so-called run levels, and that for each run level, scripts can be defined that start a certain service. These scripts are located in the /etc/rc.d/init.d directory. This allows for services to be started when the system boots or to be stopped on system shutdown. The different run levels are specified by a specific directory in the /etc/rc.d directory, i.e.,

  • rc0.d – contains scripts that are executed on system shutdown.
  • rc1.d – contains scripts for single-user mode.
  • rc2.d – contains scripts for multi-user mode.
  • rc3.d – contains scripts for multi-user mode and networking.
  • rc4.d – not used.
  • rc5.d – same as rc3.d plus some graphical stuff.
  • rc6.d – contains scripts that are executed on system reboot.

The boot sequence is as follows: in the /etc/inittab file the starting runlevel is defined, the script /etc/rc.d/rc.sysinit is called and /etc/rc.d/rc is run. The rc script looks in the /etc/rc.d/rc<start-runlevel>.d to execute the K**<script-name> scripts with the stop option. After this the S**<script-name> scripts are executed with the start option. Note that scripts are started in numerical order, i.e., the S10network script is executed before the S80sendmail script.

To create a domain controller ‘service’, we can use the following script

#!/bin/sh
#
# chkconfig: 235 91 35
# description: starts and stops the jboss domain controller
#
#
. /etc/rc.d/init.d/functions

RETVAL=0
SERVICE="jboss-domain-controller"

start() {
	echo "Starting JBoss Domain Controller"
	su - jboss -c "/home/jboss/scripts/start-domain-controller.sh" >/dev/null 2>&1
	RETVAL=$?
	[ $RETVAL -eq 0 ] && success || failure
	echo
	[ $RETVAL -eq 0 ] && touch /var/lock/subsys/${SERVICE}
	return $RETVAL
} 

stop() {
	echo "Stopping JBoss Domain Controller and Local JBoss Server Instances"
	su - jboss -c "/home/jboss/scripts/stop-domain-controller-and-local-servers.sh" >/dev/null 2>&1
	RETVAL=$?
	[ $RETVAL -eq 0 ] && success || failure
	echo
	[ $RETVAL -eq 0 ] && rm -r /var/lock/subsys/${SERVICE}
	return $RETVAL
} 

restart() {
	stop
	start
} 

case "$1" in
	start)
		start
		;;
	stop)
		stop
		;;
	restart)
		restart
		;;
	*)
		echo $"Usage: $0 {start|stop|restart}"
		exit 1
esac 

exit $?

Place this script in the /etc/rc.d/init.d directory. By using the chkconfig command we can update the runlevel information for system services, for example, chkconfig --add jbossdomaincontroller. To test the set-up shut the system down and start it again. To check if the domain controller is running we can use ps -ef|grep java.

Next, we can start the configured servers, for example, by using

connect machine1.com:9999
/host=machine1/server-config=cluster-server1:start
/host=machine1/server-config=cluster-server2:start
/host=machine2/server-config=cluster-server3:start
/host=machine2/server-config=cluster-server4:start

To shutdown the environment we create host specific cli file, i.e., on machine1 we have

connect machine1.com:9999
/host=machine1/server-config=cluster-server1:stop
/host=machine1/server-config=cluster-server2:stop
/host=machine1:shutdown

and on machine2 we have

connect machine1.com:9999
/host=machine2/server-config=cluster-server3:stop
/host=machine2/server-config=cluster-server4:stop
/host=machine2:shutdown

The last set-up with the domain controllers starting when the servers boot, is the preferred way (as we can now bring down a specific host, start JBoss servers instances in a more controlled manner and we do not need ssh).

References

[1] Install Guide.
[2] Administration and Configuration Guide.
[3] JBoss Enterprise Application Platform Documentation.


ActiveCache and Coherence*Web

Coherence*Web is an HTTP session management module dedicated to managing session state in clustered environments. Built on top of Coherence, Coherence*Web: brings Coherence data grid’s data scalability, availability, reliability, and performance to in-memory session management and storage; allows storage of session data outside of the Java EE application server, freeing application server heap space and enabling server restarts without session data loss; enables session sharing and management across different Web applications, domains and application servers. More information can be found in the post Setting-up a WebLogic Cluster that uses Coherence.

ActiveCache is employed by applications running on WebLogic Server and provides replicated and distributed caching services that make an application’s data available to servers in a Coherence data cluster. ActiveCache provides direct access by applications to data caches, either through resource injection or component-based JNDI lookup, and lets us display, monitor, create, and configure Coherence clusters using the WebLogic Server Administration Console and WLST.

So far the commercial side of this post. Now let us first set-up an application that puts some data into the HttpSession. To this end we will use the following servlet

package userinterface.servlets;

import model.entities.Klant;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import java.util.Random;

public class TestServlet extends HttpServlet {

    private Random generator;

    @Override
    public void init() throws ServletException {
        generator = (Random)getServletContext().getAttribute("generator");
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        HttpSession session = request.getSession(false);

        // generate a random client
        Klant klant = createKlant();

        // insert a client
        session.setAttribute(klant.getKlantnummer().toString(), klant);
        if (generator.nextDouble() < 0.001) {
            // remove a client
            session.removeAttribute(generateKlantNummer().toString());
        } else {
            // find a client by ID
            session.getAttribute(generateKlantNummer().toString());
        }

        PrintWriter writer = response.getWriter();
        Enumeration<String> clientids = session.getAttributeNames();
        while (clientids.hasMoreElements()) {
            writer.println(session.getAttribute(clientids.nextElement()));
        }
        writer.flush();
        writer.close();
    }

    private Klant createKlant() {
        int klantnummer = generateKlantNummer();

        Klant klant = new Klant();
        klant.setKlantnummer(klantnummer);
        klant.setNaam("Middleware" + klantnummer);
        klant.setAdres("Magic");
        klant.setStad("Pune");
        klant.setProvincie("IN");
        klant.setPostcode("1234AB");
        klant.setGebied(1);
        klant.setTelefoonnummer("123-4567");
        klant.setReputatieNummer(1);
        klant.setKredietlimiet(Math.rint(generator.nextDouble() * 5000.0));
        klant.setCommentaar(Long.toString(Math.abs(generator.nextLong()), 36));

        return klant;
    }

    private Integer generateKlantNummer() {
        return generator.nextInt(10000);
    }
}

and the following web configuration

<web-app ...>
    <listener>
        <listener-class>userinterface.listeners.ContextListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>userinterface.servlets.TestServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>
    <security-constraint>
        <web-resource-collection>
            <web-resource-name>All</web-resource-name>
            <url-pattern>/test</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>MANAGER</role-name>
            <role-name>EMPLOYEE</role-name>
        </auth-constraint>
        <user-data-constraint>
            <transport-guarantee>NONE</transport-guarantee>
        </user-data-constraint>
    </security-constraint>
    <login-config>
        <auth-method>FORM</auth-method>
        <form-login-config>
            <form-login-page>/login.jsp</form-login-page>
            <form-error-page>/login.jsp</form-error-page>
        </form-login-config>
    </login-config>
    <security-role>
        <role-name>MANAGER</role-name>
    </security-role>
    <security-role>
        <role-name>EMPLOYEE</role-name>
    </security-role>
</web-app>

which secures the servlet URL (and enables us to set-up a session). Refer to the posts WebLogic 12c in Action and Deploy WebLogic12c to Multiple Machines for more information (and WLST scripts) on setting-up a WebLogic cluster. To deploy the application, we create the following directory structure

/testactivecache
	/app
		TestActiveCache.war
	/plan
		Plan.xml
		/WEB-INF
			weblogic.xml

Here weblogic.xml has the following contents

<weblogic-web-app ...>
	<security-role-assignment>
		<role-name>EMPLOYEE</role-name>
		<principal-name>employees</principal-name>
	</security-role-assignment>
	<security-role-assignment>
		<role-name>MANAGER</role-name>
		<principal-name>managers</principal-name>
	</security-role-assignment>
	<session-descriptor>
		<persistent-store-type>replicated_if_clustered</persistent-store-type>
	</session-descriptor>
</weblogic-web-app>

in which we map the EMPLOYEE and MANAGER roles (defined in the application) to groups (employees and managers) created in the WebLogic console. We set the persistent-store-type to replicated_if_clustered, i.e., if the Web application is deployed on a clustered server, the in-effect persistent-store-type will be replicated.

Let us test the session fail-over. We start with two servers in the cluster and issue requests as two different users. By using the cluster, monitoring environment in the WebLogic Admin console, we can see that cluster-server1 is the holder of the primary sessions and cluster-server2 holds the secundairy sessions

Next, we shutdown cluster-server1

Issue some requests (and notice that the session has failed-over to cluster-server2) and we can continue working as if nothing has happened. Bring up cluster-server1 again

Now cluster-server2 is the holder of the primary sessions and cluster-server1 holds the secundairy sessions. Note that the secundairy sessions are present after the user has issued some requests, i.e., the session is replicated when setAttribute has been called on HttpSession. In the application server logging the following is observed

# SHUTDOWN CLUSTER-SERVER1
####<Mar 7, 2013 12:59:37 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server1> <[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <weblogic> <> <94ba3ca995633592:-60f7582f:13d44ab2061:-8000-0000000000000401> <1362657577726> <BEA-000103> <Disconnecting from cluster loadtest-cluster> 

####<Mar 7, 2013 12:59:37 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server2> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657577103> <BEA-000144> <Managed Server cluster-server1 has been suspended or shut down.> 

# START CLUSTER_SERVER1
####<Mar 7, 2013 1:04:21 PM CET> <Notice> <Cluster> <middleware-magic.com> <cluster-server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657861115> <BEA-000197> <Listening for announcements from cluster using unicast cluster messaging> 

####<Mar 7, 2013 1:04:21 PM CET> <Notice> <Cluster> <middleware-magic.com> <cluster-server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657861125> <BEA-000133> <Waiting to synchronize with other running members of loadtest-cluster.> 

####<Mar 7, 2013 1:04:29 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server1> <weblogic.cluster.MessageReceiver> <<WLS Kernel>> <> <> <1362657869754> <BEA-003107> <Lost 2 unicast message(s).> 

####<Mar 7, 2013 1:04:29 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server1> <[STANDBY] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657869781> <BEA-000111> <Adding cluster-server2 with ID -5268211843454898694S:middleware-magic.com:[9002,9002,-1,-1,-1,-1,-1]:base_domain:cluster-server2 to cluster: loadtest-cluster view.> 

####<Mar 7, 2013 1:04:29 PM CET> <Notice> <Cluster> <middleware-magic.com> <cluster-server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657869787> <BEA-000142> <Trying to download cluster JNDI tree from server cluster-server2.> 

####<Mar 7, 2013 1:04:29 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server1> <[STANDBY] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657869806> <BEA-000128> <Updating -5268211843454898694S:middleware-magic.com:[9002,9002,-1,-1,-1,-1,-1]:base_domain:cluster-server2 in the cluster.> 

####<Mar 7, 2013 1:04:29 PM CET> <Notice> <Cluster> <middleware-magic.com> <cluster-server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657869936> <BEA-000164> <Synchronized cluster JNDI tree from server cluster-server2.> 

####<Mar 7, 2013 1:04:30 PM CET> <Notice> <Cluster> <middleware-magic.com> <cluster-server1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657870214> <BEA-000162> <Starting "async" replication service with remote cluster address "null">

####<Mar 7, 2013 1:04:30 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server2> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657870415> <BEA-000111> <Adding cluster-server1 with ID 7719031716195535281S:middleware-magic.com:[9001,9001,-1,-1,-1,-1,-1]:base_domain:cluster-server1 to cluster: loadtest-cluster view.> 

####<Mar 7, 2013 1:04:31 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server2> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657871227> <BEA-000128> <Updating 7719031716195535281S:middleware-magic.com:[9001,9001,-1,-1,-1,-1,-1]:base_domain:cluster-server1 in the cluster.> 

####<Mar 7, 2013 1:04:31 PM CET> <Info> <Cluster> <middleware-magic.com> <cluster-server1> <[STANDBY] ExecuteThread: '3' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1362657871758> <BEA-000128> <Updating -5268211843454898694S:middleware-magic.com:[9002,9002,-1,-1,-1,-1,-1]:base_domain:cluster-server2 in the cluster.>

Now let us configure the application such that it will use Coherence*Web to store the session information (such that the session data will be off loaded to separate JVMs and not interfere with the application). We start with configuring a Coherence Cluster by using the WebLogic Admin console. The Coherence Cluster has the following configuration

<!-- snippet from config.xml -->
<coherence-cluster-system-resource>
	<name>coherence-session-cluster</name>
    <target>loadtest-cluster</target>
    <descriptor-file-name>coherence/coherence-session-cluster/coherence-session-cluster-coherence.xml</descriptor-file-name>
</coherence-cluster-system-resource>

<!-- coherence-session-cluster-coherence.xml -->
<weblogic-coherence ...>
	<name>coherence-session-cluster</name>
	<coherence-cluster-params>
		<unicast-listen-address>localhost</unicast-listen-address>
		<unicast-listen-port>8088</unicast-listen-port>
		<unicast-port-auto-adjust>true</unicast-port-auto-adjust>
		<multicast-listen-address>231.1.1.1</multicast-listen-address>
		<multicast-listen-port>7777</multicast-listen-port>
		<coherence-cluster-well-known-addresses>
			<coherence-cluster-well-known-address>
				<name>middleware-magic</name>
				<listen-address>middleware-magic.com</listen-address>
				<listen-port>8088</listen-port>
			</coherence-cluster-well-known-address>
		</coherence-cluster-well-known-addresses>
	</coherence-cluster-params>
</weblogic-coherence>

Note that when a well-known-address has been confgured, the multicast settings are not used. Next, we need to configure a Coherence Server. The Coherence Server has the following configuration

<coherence-server>
    <name>coherence-session-server</name>
    <machine>machine1</machine>
    <coherence-cluster-system-resource>coherence-session-cluster</coherence-cluster-system-resource>
    <unicast-listen-address>localhost</unicast-listen-address>
    <unicast-listen-port>8088</unicast-listen-port>
    <unicast-port-auto-adjust>true</unicast-port-auto-adjust>
    <coherence-server-start>
		<java-vendor>Oracle</java-vendor>
		<java-home>/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0</java-home>
		<class-path>/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules.coherence.server_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence-web.jar</class-path>
		<arguments>-jrockit -Xms512m -Xmx512m -Xns128m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200ms -Dtangosol.coherence.cacheconfig=session-cache-config.xml -Dtangosol.coherence.session.localstorage=true -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true</arguments>
    </coherence-server-start>
</coherence-server>

Note the class path entries. The first is logical, the second is needed such that the Coherence Server can be started using the node manager, the third is needed as it contains the Coherence cache conifguration file (in this case session-cache-config.xml). In the JVM arguments we set the system property tangosol.coherence.cacheconfig to session-cache-config.xml. This tells Coherence which cache configuration to use. We also set the system property tangosol.coherence.session.localstorage to true, as within the cache configuration the storage is turned off

...
<distributed-scheme>
	<scheme-name>session-base</scheme-name>
	<service-name>DistributedSessions</service-name>
	<thread-count>0</thread-count>
	<lease-granularity>member</lease-granularity>
	<local-storage system-property="tangosol.coherence.session.localstorage">false</local-storage>
	<partition-count>257</partition-count>
	<backup-count>1</backup-count>
	<backup-storage>
		<type>on-heap</type>
	</backup-storage>
	<request-timeout>30s</request-timeout>
	<backing-map-scheme>
		<local-scheme>
			<scheme-ref>unlimited-local</scheme-ref>
		</local-scheme>
	</backing-map-scheme>
	<autostart>true</autostart>
</distributed-scheme>
...

Next we deploy the following shared libraries

<library>
    <name>coherence-web-spi#1.0.0.0@1.0.0.0</name>
    <target>loadtest-cluster</target>
    <module-type>war</module-type>
    <source-path>/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence-web-spi.war</source-path>
    <security-dd-model>DDOnly</security-dd-model>
</library>
<library>
    <name>coherence#3.7.1.1@3.7.1.1</name>
    <target>loadtest-cluster</target>
    <module-type xsi:nil="true"></module-type>
    <source-path>/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar</source-path>
    <security-dd-model>DDOnly</security-dd-model>
</library>
<library>
    <name>active-cache#1.0@1.0</name>
    <target>loadtest-cluster</target>
    <module-type xsi:nil="true"></module-type>
    <source-path>/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/common/deployable-libraries/active-cache-1.0.jar</source-path>
    <security-dd-model>DDOnly</security-dd-model>
    <staging-mode>nostage</staging-mode>
</library>

Note that for the ActiveCache library we have chosen nostage as the staging mode, i.e., in the WebLogic Admin console on the deployment settings page, choose the ‘I will make the deployment accessible from the following location’. The reason for this, is that the jar file only contains a MANIFEST.MF with the following class path setting

Class-Path: ../../../modules/features/weblogic.server.modules.coherence.integration_12.1.1.0.jar

The weblogic.server.modules.coherence.integration_12.1.1.0.jar file in its MANIFEST.MF refers to

Class-Path: ../com.oracle.core.coherence.integration_2.0.0.0.jar

If we would choose a staging method the references would break, and ActiveCache will not work. To let the application refer to the deployed ActiveCache and Coherence libraries, we add the following to the MANIFEST.MF file

Extension-List: ActiveCache Coherence
ActiveCache-Extension-Name: active-cache
ActiveCache-Specification-Version: 1.0
ActiveCache-Implementation-Version: 1.0
Coherence-Extension-Name: coherence
Coherence-Specification-Version: 3.7.1.1
Coherence-Implementation-Version: 3.7.1.1

We also included a tangosol-coherence-override.xml file in the WEB-INF/classes directory of the application, with the following contents

<coherence ...>
    <cluster-config>
        <member-identity>
            <cluster-name system-property="tangosol.coherence.cluster">coherence-session-cluster</cluster-name>
        </member-identity>
        <unicast-listener>
            <well-known-addresses>
                <socket-address id="1">
                    <address>middleware-magic.com</address>
                    <port>8088</port>
                </socket-address>
            </well-known-addresses>
        </unicast-listener>
    </cluster-config>
</coherence>

Here, we configure the cluster-name, such that the application will only join the cluster with name coherence-session-cluster, which we also used in the configuration of the Coherence Cluster in the WebLogic Admin console. We also have configured a well-known-address. By default, Coherence uses a multicast protocol to discover other nodes when forming a cluster. If multicast networking is undesirable, or unavailable in the environment, the Well Known Addresses feature may be used to eliminate the need for multicast traffic. When in use the cluster is configured with a relatively small list of nodes which are allowed to start the cluster, and which are likely to remain available over the cluster lifetime. There is no requirement for all WKA nodes to be simultaneously active at any point in time. This list is used by all other nodes to find their way into the cluster without the use of multicast, thus at least one node that is configured as a well-known node must be running for other nodes to be able to join.

To deploy the application we again use the following structure

/testactivecache
	/app
		TestActiveCache.war
	/plan
		Plan.xml
		/WEB-INF
			weblogic.xml

in which weblogic.xml has the following contents

<weblogic-web-app ...>
	<security-role-assignment>
		<role-name>EMPLOYEE</role-name>
		<principal-name>employees</principal-name>
	</security-role-assignment>
	<security-role-assignment>
		<role-name>MANAGER</role-name>
		<principal-name>managers</principal-name>
	</security-role-assignment>
	<library-ref>
		<library-name>coherence-web-spi</library-name>
		<specification-version>1.0.0.0</specification-version>
		<implementation-version>1.0.0.0</implementation-version>
		<exact-match>true</exact-match>
	</library-ref>
	<coherence-cluster-ref>
		<coherence-cluster-name>coherence-session-cluster</coherence-cluster-name>
	</coherence-cluster-ref>
</weblogic-web-app>

Here we refer to the Coherence*Web shared library, such that it will be merged on runtime with our application, as it contains, next to the necessary jars, an important configuration in its web.xml

<context-param>
	<param-name>coherence-web-sessions-enabled</param-name>
    <param-value>true</param-value>
</context-param>

which enables Coherence web sessions for the application. To test the set-up, deploy the application, issue some requests as different users

shutdown a server (in this case cluster-server2)

As we have turned on the MBean management in Coherence (-Dtangosol.coherence.management=all) we can use an MBean browser to see what is going on

What is fun is that it is even possible to shut down all the WebLogic servers in the cluster and still be able to retrieve the session

<Mar 7, 2013 2:08:57 PM> <INFO> <NodeManager> <Starting Coherence server with command line: /home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0/bin/java -Dtangosol.coherence.member=coherence-session-server -Dtangosol.coherence.wka=middleware-magic.com -Dtangosol.coherence.wka.port=8088 -Dtangosol.coherence.clusterport=7777 -Dtangosol.coherence.clusteraddress=231.1.1.1 -Dtangosol.coherence.localport=8088 -Dtangosol.coherence.localhost=localhost -Dtangosol.coherence.cluster=coherence-session-cluster -Djava.class.path=/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules.coherence.server_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence-web.jar -jrockit -Xms512m -Xmx512m -Xns128m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200ms -Dtangosol.coherence.cacheconfig=session-cache-config.xml -Dtangosol.coherence.session.localstorage=true -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true -Dweblogic.RootDirectory=/home/weblogic/weblogic12.1.1/configuration/domains/base_domain weblogic.nodemanager.server.provider.WeblogicCacheServer >
<Mar 7, 2013 2:08:57 PM> <INFO> <NodeManager> <Working directory is '/home/weblogic/weblogic12.1.1/configuration/domains/base_domain'>
<Mar 7, 2013 2:08:57 PM> <INFO> <NodeManager> <Server output log file is '/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers_coherence/coherence-session-server/logs/coherence-session-server.out'>
2013-03-07 14:08:58.464/1.196 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence.xml"
2013-03-07 14:08:58.489/1.221 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational overrides from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence-override-dev.xml"
2013-03-07 14:08:58.489/1.221 Oracle Coherence 3.7.1.1 <D5> (thread=Main Thread, member=n/a): Optional configuration override "/tangosol-coherence-override.xml" is not specified
2013-03-07 14:08:58.494/1.226 Oracle Coherence 3.7.1.1 <D5> (thread=Main Thread, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified

Oracle Coherence Version 3.7.1.1 Build 28901
 Grid Edition: Development mode
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

2013-03-07 14:08:59.345/2.077 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded Reporter configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/reports/report-group.xml"
2013-03-07 14:09:00.016/2.748 Oracle Coherence GE 3.7.1.1 <D4> (thread=Main Thread, member=n/a): TCMP bound to /192.168.1.150:8088 using SystemSocketProvider
2013-03-07 14:09:03.440/6.172 Oracle Coherence GE 3.7.1.1 <Info> (thread=Cluster, member=n/a): Created a new cluster "coherence-session-cluster" with Member(Id=1, Timestamp=2013-03-07 14:09:00.083, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8431,member:coherence-session-server, Role=WeblogicWeblogicCacheServer, Edition=Grid Edition, Mode=Development, CpuCount=4, SocketCount=1) UID=0xC0A801960000013D44F80E33FE391F98
2013-03-07 14:09:03.477/6.209 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Started cluster Name=coherence-session-cluster

WellKnownAddressList(Size=1,
  WKA{Address=192.168.1.150, Port=8088}
  )

MasterMemberSet(
  ThisMember=Member(Id=1, Timestamp=2013-03-07 14:09:00.083, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8431,member:coherence-session-server, Role=WeblogicWeblogicCacheServer)
  OldestMember=Member(Id=1, Timestamp=2013-03-07 14:09:00.083, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8431,member:coherence-session-server, Role=WeblogicWeblogicCacheServer)
  ActualMemberSet=MemberSet(Size=1
    Member(Id=1, Timestamp=2013-03-07 14:09:00.083, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8431,member:coherence-session-server, Role=WeblogicWeblogicCacheServer)
    )
  MemberId|ServiceVersion|ServiceJoined|MemberState
    1|3.7.1|2013-03-07 14:09:03.445|JOINED
  RecycleMillis=1200000
  RecycleSet=MemberSet(Size=0
    )
  )

TcpRing{Connections=[]}
IpMonitor{AddressListSize=0}

2013-03-07 14:09:03.596/6.328 Oracle Coherence GE 3.7.1.1 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
2013-03-07 14:09:03.682/6.414 Oracle Coherence GE 3.7.1.1 <D5> (thread=ReplicatedCache:ReplicatedSessionsMisc, member=1): Service ReplicatedSessionsMisc joined the cluster with senior service member 1
2013-03-07 14:09:03.872/6.604 Oracle Coherence GE 3.7.1.1 <D5> (thread=DistributedCache:DistributedSessions, member=1): Service DistributedSessions joined the cluster with senior service member 1
2013-03-07 14:09:03.914/6.646 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=1):
Services
  (
  ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.7.1, OldestMemberId=1}
  InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
  ReplicatedCache{Name=ReplicatedSessionsMisc, State=(SERVICE_STARTED), Id=2, Version=3.0, OldestMemberId=1}
  PartitionedCache{Name=DistributedSessions, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0}
  )

Started DefaultCacheServer...

2013-03-07 14:10:48.607/111.339 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-03-07 14:10:48.395, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8311, Role=WeblogicServer) joined Cluster with senior member 1
2013-03-07 14:10:48.856/111.589 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1
2013-03-07 14:10:48.903/111.635 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=3, Timestamp=2013-03-07 14:10:48.702, Address=192.168.1.150:8092, MachineId=65081, Location=site:,machine:middleware-magic,process:8308, Role=WeblogicServer) joined Cluster with senior member 1
2013-03-07 14:10:49.360/112.092 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 3 joined Service Management with senior member 1
2013-03-07 14:10:56.837/119.569 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 3 joined Service DistributedSessions with senior member 1
2013-03-07 14:10:56.858/119.590 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service DistributedSessions with senior member 1
# MBEAN BROWSER IS STARTED
[INFO ][mgmnt  ] Local JMX connector started
# CLUSTER-SERVER 2 IS SHUTDOWN
2013-03-07 14:23:26.704/869.436 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 3 left service Management with senior member 1
2013-03-07 14:23:26.710/869.442 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 3 left service DistributedSessions with senior member 1
2013-03-07 14:23:26.731/869.463 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=3, Timestamp=2013-03-07 14:10:48.702, Address=192.168.1.150:8092, MachineId=65081, Location=site:,machine:middleware-magic,process:8308, Role=WeblogicServer) due to a peer departure; removing the member.
2013-03-07 14:23:26.733/869.465 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=3, Timestamp=2013-03-07 14:23:26.733, Address=192.168.1.150:8092, MachineId=65081, Location=site:,machine:middleware-magic,process:8308, Role=WeblogicServer) left Cluster with senior member 1
# CLUSTER-SERVER 2 IS STARTED AGAIN
2013-03-07 14:43:17.466/2060.198 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=4, Timestamp=2013-03-07 14:43:17.261, Address=192.168.1.150:8092, MachineId=65081, Location=site:,machine:middleware-magic,process:9145, Role=WeblogicServer) joined Cluster with senior member 1
2013-03-07 14:43:17.908/2060.640 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 4 joined Service Management with senior member 1
2013-03-07 14:43:20.149/2062.881 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 4 joined Service DistributedSessions with senior member 1
# CLUSTER-SERVER 1 AND CLUSTER-SERVER 2 ARE SHUTDOWN
2013-03-07 14:46:16.667/2239.399 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 left service Management with senior member 1
2013-03-07 14:46:16.672/2239.404 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 4 left service Management with senior member 1
2013-03-07 14:46:16.680/2239.412 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 left service DistributedSessions with senior member 1
2013-03-07 14:46:16.687/2239.419 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 4 left service DistributedSessions with senior member 1
2013-03-07 14:46:16.711/2239.443 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=4, Timestamp=2013-03-07 14:43:17.261, Address=192.168.1.150:8092, MachineId=65081, Location=site:,machine:middleware-magic,process:9145, Role=WeblogicServer) due to a peer departure; removing the member.
2013-03-07 14:46:16.711/2239.443 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=4, Timestamp=2013-03-07 14:46:16.711, Address=192.168.1.150:8092, MachineId=65081, Location=site:,machine:middleware-magic,process:9145, Role=WeblogicServer) left Cluster with senior member 1
2013-03-07 14:46:16.712/2239.444 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): TcpRing connection to Member(Id=2, Timestamp=2013-03-07 14:10:48.395, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8311, Role=WeblogicServer) refused (Connection refused); removing the member.
2013-03-07 14:46:16.712/2239.444 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-03-07 14:46:16.712, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8311, Role=WeblogicServer) left Cluster with senior member 1
# CLUSTER-SERVER 1 AND CLUSTER-SERVER 2 ARE STARTED AGAIN
2013-03-07 14:48:12.673/2355.405 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=3, Timestamp=2013-03-07 14:48:12.472, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:9402, Role=WeblogicServer) joined Cluster with senior member 1
2013-03-07 14:48:13.124/2355.856 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 3 joined Service Management with senior member 1
2013-03-07 14:48:15.067/2357.799 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=5, Timestamp=2013-03-07 14:48:14.866, Address=192.168.1.150:8092, MachineId=65081, Location=site:,machine:middleware-magic,process:9411, Role=WeblogicServer) joined Cluster with senior member 1
2013-03-07 14:48:15.482/2358.214 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 5 joined Service Management with senior member 1
2013-03-07 14:48:15.594/2358.326 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 3 joined Service DistributedSessions with senior member 1
2013-03-07 14:48:17.851/2360.583 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 5 joined Service DistributedSessions with senior member 1

When cluster-server1 and cluster-server2 are up again, we can access the application with the session still available. Not very useful, as the application cannot be reached when all the servers that it runs on are down, but good to know that Coherence holds on to the data as long as the data does not expire. Very powerful stuff!

References

[1] Coherence Documentation.
[2] User’s Guide for Coherence*Web.
[3] Using ActiveCache.


WebLogic Logging Configuration

In general, it is a good idea to use log rotation to prevent having to stop a WebLogic server to remove a large log file that is filling up the file system. It is also a good idea to create a separate partition such that the root file system does not fill up. A partition is a contiguous set of blocks on a drive that are treated as if they were independent disks. The default installation of today’s Enterprise Linux distributions use flexible partitioning layouts by creating one or more logical volumes. Some of the partitions that we might want to consider separating out from root to provide more flexibility and better performance in the environment

  • /home – A file server environment would benefit from separating out /home to its own partition. This is the home directory for all users on the system, if there are no disk quotas implemented, so separating this directory should isolate a user’s runaway consumption of disk space.
  • /tmp – If we are running a high-performance computing environment, large amounts of temporary space are needed during compute time, then released upon completion.
  • /usr – This is where the kernel source tree and Linux documentation (as well as most executable binaries) are located. The /usr/local directory stores the executables that must be accessed by all users on the system and is a good location to store custom scripts developed for our environment. If it is separated to its own partition, then files will not have to be reinstalled during an upgrade or reinstall by simply choosing not to have the partition reformatted
  • /var – The /var partition is important in mail, Web, and print server environments because it contains the log files for these environments and the overall system log. Chronic messages can flood and fill this partition. If this occurs and the partition is not separate from the /, service interruptions are possible. Depending on the environment, further separation of this partition is possible by separating out /var/spool/mail for a mail server or /var/log for system logs.
  • /opt – The installation of some third-party software products, such as WebLogic Server, default to this partition. If not separate, the installation will continue under / and, if there is not enough space allocated, could fail.

To learn how to create partitions on a disk drive and how to format them for use on a Linux system as swap or data space, we can use Create partitions and filesystems and Hard disk layout.

To configure the domain logging characteristics, we can use the domain’s logging configuration tab. Set the file name to, for example, base-dir/domain-name/domain-name.log. Here, base-dir could be /var/log/weblogic/domains. Set the rotation type attribute to by time, and the limit number of retained log files checkbox to checked. Note that it is also possible to move old log files to another directory, by using the log file rotation directy property. The default rotation are: rotation time 00:00 and rotation interval 24 hours (i.e., the log file is rotated daily at midnight). In practice the domain log file does not grow very quickly.

To configure server logging, we can use the servers’ general logging tabs. The file name can be set to base-dir/domain-name/server-name/server-name.log. When you expect a log file to fill up quickly it is useful to set the rotation interval to a shorter period. By using the HTTP logging tab, we can control the HTTP access log settings. In general, the HTTP access log files grow proportionally to the number of requests, so in this case depending on the amount of traffic to set the rotation to by size instead of by time, this guarantees that do not end up with a very large log file that could fill up the available disk space. Set the rotation file size to an appropriate value, for example 5000 kilobytes. Note that HTTP access logging is enabled by default. When using web server (such as Apache), it makes sense to disable HTTP access logging on WebLogic as the web server already creates an HTTP access log.

When we use the node manager, a nodemanager.log is created in the node manager’s home directory. This file contains the warning and errors related to the node manager life cycle, for example,

<Feb 26, 2013 11:00:56 AM> <INFO> <base_domain> <cluster-server2> <Startup configuration properties loaded from "/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers/cluster-server2/data/nodemanager/startup.properties">
<Feb 26, 2013 11:00:56 AM> <INFO> <base_domain> <cluster-server1> <Startup configuration properties loaded from "/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers/cluster-server1/data/nodemanager/startup.properties">
<Feb 26, 2013 11:00:56 AM> <INFO> <base_domain> <security-server> <Startup configuration properties loaded from "/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers/security-server/data/nodemanager/startup.properties">
<Feb 26, 2013 11:00:56 AM> <INFO> <base_domain> <coherence-server1> <Startup configuration properties loaded from "/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers_coherence/coherence-server1/data/nodemanager/startup.properties">
<Feb 26, 2013 11:00:57 AM> <INFO> <Secure socket listener started on port 5556, host middleware-magic.com/192.168.1.150>
<Feb 26, 2013 11:04:27 AM> <INFO> <base_domain> <AdminServer> <Rotated server output log to "/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers/AdminServer/logs/AdminServer.out00001">
<Feb 26, 2013 11:04:27 AM> <INFO> <base_domain> <AdminServer> <Server error log also redirected to server log>
<Feb 26, 2013 11:04:27 AM> <INFO> <base_domain> <AdminServer> <Starting WebLogic server with command line: /home/weblogic/weblogic12.1.1/configuration/domains/base_domain/bin/startWebLogic.sh >
<Feb 26, 2013 11:04:27 AM> <INFO> <base_domain> <AdminServer> <Working directory is '/home/weblogic/weblogic12.1.1/configuration/domains/base_domain'>
<Feb 26, 2013 11:04:27 AM> <INFO> <base_domain> <AdminServer> <Server output log file is '/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers/AdminServer/logs/AdminServer.out'>

As shown in the example above, when using the node manager, WebLogic captures the stdout and stderr output streams and writes them to disk. Note that these files are created in the server’s log directory and are called server-name.out. The server-name.out files allows us to determine why the server failed to start if the server fails before writing to its own log file. One thing to note is that there is no way to limit the size of the server-name.out files or automatically rotate it. The reduce the size of these files we can set the standard out logging destination’s severity level to, for example, critical using the advanced area of the server’s general logging tab. When on Linux when can use logrotate.

The following are the key files for logrotate to work properly

  • /usr/bin/logrotate – the logrotate command
  • /etc/cron.daily/logrotate – shell script that executes the logrotate command daily
    	#!/bin/sh
    
    	/usr/sbin/logrotate /etc/logrotate.conf >/dev/null 2>&1
    	EXITVALUE=$?
    	if [ $EXITVALUE != 0 ]; then
    		/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
    	fi
    	exit 0
    	
  • /etc/logrotate.conf – log rotation configuration
    	# see "man logrotate" for details
    	# rotate log files weekly
    	weekly
    	# keep 4 weeks worth of backlogs
    	rotate 4
    	# create new (empty) log files after rotating old ones
    	create
    	# use date as a suffix of the rotated file
    	dateext
    	# uncomment this if you want your log files compressed
    	#compress
    	# RPM packages drop log rotation information into this directory
    	include /etc/logrotate.d
    	# no packages own wtmp and btmp -- we'll rotate them here
    	/var/log/wtmp {
    		monthly
    		create 0664 root utmp
    		minsize 1M
    		rotate 1
    	}
    
    	/var/log/btmp {
    		missingok
    		monthly
    		create 0600 root utmp
    		rotate 1
    	}	
    
    	/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers/AdminServer/logs/AdminServer.out {
    		missingok
    		nodateext
    		copytruncate
    		# create 0664 weblogic weblogic
    		rotate 10
    		size 10k
    	}
    	
  • /etc/logrotate.d – RPM packages drop log rotation information into this directory, for example, the httpd log rotation configuration (/etc/logrotate.d/httpd) looks as follows
    	/var/log/httpd/*log {
    		missingok
    		notifempty
    		sharedscripts
    		delaycompress
    		postrotate
    			/sbin/service httpd reload > /dev/null 2>/dev/null || true
    		endscript
    	}
    	

By using the /etc/logrotate.d directory we can also add a WebLogic specific file that contains all the configuration related to server-name.out files. To test the example, presented in the /etc/logrotate.conf file, start the admin server using the node manager and at a certain point execute the logrotate -v /etc/logrotate.conf command. We can see that a file named AdminServer.out.1 is created that contains

...
<Feb 22, 2013 2:25:46 PM CET> <Notice> <Log Management> <BEA-170019> <The server log file /home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers/AdminServer/logs/AdminServer.log is opened. All server side log events will be written to this file.>
<Feb 22, 2013 2:25:49 PM CET> <Notice> <Security> <BEA-090082> <Security initializing using security realm myrealm.>
<Feb 22, 2013 2:25:53 PM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to STANDBY.>
<Feb 22, 2013 2:25:53 PM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to STARTING.>

and a file AdminServer.out that contains

<Feb 22, 2013 2:25:57 PM CET> <Notice> <Log Management> <BEA-170027> <The server has successfully established a connection with the Domain level Diagnostic Service.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to ADMIN.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RESUMING.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <Server> <BEA-002613> <Channel "Default[1]" is now listening on fe80:0:0:0:20c:29ff:fe9c:771e:7001 for protocols iiop, t3, ldap, snmp, http.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <Server> <BEA-002613> <Channel "Default[2]" is now listening on 127.0.0.1:7001 for protocols iiop, t3, ldap, snmp, http.>
<Feb 22, 2013 2:25:58 PM CET> <Warning> <Server> <BEA-002611> <The hostname "localhost", maps to multiple IP addresses: 127.0.0.1, 0:0:0:0:0:0:0:1.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <Server> <BEA-002613> <Channel "Default[3]" is now listening on 0:0:0:0:0:0:0:1:7001 for protocols iiop, t3, ldap, snmp, http.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <Server> <BEA-002613> <Channel "Default" is now listening on 192.168.1.150:7001 for protocols iiop, t3, ldap, snmp, http.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <WebLogicServer> <BEA-000329> <Started the WebLogic Server Administration Server "AdminServer" for domain "base_domain" running in production mode.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RUNNING.>
<Feb 22, 2013 2:25:58 PM CET> <Notice> <WebLogicServer> <BEA-000360> <The server started in RUNNING mode.>

The reason for this test is that certain processes write to a file at whichever offset it were last, i.e., logrotate truncates the file (the size is zero), the process writes to the file again, continuing at the offset it left off. Let us demostrate this behavior by using the following example

#!/bin/sh
# coherence options
COHERENCE_OPTIONS="-Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml -Dtangosol.coherence.distributed.localstorage=false"
export COHERENCE_OPTIONS

MEASUREMENT_OPTIONS="-verbosegc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:/home/weblogic/temp/gc.out"
export MEASUREMENT_OPTIONS

JAVA_HOME="/home/weblogic/jdk1.7.0_11"
export JAVA_HOME

MEM_ARGS="-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:G1HeapRegionSize=2048k -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages"

CLASSPATH="/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar"
export CLASSPATH

# start the test
${JAVA_HOME}/bin/java ${MEM_ARGS} ${COHERENCE_OPTIONS} ${MEASUREMENT_OPTIONS} model.test.Test

In the example, we log the verbose garbage collection output of the G1 Collector. We add the following logrotate configuration to /etc/logrotate.conf

/home/weblogic/temp/gc.out {
    missingok
    nodateext
    copytruncate
    rotate 1
    size 100k
}

Let it run for a while and when the file reaches 100 kilobytes run the following command

[root@middleware-magic weblogic]# logrotate -v /etc/logrotate.conf
reading config file /etc/logrotate.conf
including /etc/logrotate.d
...
reading config info for /home/weblogic/temp/gc.out
...
rotating pattern: /home/weblogic/temp/gc.out  102400 bytes (1 rotations)
empty log files are rotated, old logs are removed
considering log /home/weblogic/temp/gc.out
  log needs rotating
rotating log /home/weblogic/temp/gc.out, log->rotateCount is 1
dateext suffix '-20130226'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
renaming /home/weblogic/temp/gc.out.1 to /home/weblogic/temp/gc.out.2 (rotatecount 1, logstart 1, i 1),
old log /home/weblogic/temp/gc.out.1 does not exist
renaming /home/weblogic/temp/gc.out.0 to /home/weblogic/temp/gc.out.1 (rotatecount 1, logstart 1, i 0),
old log /home/weblogic/temp/gc.out.0 does not exist
log /home/weblogic/temp/gc.out.2 doesn't exist -- won't try to dispose of it
copying /home/weblogic/temp/gc.out to /home/weblogic/temp/gc.out.1
set default create context
truncating /home/weblogic/temp/gc.out

To see what happens to the gc.out we can use od -c gc.out | heap -n 10

[weblogic@middleware-magic temp]$ od -c gc.out | head -n 10
0000000  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
*
0363540  \0       [   T   i   m   e   s   :       u   s   e   r   =   0
0363560   .   3   8       s   y   s   =   0   .   0   0   ,       r   e
0363600   a   l   =   0   .   3   4       s   e   c   s   ]      \n   T
0363620   o   t   a   l       t   i   m   e       f   o   r       w   h
0363640   i   c   h       a   p   p   l   i   c   a   t   i   o   n
0363660   t   h   r   e   a   d   s       w   e   r   e       s   t   o
0363700   p   p   e   d   :       0   .   3   4   0   0   1   1   0
0363720   s   e   c   o   n   d   s  \n   2   3   0   .   3   1   4   :

What this says is from offset 0 to 363540 the file consists of null bytes, and then some legible data. Getting to this state does not take the same amount of time it would take to actually write all those null-bytes. The ext{2,3,4} filesystems support so-called sparse files, so if we seek past a region of a file that does not contain anything, that region will be assumed to contain null-bytes and will not take up space on disk. Those null bytes will not actually be written, just assumed to be there. Note that when this happens the file is not useful anymore, so it is important to first test if the process can handle log rotation.

To configure the WebLogic logging by using WLST we can use something like the following

import socket;

base_dir = '/var/log/weblogic/domains';

admin_server_listen_address = socket.gethostname();
admin_server_url = 't3://' + admin_server_listen_address + ':' + admin_server_listen_port;

print 'CONNECT TO ADMIN SERVER';

connect(admin_username, admin_password, admin_server_url);

print 'CHANGE TO DOMAIN CONFIG';
domainConfig();

print 'START EDIT MODE';
edit();
startEdit();

print 'CHANGE DOMAIN AUDITING AND BACKUP SETTINGS';
cmo.setConfigurationAuditType('log');
cmo.setConfigBackupEnabled(java.lang.Boolean('true'));
cmo.setArchiveConfigurationCount(10);

print 'CHANGE DOMAIN LOG SETTINGS';
domain_name = cmo.getName();
domain_log = cmo.getLog();
domain_log.setFileName(base_dir + '/' + domain_name + '/' + domain_name + '.log');
domain_log.setRotationType('byTime');
domain_log.setFileTimeSpan(24);
domain_log.setRotationTime('00:00');
domain_log.setNumberOfFilesLimited(java.lang.Boolean('true'));
domain_log.setFileCount(10);

print 'CHANGE SERVER LOG SETTINGS';
servers = cmo.getServers();
for server in servers:
	server_name = server.getName();
	if server_name == 'AdminServer':
		server_log = server.getLog();
		server_log.setFileName(base_dir + '/' + domain_name + '/' + server_name + '/' + server_name + '.log');
		server_log.setRotationType('byTime');
		server_log.setFileTimeSpan(24);
		server_log.setRotationTime('00:00');
		server_log.setNumberOfFilesLimited(java.lang.Boolean('true'));
		server_log.setFileCount(10);
		server_log.setRedirectStderrToServerLogEnabled(java.lang.Boolean('true'));
		server_log.setRedirectStdoutToServerLogEnabled(java.lang.Boolean('true'));
		server_log.setLogFileSeverity('Warning');
		server_log.setStdoutSeverity('Warning');
		server_log.setDomainLogBroadcastSeverity('Warning');
		server_log.setMemoryBufferSeverity('Warning');
		web_server_log = server.getWebServer().getWebServerLog();
		web_server_log.setLoggingEnabled(java.lang.Boolean('false'));

print 'SAVE AND ACTIVATE CHANGES';
save();
activate(block='true');

One thing to note is that the .out files are still written to the domain-home/server/server-name/logs directory. Also by setting the -Dweblogic.Stdout and -Dweblogic.Stderr, for example,

if [ "${SERVER_NAME}" = "AdminServer" ] ; then

	if [ "${JAVA_VENDOR}" = "Sun" ] ; then
		# Memory arguments for JDK
		# USER_MEM_ARGS="-server -Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseG1GC -XX:ParallelGCThreads=2 -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:G1HeapRegionSize=2048k -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages"
		USER_MEM_ARGS="-server -Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -XX:+UseParallelOldGC"
		export USER_MEM_ARGS
	fi

	if [ "${JAVA_VENDOR}" = "Oracle" ] ; then
		# JMX_OPTIONS="-Djava.rmi.server.hostname=192.168.1.150 -Xmanagement:ssl=false,authenticate=false,port=7091,autodiscovery=true"
		# export JMX_OPTIONS

		LOGGING_OPTIONS="-Dweblogic.Stdout=/var/log/weblogic/domains/base_domain/AdminServer/AdminServer.out -Dweblogic.Stderr=/var/log/weblogic/domains/base_domain/AdminServer/AdminServer.out"
		export LOGGING_OPTIONS

		# Memory arguments for JRockit
		USER_MEM_ARGS="-jrockit -Xms512m -Xmx512m -Xns128m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200ms ${LOGGING_OPTIONS}"
		export USER_MEM_ARGS
	fi
fi

an .out is created, specified by the -Dweblogic.Stdout option, but an .out file is also created (and written to) in the domain-home/server/server-name/logs directory. Note also the documentation states: “For each server instance that it controls, Node Manager maintains a log file that contains stdout and stderr messages generated by the server instance.” This means the node manager maintains the log file and not the server itself, so setting the -Dweblogic.Stdout on a server does not help and can be left out.

References

[1] Configuring Log Files and Filtering Log Messages.


WebLogic, Coherence and the G1 Collector

With JRockit not seeing a JDK7 version, we might want to change a current WebLogic environment to use Oracle JDK. Let us use the Garbage-First (G1) Collector, which is fully supported in Oracle JDK 7 update 4 and later releases.

When using the G1 collector, the heap is partitioned into a set of equal-sized heap regions, each a contiguous range of virtual memory. Certain region sets are assigned the same roles (eden, survivor, old) as in the older collectors, but there is not a fixed size for them. This provides greater flexibility in memory usage. When performing garbage collections, G1 operates in a manner similar to the CMS collector. G1 performs a concurrent global marking phase to determine the liveness of objects throughout the heap. After the mark phase completes, G1 knows which regions are mostly empty. It collects in these regions first, which usually yields a large amount of free space. This is why this method of garbage collection is called Garbage-First. As the name suggests, G1 concentrates its collection and compaction activity on the areas of the heap that are likely to be full of reclaimable objects, that is, garbage. G1 uses a pause prediction model to meet a user-defined pause time target and selects the number of regions to collect based on the specified pause time target.

The regions identified by G1 as ripe for reclamation are garbage collected using evacuation. G1 copies objects from one or more regions of the heap to a single region on the heap, and in the process both compacts and frees up memory. This evacuation is performed in parallel on multi-processors, to decrease pause times and increase throughput. Thus, with each garbage collection, G1 continuously works to reduce fragmentation, working within the user defined pause times. This is beyond the capability of both the previous methods. CMS (Concurrent Mark Sweep ) garbage collector does not do compaction. ParallelOld garbage collection performs only whole-heap compaction, which results in considerable pause times.

It is important to note that G1 is not a real-time collector. It meets the set pause time target with high probability but not absolute certainty. Based on data from previous collections, G1 does an estimate of how many regions can be collected within the user specified target time. Thus, the collector has a reasonably accurate model of the cost of collecting the regions, and it uses this model to determine which and how many regions to collect while staying within the pause time target.

To change a WebLogic installation to use another JDK, we can adjust the setDomainEnv file as follows (i.e., add SUN_JAVA_HOME, JAVA_VENDOR and USER_MEM_ARGS), for example,

#!/bin/sh

...

WL_HOME="/home/weblogic/weblogic12.1.1/installation/wlserver_12.1"
export WL_HOME

BEA_JAVA_HOME="/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0"
export BEA_JAVA_HOME

SUN_JAVA_HOME="/home/weblogic/jdk1.7.0_11"
export SUN_JAVA_HOME

JAVA_VENDOR="Sun"
export JAVA_VENDOR

if [ "${JAVA_VENDOR}" = "Oracle" ] ; then
	JAVA_HOME="${BEA_JAVA_HOME}"
	export JAVA_HOME
else
	if [ "${JAVA_VENDOR}" = "Sun" ] ; then
		JAVA_HOME="${SUN_JAVA_HOME}"
		export JAVA_HOME
	else
		JAVA_VENDOR="Oracle"
		export JAVA_VENDOR
		JAVA_HOME="/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0"
		export JAVA_HOME
	fi
fi

...

if [ "${SERVER_NAME}" = "" ] ; then
	SERVER_NAME="AdminServer"
	export SERVER_NAME
fi

if [ "${SERVER_NAME}" = "AdminServer" ] ; then
	if [ "${JAVA_VENDOR}" = "Sun" ] ; then
		# Memory arguments for JDK
		USER_MEM_ARGS="-server -Xms512m -Xmx512m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:G1HeapRegionSize=2048k -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages"
		export USER_MEM_ARGS
	fi

	if [ "${JAVA_VENDOR}" = "Oracle" ] ; then
		# JMX configuration for JRockit
		JMX_OPTIONS="-Djava.rmi.server.hostname=192.168.1.150 -Xmanagement:ssl=false,authenticate=false,port=7091,autodiscovery=true"
		export JMX_OPTIONS
		# Memory arguments for JRockit
		USER_MEM_ARGS="-jrockit -Xms512m -Xmx512m -Xns128m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200ms -XX:+UseCallProfiling -XX:+UseLargePagesForHeap ${JMX_OPTIONS}"
		export USER_MEM_ARGS
	fi
fi

To prevent the following error

Exception in thread "[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'"
Exception in thread "Timer-1"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Timer-1"
***************************************************************************
The WebLogic Server encountered a critical failure
Reason: PermGen space
***************************************************************************
<Jan 30, 2013 4:24:14 PM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to FORCE_SHUTTING_DOWN.>
Exception in thread "main"
Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "main"

set the perm size, to values that are large enough (in the example 256Mb was enough in order to start WebLogic, these values might change when we are dealing with large deployments). When we want to use the node manager to start and stop servers we have to adjust the nodemanager.properties and set the JAVA_HOME variables accordingly, for example,

...
javaHome=/home/weblogic/jdk1.7.0_11
...
JavaHome=/home/weblogic/jdk1.7.0_11/jre
...
StartScriptEnabled=true
...

To set up an environment that has an application that uses Coherence deployed on WebLogic, we create a WebLogic managed server that has the following settings

<server>
	<name>security-server</name>
    <ssl>
		<enabled>false</enabled>
    </ssl>
    <machine>machine1</machine>
    <listen-port>8001</listen-port>
    <cluster xsi:nil="true"></cluster>
    <web-server>
		<web-server-log>
			<number-of-files-limited>false</number-of-files-limited>
		</web-server-log>
    </web-server>
    <listen-address>middleware-magic.com</listen-address>
    <server-start>
		<java-vendor>Sun</java-vendor>
		<java-home>/home/weblogic/jdk1.7.0_11</java-home>
		<arguments>-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:G1HeapRegionSize=2048k -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages -Dtangosol.coherence.mode=prod -Dtangosol.coherence.distributed.localstorage=false</arguments>
    </server-start>
</server>

and a Coherence cache server that has the following settings

<coherence-server>
    <name>coherence-server1</name>
    <machine>machine1</machine>
    <coherence-cluster-system-resource xsi:nil="true"></coherence-cluster-system-resource>
    <unicast-listen-address>localhost</unicast-listen-address>
    <unicast-listen-port>8088</unicast-listen-port>
    <unicast-port-auto-adjust>true</unicast-port-auto-adjust>
    <coherence-server-start>
		<java-vendor>Sun</java-vendor>
		<java-home>/home/weblogic/jdk1.7.0_11</java-home>
		<class-path>/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules.coherence.server_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar</class-path>
		<arguments>-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:G1HeapRegionSize=2048k -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages -Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true</arguments>
    </coherence-server-start>
</coherence-server>
  • -server – select the JIT compiler.
  • -Xms – initial heap size.
  • -Xmx – maximum heap size.
  • -XX:PermSize and -XX:MaxPermSize – size of the permanent generation.
  • -XX:NewRatio=N – sets the young generation to heap size / (1 + N).
  • -XX:SurvivorRatio – ratio of eden/survivor space size.
  • -XX:MaxTenuringThreshold – sets the maximum tenuring threshold for use in adaptive GC sizing (above we assume that objects that are not collected in the eden space are objects related to the Coherence cache, and are tenured to the old space as these objects will live for a long time).
  • -XX:+UseG1GC – select the G1 collector.
  • -XX:MaxGCPauseMillis – sets the maximum pause time goal.
  • -XX:InitiatingHeapOccupancyPercent – percentage of the (entire) heap occupancy to start a concurrent GC cycle. It is used by the G1 collector to trigger a concurrent GC cycle based on the occupancy of the entire heap, not just one of the generations.
  • -XX:G1HeapRegionSize – sets the size of the uniformly sized regions. We set this equal to the large page size.
  • -XX:+UseTLAB – enables thread-local object allocation. More information on thread local allocation can be found in the ‘Compaction and Thread Local Area’ section of the Tune the JVM that runs Coherence post.
  • -XX:LargePageSizeInBytes – sets the large page size used for the Java heap. We set this equal to the operating system parameter: Hugepagesize, which in our case is 2048kB
  • -XX:+UseLargePages – use large page memory. The steps involved on how to configure large pages in the operating system can be found in the ‘Call profiling and large pages’ section of the Tune the JVM that runs Coherence post.

Testing

To test the Coherence part of the set-up we will perform a load test, by using the following scripts

#!/bin/sh

# coherence options
#JMX_OPTIONS="-Dcom.sun.management.jmxremote.port=7091 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"
#JMX_OPTIONS="-Djava.rmi.server.hostname=192.168.1.150 -Xmanagement:ssl=false,authenticate=false,port=7091,autodiscovery=true"
COHERENCE_MANAGEMENT_OPTIONS="-Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true"
COHERENCE_OPTIONS="-Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml ${COHERENCE_MANAGEMENT_OPTIONS} ${JMX_OPTIONS}"
export COHERENCE_OPTIONS

JHICCUP_HOME="/home/weblogic/temp/jHiccup"
export JHICCUP_HOME

JAVA_HOME="/home/weblogic/jdk1.7.0_11"
#JAVA_HOME="/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0"
export JAVA_HOME

MEM_ARGS="-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:G1HeapRegionSize=2048k -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages"
#MEM_ARGS="-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -XX:+UseParallelOldGC -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages"
#MEM_ARGS="-jrockit -Xms1024m -Xmx1024m -Xgc:pausetime -XpauseTarget=200m -XX:+UseCallProfiling -XX:+UseLargePagesForHeap"
export MEM_ARGS

CLASSPATH="/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar"
export CLASSPATH

# start the test
${JAVA_HOME}/bin/java ${MEM_ARGS} ${COHERENCE_OPTIONS} com.tangosol.net.DefaultCacheServer
#$JHICCUP_HOME/jHiccup ${JAVA_HOME}/bin/java ${MEM_ARGS} ${COHERENCE_OPTIONS} com.tangosol.net.DefaultCacheServer

and

#!/bin/sh
# coherence options
COHERENCE_MANAGEMENT_OPTIONS="-Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true"
COHERENCE_OPTIONS="-Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml -Dtangosol.coherence.distributed.localstorage=false"
export COHERENCE_OPTIONS

#MEASUREMENT_OPTIONS="-verbosegc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -Xloggc:/home/weblogic/temp/gc.out"
#export MEASUREMENT_OPTIONS

JHICCUP_HOME="/home/weblogic/temp/jHiccup"
export JHICCUP_HOME

JAVA_HOME="/home/weblogic/jdk1.7.0_11"
#JAVA_HOME="/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0"
export JAVA_HOME

MEM_ARGS="-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:InitiatingHeapOccupancyPercent=80 -XX:G1HeapRegionSize=2048k -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages"
#MEM_ARGS="-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -XX:+UseParallelOldGC -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages"
#MEM_ARGS="-jrockit -Xms1024m -Xmx1024m -Xgc:pausetime -XpauseTarget=200m -XX:+UseCallProfiling -XX:+UseLargePagesForHeap"
export MEM_ARGS

CLASSPATH="/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar"
export CLASSPATH

# start the test
${JAVA_HOME}/bin/java ${MEM_ARGS} ${COHERENCE_OPTIONS} ${MEASUREMENT_OPTIONS} model.test.Test
#$JHICCUP_HOME/jHiccup ${JAVA_HOME}/bin/java ${MEM_ARGS} ${COHERENCE_OPTIONS} ${MEASUREMENT_OPTIONS} model.test.Test

The first script runs a cache server, the second a cache client (which inserts, updates, deletes and obtains data from the cache)

[weblogic@middleware-magic temp]$ ./default-cache-server.sh
2013-02-08 13:18:23.816/0.518 Oracle Coherence 3.7.1.1 <Info> (thread=main, member=n/a): Loaded operational configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence.xml"
2013-02-08 13:18:23.911/0.613 Oracle Coherence 3.7.1.1 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence-override-prod.xml"
2013-02-08 13:18:24.003/0.705 Oracle Coherence 3.7.1.1 <Info> (thread=main, member=n/a): Loaded operational overrides from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/tangosol-coherence-override.xml"
2013-02-08 13:18:24.010/0.712 Oracle Coherence 3.7.1.1 <D5> (thread=main, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified

Oracle Coherence Version 3.7.1.1 Build 28901
 Grid Edition: Production mode
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

2013-02-08 13:18:24.434/1.136 Oracle Coherence GE 3.7.1.1 <Info> (thread=main, member=n/a): Loaded cache configuration from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/security-cache-config.xml"
2013-02-08 13:18:24.569/1.271 Oracle Coherence GE 3.7.1.1 <Info> (thread=main, member=n/a): Loaded Reporter configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/reports/report-group.xml"
2013-02-08 13:18:25.047/1.749 Oracle Coherence GE 3.7.1.1 <D4> (thread=main, member=n/a): TCMP bound to /192.168.1.150:8088 using SystemSocketProvider
2013-02-08 13:18:55.444/32.146 Oracle Coherence GE 3.7.1.1 <Info> (thread=Cluster, member=n/a): Created a new cluster "SecurityCoherenceCluster" with Member(Id=1, Timestamp=2013-02-08 13:18:25.091, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8514, Role=CoherenceServer, Edition=Grid Edition, Mode=Production, CpuCount=4, SocketCount=1) UID=0xC0A801960000013CB9BE0AC3FE391F98
2013-02-08 13:18:55.459/32.161 Oracle Coherence GE 3.7.1.1 <Info> (thread=main, member=n/a): Started cluster Name=SecurityCoherenceCluster

WellKnownAddressList(Size=1,
  WKA{Address=192.168.1.150, Port=8088}
  )

MasterMemberSet(
  ThisMember=Member(Id=1, Timestamp=2013-02-08 13:18:25.091, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8514, Role=CoherenceServer)
  OldestMember=Member(Id=1, Timestamp=2013-02-08 13:18:25.091, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8514, Role=CoherenceServer)
  ActualMemberSet=MemberSet(Size=1
    Member(Id=1, Timestamp=2013-02-08 13:18:25.091, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:8514, Role=CoherenceServer)
    )
  MemberId|ServiceVersion|ServiceJoined|MemberState
    1|3.7.1|2013-02-08 13:18:55.444|JOINED
  RecycleMillis=1200000
  RecycleSet=MemberSet(Size=0
    )
  )

TcpRing{Connections=[]}
IpMonitor{AddressListSize=0}

2013-02-08 13:18:55.530/32.232 Oracle Coherence GE 3.7.1.1 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
2013-02-08 13:18:55.759/32.461 Oracle Coherence GE 3.7.1.1 <Info> (thread=DistributedCache, member=1): Loaded POF configuration from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/security-pof-config.xml"
2013-02-08 13:18:55.788/32.490 Oracle Coherence GE 3.7.1.1 <Info> (thread=DistributedCache, member=1): Loaded included POF configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/coherence-pof-config.xml"
2013-02-08 13:18:55.850/32.552 Oracle Coherence GE 3.7.1.1 <D5> (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1
2013-02-08 13:18:55.881/32.583 Oracle Coherence GE 3.7.1.1 <Info> (thread=main, member=1):
Services
  (
  ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.7.1, OldestMemberId=1}
  InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
  PartitionedCache{Name=DistributedCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0}
  )

Started DefaultCacheServer...

2013-02-08 13:19:19.525/56.227 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest) joined Cluster with senior member 1
2013-02-08 13:19:19.612/56.314 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1
2013-02-08 13:19:20.038/56.740 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service DistributedCache with senior member 1
2013-02-08 13:20:56.110/152.812 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1125 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 75 packets rescheduled, PauseRate=0.0116, Threshold=4096
2013-02-08 13:20:58.125/154.827 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1154 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 45 packets rescheduled, PauseRate=0.0231, Threshold=3892
2013-02-08 13:27:11.534/528.236 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1784 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 1605 packets rescheduled, PauseRate=0.014, Threshold=3882
2013-02-08 13:27:12.915/529.617 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1166 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 215 packets rescheduled, PauseRate=0.0164, Threshold=3688
2013-02-08 13:27:47.460/564.162 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 3083 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 45 packets rescheduled, PauseRate=0.0214, Threshold=4096
2013-02-08 13:29:33.054/669.756 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1457 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4118 packets rescheduled, PauseRate=0.0207, Threshold=4096
2013-02-08 13:29:58.610/695.312 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1099 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 1244 packets rescheduled, PauseRate=0.0219, Threshold=3505
2013-02-08 13:32:54.405/871.107 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 3079 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 261 packets rescheduled, PauseRate=0.0226, Threshold=2713
2013-02-08 13:39:45.109/1281.811 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1001 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4116 packets rescheduled, PauseRate=0.0172, Threshold=4096
2013-02-08 13:41:05.814/1362.516 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 2553 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 3918 packets rescheduled, PauseRate=0.0185, Threshold=4096
2013-02-08 13:41:07.168/1363.870 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1146 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 2920 packets rescheduled, PauseRate=0.0194, Threshold=4086
2013-02-08 13:41:20.716/1377.418 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 2990 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 111 packets rescheduled, PauseRate=0.0214, Threshold=3505
2013-02-08 13:41:58.747/1415.449 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 3029 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4126 packets rescheduled, PauseRate=0.0231, Threshold=4096
2013-02-08 13:42:00.268/1416.970 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1284 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4117 packets rescheduled, PauseRate=0.024, Threshold=4096
2013-02-08 13:47:57.581/1774.283 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 3942 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 106 packets rescheduled, PauseRate=0.0215, Threshold=3854
2013-02-08 13:49:12.154/1848.856 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 2733 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 148 packets rescheduled, PauseRate=0.0223, Threshold=3505
2013-02-08 13:50:15.032/1911.734 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 3392 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 190 packets rescheduled, PauseRate=0.0235, Threshold=4096
2013-02-08 13:51:00.063/1956.765 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 2918 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4052 packets rescheduled, PauseRate=0.0247, Threshold=4023
2013-02-08 13:51:01.733/1958.435 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1457 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 3890 packets rescheduled, PauseRate=0.0255, Threshold=4096
2013-02-08 13:52:41.079/2057.781 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 2750 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 3726 packets rescheduled, PauseRate=0.0261, Threshold=3698
2013-02-08 14:08:09.516/2986.218 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1063 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 1753 packets rescheduled, PauseRate=0.0229, Threshold=4086
2013-02-08 14:10:04.268/3100.970 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1131 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4106 packets rescheduled, PauseRate=0.0227, Threshold=4086
2013-02-08 14:10:13.452/3110.154 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1010 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4115 packets rescheduled, PauseRate=0.023, Threshold=4096
2013-02-08 14:10:14.833/3111.535 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1139 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4106 packets rescheduled, PauseRate=0.0233, Threshold=4086
2013-02-08 14:10:31.388/3128.090 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1010 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 2878 packets rescheduled, PauseRate=0.0235, Threshold=2858
2013-02-08 14:10:32.819/3129.521 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1206 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 2872 packets rescheduled, PauseRate=0.0239, Threshold=2851
2013-02-08 14:10:43.136/3139.838 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1135 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 163 packets rescheduled, PauseRate=0.0245, Threshold=3283
2013-02-08 14:11:36.859/3193.561 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 4313 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 177 packets rescheduled, PauseRate=0.0254, Threshold=4096
2013-02-08 14:27:48.746/4165.448 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 2824 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4115 packets rescheduled, PauseRate=0.0223, Threshold=4086
2013-02-08 14:27:50.454/4167.156 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1490 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4098 packets rescheduled, PauseRate=0.0227, Threshold=4076
2013-02-08 14:28:39.448/4216.150 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 3848 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 86 packets rescheduled, PauseRate=0.0233, Threshold=4096
2013-02-08 14:29:44.679/4281.381 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 4360 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 199 packets rescheduled, PauseRate=0.0242, Threshold=4096
2013-02-08 14:30:35.106/4331.808 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 3074 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 4126 packets rescheduled, PauseRate=0.0247, Threshold=4096
2013-02-08 14:30:36.794/4333.496 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 1455 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 3904 packets rescheduled, PauseRate=0.0251, Threshold=3882
2013-02-08 14:31:46.922/4403.624 Oracle Coherence GE 3.7.1.1 <Warning> (thread=PacketPublisher, member=1): Experienced a 4512 ms communication delay (probable remote GC) with Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest); 142 packets rescheduled, PauseRate=0.0257, Threshold=4086
2013-02-08 14:32:32.260/4448.962 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=2, Timestamp=2013-02-08 13:19:19.335, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest) due to a peer departure; removing the member.
2013-02-08 14:32:32.260/4448.962 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 left service Management with senior member 1
2013-02-08 14:32:32.260/4448.962 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 left service DistributedCache with senior member 1
2013-02-08 14:32:32.260/4448.962 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-02-08 14:32:32.26, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:8610, Role=ModelTestTest) left Cluster with senior member 1

What is worrying are the ‘Experienced a ….ms communication delay’ messages that appear frequently, and also the reason behind it (i.e., probable remote GC). To see what is happening on the operating system (RAM and CPU) we can use vmstat and mpstat

[weblogic@middleware-magic ~]$ vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 4374164 162896 695112    0    0    14   146  443  602 28  3 68  1  0
[weblogic@middleware-magic ~]$ mpstat -P ALL
Linux 2.6.32-279.22.1.el6.x86_64 (middleware-magic.com) 	02/08/2013 	_x86_64_	(4 CPU)

02:33:15 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
02:33:15 PM  all   28.09    0.29    2.44    0.83    0.01    0.12    0.00    0.00   68.23
02:33:15 PM    0   27.13    0.42    2.53    0.81    0.00    0.12    0.00    0.00   68.98
02:33:15 PM    1   29.86    0.30    2.33    0.81    0.00    0.11    0.00    0.00   66.57
02:33:15 PM    2   27.70    0.21    2.55    0.91    0.00    0.13    0.00    0.00   68.49
02:33:15 PM    3   27.66    0.23    2.35    0.77    0.01    0.12    0.00    0.00   68.87

Now let us see if the communication is really some problem that involves garbage collection (stop-the-world) times. We run the test again, now with JRockit (and also set a pausetime goal of 200msec, just as was done with the G1 collector). The following shows the output of the cache server

[weblogic@middleware-magic temp]$ ./default-cache-server.sh
2013-02-08 11:24:19.549/2.676 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence.xml"
2013-02-08 11:24:19.577/2.704 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational overrides from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence-override-prod.xml"
2013-02-08 11:24:19.595/2.722 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational overrides from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/tangosol-coherence-override.xml"
2013-02-08 11:24:19.601/2.728 Oracle Coherence 3.7.1.1 <D5> (thread=Main Thread, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified

Oracle Coherence Version 3.7.1.1 Build 28901
 Grid Edition: Production mode
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

2013-02-08 11:24:19.916/3.043 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded cache configuration from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/security-cache-config.xml"
2013-02-08 11:24:20.393/3.520 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded Reporter configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/reports/report-group.xml"
2013-02-08 11:24:21.262/4.389 Oracle Coherence GE 3.7.1.1 <D4> (thread=Main Thread, member=n/a): TCMP bound to /192.168.1.150:8088 using SystemSocketProvider
2013-02-08 11:24:51.778/34.905 Oracle Coherence GE 3.7.1.1 <Info> (thread=Cluster, member=n/a): Created a new cluster "SecurityCoherenceCluster" with Member(Id=1, Timestamp=2013-02-08 11:24:21.331, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:7376, Role=CoherenceServer, Edition=Grid Edition, Mode=Production, CpuCount=4, SocketCount=1) UID=0xC0A801960000013CB9559D53FE391F98
2013-02-08 11:24:51.816/34.943 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Started cluster Name=SecurityCoherenceCluster

WellKnownAddressList(Size=1,
  WKA{Address=192.168.1.150, Port=8088}
  )

MasterMemberSet(
  ThisMember=Member(Id=1, Timestamp=2013-02-08 11:24:21.331, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:7376, Role=CoherenceServer)
  OldestMember=Member(Id=1, Timestamp=2013-02-08 11:24:21.331, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:7376, Role=CoherenceServer)
  ActualMemberSet=MemberSet(Size=1
    Member(Id=1, Timestamp=2013-02-08 11:24:21.331, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:7376, Role=CoherenceServer)
    )
  MemberId|ServiceVersion|ServiceJoined|MemberState
    1|3.7.1|2013-02-08 11:24:51.783|JOINED
  RecycleMillis=1200000
  RecycleSet=MemberSet(Size=0
    )
  )

TcpRing{Connections=[]}
IpMonitor{AddressListSize=0}

2013-02-08 11:24:51.944/35.071 Oracle Coherence GE 3.7.1.1 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
2013-02-08 11:24:52.255/35.382 Oracle Coherence GE 3.7.1.1 <Info> (thread=DistributedCache, member=1): Loaded POF configuration from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/security-pof-config.xml"
2013-02-08 11:24:52.265/35.392 Oracle Coherence GE 3.7.1.1 <Info> (thread=DistributedCache, member=1): Loaded included POF configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/coherence-pof-config.xml"
2013-02-08 11:24:52.303/35.430 Oracle Coherence GE 3.7.1.1 <D5> (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1
2013-02-08 11:24:52.375/35.503 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=1):
Services
  (
  ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.7.1, OldestMemberId=1}
  InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
  PartitionedCache{Name=DistributedCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0}
  )

Started DefaultCacheServer...

2013-02-08 11:26:21.422/124.550 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-02-08 11:26:21.174, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:7442, Role=ModelTestTest) joined Cluster with senior member 1
2013-02-08 11:26:21.716/124.843 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1
2013-02-08 11:26:22.150/125.277 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service DistributedCache with senior member 1
[INFO ][mgmnt  ] Local JMX connector started
2013-02-08 13:07:05.135/6168.262 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): TcpRing disconnected from Member(Id=2, Timestamp=2013-02-08 11:26:21.174, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:7442, Role=ModelTestTest) due to a peer departure; removing the member.
2013-02-08 13:07:05.139/6168.266 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 left service Management with senior member 1
2013-02-08 13:07:05.140/6168.267 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 left service DistributedCache with senior member 1
2013-02-08 13:07:05.144/6168.271 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-02-08 13:07:05.141, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:7442, Role=ModelTestTest) left Cluster with senior member 1

Luckily the communication issues are gone. To see what JRockit does on the operating system we again use vmstat and pmstat

[weblogic@middleware-magic ~]$ vmstat
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 5393884 155152 694208    0    0    20   209  715   26 29  2 68  1  0
[weblogic@middleware-magic ~]$ mpstat -P ALL
Linux 2.6.32-279.22.1.el6.x86_64 (middleware-magic.com) 	02/08/2013 	_x86_64_	(4 CPU)

01:08:01 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
01:08:01 PM  all   28.52    0.41    2.22    1.16    0.01    0.13    0.00    0.00   67.55
01:08:01 PM    0   27.03    0.60    2.38    1.15    0.01    0.13    0.00    0.00   68.71
01:08:01 PM    1   31.10    0.41    2.20    1.14    0.00    0.11    0.00    0.00   65.03
01:08:01 PM    2   28.10    0.31    2.28    1.28    0.00    0.14    0.00    0.00   67.89
01:08:01 PM    3   27.86    0.33    2.02    1.08    0.01    0.13    0.00    0.00   68.57

A remark is in order; the ‘Experienced a …ms communication delay’ messages also do not appear when the parallel collector (-XX:+UseParallelGC) settings are used, which can also be seen in the following measurements

Note the difference in garbage collection times between the G1 collector (the first two) and the parallel collector (the last two). The load test brakes about everything the G1 collector is designed for:

  • Operate concurrently with applications threads like the CMS collector.
  • Compact free space without lengthy GC induced pause times.
  • Need more predictable GC pause durations.
  • Do not want to sacrifice a lot of throughput performance.
  • Do not require a much larger Java heap.

Based on the measurements we will resort to the parallel collector and change the JVM parameters to the following for the WebLogic managed server

<server>
    <name>security-server</name>
    <ssl>
		<enabled>false</enabled>
    </ssl>
    <machine>machine1</machine>
    <listen-port>8001</listen-port>
    <cluster xsi:nil="true"></cluster>
    <web-server>
		<web-server-log>
			<number-of-files-limited>false</number-of-files-limited>
		</web-server-log>
    </web-server>
    <listen-address>middleware-magic.com</listen-address>
    <server-start>
		<java-vendor>Sun</java-vendor>
		<java-home>/home/weblogic/jdk1.7.0_11</java-home>
		<arguments>-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -XX:+UseParallelOldGC -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages -Dtangosol.coherence.mode=prod -Dtangosol.coherence.distributed.localstorage=false</arguments>
    </server-start>
  </server>

and to the following for the Coherence cache server

<coherence-server>
    <name>coherence-server1</name>
    <machine>machine1</machine>
    <coherence-cluster-system-resource xsi:nil="true"></coherence-cluster-system-resource>
    <unicast-listen-address>localhost</unicast-listen-address>
    <unicast-listen-port>8088</unicast-listen-port>
    <unicast-port-auto-adjust>true</unicast-port-auto-adjust>
    <coherence-server-start>
		<java-vendor>Sun</java-vendor>
		<java-home>/home/weblogic/jdk1.7.0_11</java-home>
		<class-path>/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules.coherence.server_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar</class-path>
		<arguments>-server -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:NewRatio=2 -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -XX:+UseParallelOldGC -XX:+UseTLAB -XX:LargePageSizeInBytes=2048k -XX:+UseLargePages -Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true</arguments>
    </coherence-server-start>
  </coherence-server>

References

[1] Getting Started with the G1 Garbage Collector.
[2] Java Garbage Collection Basics.
[3] jHiccup: Open Source Tool to Measure Variations in Java Performance.


Automate WebLogic Installation and Configuration

In this post, we will show how to create automation scripts in order to set-up middleware environments.

Preparation

As an example, we will use the Oracle Service Bus. In the example, we will use the following software

First, we have to decide how the directory structure will look, for example

/home/osb
	/oraInventory (created during the installation of Oracle Service Bus)
	/osb11.1.1.6
		/jrockit-jdk1.6.0_37 (created during the installation of JRockit)
		/installation (directory which will contain all the software)
			/coherence_3.7 (created during the installation of WebLogic Server)
			/oracle_common (created during the installation of Oracle Service Bus)
			/oracle_service_bus (created during the installation of Oracle Service Bus)
			/wlserver_10.3 (created during the installation of WebLogic Server)
		/configuration
			/applications
				/osb_domain (created during the configuration of Oracle Service Bus)
			/domains
				/osb_domain (created during the configuration of Oracle Service Bus)
			/nodemanagers
				/osb_domain (created during the configuration of Oracle Service Bus)

Installation

To silent install JRockit, we need the following XML file

<domain-template-descriptor>
	<input-fields>
		<!-- Installation directory -->
		<data-value name="USER_INSTALL_DIR" value="/home/osb/osb11.1.1.6/jrockit-jdk1.6.0_37"/>
		<!-- Optional installation of Demos and Samples -->
		<data-value name="INSTALL_DEMOS_AND_SAMPLES" value="false"/>
		<!-- Optional installation of Source Code -->
		<data-value name="INSTALL_SOURCE_CODE" value="false"/>
	</input-fields>
</domain-template-descriptor>

To silent install WebLogic, we need the following XML file

<bea-installer>
	<input-fields>
		<!-- BEAHOME: The full path for the middleware home directory. -->
		<data-value name="BEAHOME" value="/home/osb/osb11.1.1.6/installation"/>
		<!-- WLS_INSTALL_DIR: The full path for the directory where to install WebLogic Server. -->
		<data-value name="WLS_INSTALL_DIR" value="/home/osb/osb11.1.1.6/installation/wlserver_10.3"/>
		<!-- OCP_INSTALL_DIR: The full path for the directory where to install Coherence. -->
		<data-value name="OCP_INSTALL_DIR" value="/home/osb/osb11.1.1.6/installation/coherence_3.7"/>
		<!-- COMPONENT_PATHS: Specify the components and subcomponents to install. -->
		<data-value name="COMPONENT_PATHS" value="WebLogic Server/Core Application Server|WebLogic Server/Administration Console|WebLogic Server/Configuration Wizard and Upgrade Framework|WebLogic Server/Web 2.0 HTTP Pub-Sub Server|WebLogic Server/WebLogic JDBC Drivers|WebLogic Server/Third Party JDBC Drivers|WebLogic Server/WebLogic Server Clients|WebLogic Server/WebLogic Web Server Plugins|WebLogic Server/UDDI and Xquery Support|Oracle Coherence/Coherence Product Files"/>
		<!-- INSTALL_NODE_MANAGER_SERVICE: Install Node Manager as a Windows service. -->
		<data-value name="INSTALL_NODE_MANAGER_SERVICE" value="no"/>
		<!-- LOCAL_JVMS: Select JVMs which are already installed. -->
		<data-value name="LOCAL_JVMS" value="/home/osb/osb11.1.1.6/jrockit-jdk1.6.0_37"/>
	</input-fields>
</bea-installer>

Note that the XML files, reflect our directory structure.

As we are testing this (installing and configuring the Oracle Service Bus) on Redhat-6.4, we have to make sure that a right entry is added to the refhost.xml (located in the Disk1/stage/prereq/linux64 directory, which is created after the Oracle Service Bus software is unzipped), for example,

<OPERATING_SYSTEM>
	<VERSION VALUE="6.4"/>
	<ARCHITECTURE VALUE="x86_64"/>
    <NAME VALUE="Linux"/>
	<VENDOR VALUE="redhat"/>
	<GLIBC ATLEAST="2.12-1.7.el6"></GLIBC>
	<PACKAGES>
		<PACKAGE NAME="binutils" VERSION="2.20.51.0.2-5.11.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="compat-libcap1" VERSION="1.10-1" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="compat-libstdc++-33" VERSION="3.2.3-69.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="compat-libstdc++-33" VERSION="3.2.3-69.el6"  ARCHITECTURE="i686" />
		<PACKAGE NAME="libgcc" VERSION="4.4.4-13.el6" ARCHITECTURE="i686" />
		<PACKAGE NAME="libgcc" VERSION="4.4.4-13.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="libstdc++" VERSION="4.4.4-13.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="libstdc++" VERSION="4.4.4-13.el6" ARCHITECTURE="i686"/>
		<PACKAGE NAME="libstdc++-devel" VERSION="4.4.4-13.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="sysstat" VERSION="9.0.4-11.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="gcc" VERSION="4.4.4-13.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="gcc-c++" VERSION="4.4.4-13.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="glibc" VERSION="2.12-1.7.el6" ARCHITECTURE="i686" />
		<PACKAGE NAME="glibc" VERSION="2.12-1.7.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="glibc-devel" VERSION="2.12-1.7.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="glibc-devel" VERSION="2.12-1.7.el6" />
		<PACKAGE NAME="libaio" VERSION="0.3.107-10.el6" ARCHITECTURE="x86_64" />
		<PACKAGE NAME="libaio-devel" VERSION="0.3.107-10.el6" ARCHITECTURE="x86_64" />
	</PACKAGES>
	<KERNEL>
		<PROPERTY NAME="VERSION" VALUE="2.6.32-279.19.1.el6"/>
		<PROPERTY NAME="hardnofiles" VALUE="4096"/>
		<PROPERTY NAME="softnofiles" VALUE="4096"/>
	</KERNEL>
</OPERATING_SYSTEM>

Note that this is based on the VENDOR VALUE="oracle" and VERSION VALUE="6" entry. When running on RedHat Enterprise Linux 6.4 an entry such as above has to be added. The certification matrix states that RedHat Enterprise Linux 6.4 is supported, i.e., OSB 11.1.1.5+, x64 (only 64-bits), RedHatEL6(UL1+), JRockit Update 29 R28.2.0+.

Make sure the packages mentioned above are installed on the system. By using yum, the packages can be installed, i.e., yum install ${NAME}-${VERSION}.${ARCHITECTURE}, for example, yum install compat-libstdc++-33-3.2.3-69.el6.i686.

To silent install the Oracle Service Bus, we first have to create a response file. To this end run the installer in graphical mode, i.e., execute ./runInstaller -jreLoc /home/osb/jrockit-jdk1.6.0_37-R28.2.5-4.1.0 in the Disk1 directory.

  • When this is the first time the installer is started, the specify inventory screen will pop-up. Enter an inventory directory and an operating system group name and click ok. Next execute ${INVENTORY_HOME}/createCentralInventory.sh as root and click ok in the pop-up.
  • The welcome screen is shown, click next.
  • Select skip software updates and click next.
  • Enter the following parameters:
    • Oracle Middleware Home: /home/osb/osb11.1.1.6/installation
    • Oracle Home Directory: oracle_service_bus
  • Click next.
  • Select custom in the installation type screen, and click next.
  • De-select, oracle service bus IDE and oracle service bus examples, and click next.
  • Prerequisite checks are run, click next when they finish successfully.
  • Enter the following parameters:
    • WebLogic Server Location: /home/osb/osb11.1.1.6/installation/wlserver_10.3
  • Click next.
  • Installation summary is shown, click save to save the response file.
  • Click install, click next when finished and click finish.

The resulting response file looks as follows

[ENGINE]

#DO NOT CHANGE THIS.
Response File Version=1.0.0.0.0

[GENERIC]

#Set this to true if you wish to specify a directory where latest updates are downloaded. This option would use the software updates from the specified directory
SPECIFY_DOWNLOAD_LOCATION=false

#
SKIP_SOFTWARE_UPDATES=true

#If the Software updates are already downloaded and available on your local system, then specify the path to the directory where these patches are available and set SPECIFY_DOWNLOAD_LOCATION to true
SOFTWARE_UPDATES_DOWNLOAD_LOCATION=

#Write the name of the Oracle Home directory. The Oracle Home directory name may only contain alphanumeric , hyphen (-) , dot (.) and underscore (_) characters, and it must begin with an alphanumeric character.
ORACLE_HOME=/home/osb/osb11.1.1.6/installation/oracle_service_bus

#Write the complete path to a valid Middleware Home.
MIDDLEWARE_HOME=/home/osb/osb11.1.1.6/installation

#Set this to true if typical installation must be done. If this is set to true then wariable "CUSTOM TYPE" must be set to false as the variables are mutually exclusive
TYPICAL TYPE=false

#Set this to true if custom installation must be done, all other required variables need to be provided. If this is set to true then variable "TYPICAL TYPE" must be set to false as the variables are mutually exclusive.
CUSTOM TYPE=true

#Set this to true if component Oracle Service Bus Examples must be installed. This input will be needed only in the case of custom installation
Oracle Service Bus Examples=false

#Set this to true if component Oracle Service Bus IDE must be installed. This input will be needed only in the case of custom installation
Oracle Service Bus IDE=false

#Give the complete path to a valid WebLogic Server Home for the corresponding Middleware Home entered.
WL_HOME=/home/osb/osb11.1.1.6/installation/wlserver_10.3

#Give the complete path to a valid OEPE Home for the corresponding Middleware Home entered. This input will be needed in both typical and custom installations. But in case of custom installation, Oracle Service Bus IDE must be set to true.
#OEPE_HOME=/tmp

[SYSTEM]

[APPLICATIONS]

[RELATIONSHIPS]

An example script that installs the necessary software, looks as follows

#!/bin/bash

SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/SetEnvironmentVariables.sh

create_silent_install_files() {
	echo 'CREATING SILENT INSTALL FILES'
	echo '<?xml version="1.0" encoding="UTF-8" ?>
<domain-template-descriptor>
	<input-fields>
		<!-- Installation directory -->
		<data-value name="USER_INSTALL_DIR" value="'${JAVA_HOME}'"/>
		<!-- Optional installation of Demos and Samples -->
		<data-value name="INSTALL_DEMOS_AND_SAMPLES" value="false"/>
		<!-- Optional installation of Source Code -->
		<data-value name="INSTALL_SOURCE_CODE" value="false"/>
		<!-- Optional installation of Public JRE -->
		<data-value name="INSTALL_PUBLIC_JRE" value="false"/>
	</input-fields>
</domain-template-descriptor>' > ${SCRIPT_PATH}/silent-jrockit.xml

	echo '<?xml version="1.0" encoding="UTF-8"?>
<bea-installer>
	<input-fields>
		<!-- BEAHOME: The full path for the middleware home directory. -->
		<data-value name="BEAHOME" value="'${MIDDLEWARE_HOME}'"/>
		<!-- WLS_INSTALL_DIR: The full path for the directory where to install WebLogic Server. -->
		<data-value name="WLS_INSTALL_DIR" value="'${WEBLOGIC_HOME}'"/>
		<!-- OCP_INSTALL_DIR: The full path for the directory where to install Coherence. -->
		<data-value name="OCP_INSTALL_DIR" value="'${COHERENCE_HOME}'"/>
		<!-- COMPONENT_PATHS: Specify the components and subcomponents to install. -->
		<data-value name="COMPONENT_PATHS" value="WebLogic Server/Core Application Server|WebLogic Server/Administration Console|WebLogic Server/Configuration Wizard and Upgrade Framework|WebLogic Server/Web 2.0 HTTP Pub-Sub Server|WebLogic Server/WebLogic JDBC Drivers|WebLogic Server/Third Party JDBC Drivers|WebLogic Server/WebLogic Server Clients|WebLogic Server/WebLogic Web Server Plugins|WebLogic Server/UDDI and Xquery Support|Oracle Coherence/Coherence Product Files"/>
		<!-- INSTALL_NODE_MANAGER_SERVICE: Install Node Manager as a Windows service. -->
		<data-value name="INSTALL_NODE_MANAGER_SERVICE" value="no"/>
		<!-- LOCAL_JVMS: Select JVMs which are already installed. -->
		<data-value name="LOCAL_JVMS" value="'${JAVA_HOME}'"/>
		<!-- BEA_BUNDLED_JVMS: Option to select BEA bundled JVMS -->
		<data-value name="BEA_BUNDLED_JVMS" value=""/>
	</input-fields>
</bea-installer>' > ${SCRIPT_PATH}/silent-weblogic.xml

	echo '[ENGINE]

#DO NOT CHANGE THIS.
Response File Version=1.0.0.0.0

[GENERIC]

#Set this to true if you wish to specify a directory where latest updates are downloaded. This option would use the software updates from the specified directory
SPECIFY_DOWNLOAD_LOCATION=false

#
SKIP_SOFTWARE_UPDATES=true

#If the Software updates are already downloaded and available on your local system, then specify the path to the directory where these patches are available and set SPECIFY_DOWNLOAD_LOCATION to true
SOFTWARE_UPDATES_DOWNLOAD_LOCATION=

#Write the name of the Oracle Home directory. The Oracle Home directory name may only contain alphanumeric , hyphen (-) , dot (.) and underscore (_) characters, and it must begin with an alphanumeric character.
ORACLE_HOME='${FUSION_MIDDLEWARE_HOME}'

#Write the complete path to a valid Middleware Home.
MIDDLEWARE_HOME='${MIDDLEWARE_HOME}'

#Set this to true if typical installation must be done. If this is set to true then wariable "CUSTOM TYPE" must be set to false as the variables are mutually exclusive
TYPICAL TYPE=false

#Set this to true if custom installation must be done, all other required variables need to be provided. If this is set to true then variable "TYPICAL TYPE" must be set to false as the variables are mutually exclusive.
CUSTOM TYPE=true

#Set this to true if component Oracle Service Bus Examples must be installed. This input will be needed only in the case of custom installation
Oracle Service Bus Examples=false

#Set this to true if component Oracle Service Bus IDE must be installed. This input will be needed only in the case of custom installation
Oracle Service Bus IDE=false

#Give the complete path to a valid WebLogic Server Home for the corresponding Middleware Home entered.
WL_HOME='${WEBLOGIC_HOME}'

#Give the complete path to a valid OEPE Home for the corresponding Middleware Home entered. This input will be needed in both typical and custom installations. But in case of custom installation, Oracle Service Bus IDE must be set to true.
#OEPE_HOME=/tmp

[SYSTEM]

[APPLICATIONS]

[RELATIONSHIPS]' > ${SCRIPT_PATH}/silent-service-bus.txt

	echo 'inventory_loc='${ORACLE_INVENTORY_HOME}'
inst_group='${ORACLE_INSTALL_GROUP}'' > ${SCRIPT_PATH}/oraInv.loc
}

create_repository() {
	${SOFTWARE_DIRECTORY}/rcuHome/bin/rcu -silent -createRepository -databaseType ORACLE -connectString 192.168.1.60:1521:orcl11 -dbUser sys -dbRole SYSDBA -schemaPrefix DEV -useSamePasswordForAllSchemaUsers true -component SOAINFRA -component MDS -component ORASDPM -f < ${SCRIPT_PATH}/passwordfile.txt
}

drop_repository() {
	${SOFTWARE_DIRECTORY}/rcuHome/bin/rcu -silent -dropRepository -databaseType ORACLE -connectString 192.168.1.60:1521:orcl11 -dbUser sys -dbRole SYSDBA -schemaPrefix DEV -component SOAINFRA -component MDS -component ORASDPM -f < ${SCRIPT_PATH}/passwordfile.txt
}

install_jrockit() {
	echo 'INSTALLING JAVA VIRTUAL MACHINE'
	${SOFTWARE_DIRECTORY}/${JVM_FILE_NAME} -mode=silent -silent_xml=${SCRIPT_PATH}/silent-jrockit.xml -log=${SCRIPT_PATH}/logs/jrockit-install.log

	echo 'ADJUST ENTROPY GATHERING DEVICE SETTINGS'
	sed '/securerandom/ s_file:/dev/urandom_file:/dev/./urandom_' ${JAVA_HOME}/jre/lib/security/java.security > ${SCRIPT_PATH}/java.security
	mv ${SCRIPT_PATH}/java.security ${JAVA_HOME}/jre/lib/security/java.security
}

install_weblogic() {
	echo 'INSTALLING WEBLOGIC SERVER'
	${JAVA_HOME}/bin/java -Xms512m -Xmx512m -jar ${SOFTWARE_DIRECTORY}/${WEBLOGIC_FILE_NAME} -mode=silent -silent_xml=${SCRIPT_PATH}/silent-weblogic.xml -log=${SCRIPT_PATH}/logs/weblogic-install.log
}

install_service_bus() {
	echo 'INSTALLING SERVICE BUS'
	${SOFTWARE_DIRECTORY}/Disk1/runInstaller -silent -responsefile ${SCRIPT_PATH}/silent-service-bus.txt -jreLoc ${JAVA_HOME} -invPtrLoc ${SCRIPT_PATH}/oraInv.loc
}

create_silent_install_files

install_jrockit

install_weblogic

install_service_bus

Note that the script above also takes into account the creation of the Oracle inventory (that needs to be created when fusion middleware software is installed for the first time). The SetEnvironmentVariables.sh script has the following contents

#!/bin/sh

# Directory where the software to be installed is located
SOFTWARE_DIRECTORY="/home/osb/temp"
export SOFTWARE_DIRECTORY

# Name of JVM file
JVM_FILE_NAME="jrockit-jdk1.6.0_37-R28.2.5-4.1.0-linux-x64.bin"
export JVM_FILE_NAME

# Name of the WebLogic file
WEBLOGIC_FILE_NAME="wls1036_generic.jar"
export WEBLOGIC_FILE_NAME

# Base directory
BASE_DIRECTORY="/home/osb"
export BASE_DIRECTORY

# Directory that will used for the installation and configuration
RUNTIME_HOME="${BASE_DIRECTORY}/osb11.1.1.6"
export RUNTIME_HOME

# Directory where the JVM will be installed
JAVA_HOME="${RUNTIME_HOME}/jrockit-jdk1.6.0_37"
export JAVA_HOME

# Directory that will be used as the middleware home (holds software binaries)
MIDDLEWARE_HOME="${RUNTIME_HOME}/installation"
export MIDDLEWARE_HOME

# Depending on the WebLogic version to be installed, edit the wlserver_major.minor version
WEBLOGIC_HOME="${MIDDLEWARE_HOME}/wlserver_10.3"
export WEBLOGIC_HOME

# Depending on the Coherence version to be installed, edit the coherence_major.minor version
COHERENCE_HOME="${MIDDLEWARE_HOME}/coherence_3.7"
export COHERENCE_HOME

# Directory where the fusion middleware software will be installed
FUSION_MIDDLEWARE_HOME="${MIDDLEWARE_HOME}/oracle_service_bus"
export FUSION_MIDDLEWARE_HOME

# Location of the Oracle inventory
ORACLE_INVENTORY_HOME="${BASE_DIRECTORY}/oracle_inventory"
export ORACLE_INVENTORY_HOME

# Group under which the software needs to be installed
ORACLE_INSTALL_GROUP="javainstall"
export ORACLE_INSTALL_GROUP

# Directory where the configuration will be placed
CONFIGURATION_HOME="${RUNTIME_HOME}/configuration"
export CONFIGURATION_HOME

Now, we have just one file that needs be edited before running an installation. When the InstallSoftwareService.sh script is run, the following output is observed

[osb@machine1 scripts]$ ./InstallSoftwareService.sh
CREATING SILENT INSTALL FILES
INSTALLING JAVA VIRTUAL MACHINE
Extracting 0%....................................................................................................100%
ADJUST ENTROPY GATHERING DEVICE SETTINGS
INSTALLING WEBLOGIC SERVER
Extracting 0%....................................................................................................100%
INSTALLING SERVICE BUS
Starting Oracle Universal Installer...

Checking if CPU speed is above 300 MHz.    Actual 2195 MHz    Passed
Checking Temp space: must be greater than 150 MB.   Actual 2341 MB    Passed
Checking swap space: must be greater than 512 MB.   Actual 8015 MB    Passed
Preparing to launch Oracle Universal Installer from /tmp/OraInstall2013-05-19_03-17-02PM. Please wait ...[osb@machine1 scripts]$ Log: /home/osb/oraInventory/logs/install2013-05-19_03-17-02PM.log
Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
Reading response file..
Expected result: One of oracle-6,oracle-5.6,enterprise-5.4,enterprise-4,enterprise-5,redhat-6.4,redhat-5.4,redhat-4,redhat-5,SuSE-10,SuSE-11
Actual Result: redhat-6.4
Check complete. The overall result of this check is: Passed
CertifiedVersions Check: Success.
Checking for binutils-2.20.51.0.2-5.11.el6-x86_64; found binutils-2.20.51.0.2-5.36.el6-x86_64.	Passed
Checking for compat-libcap1-1.10-1-x86_64; found compat-libcap1-1.10-1-x86_64.	Passed
Checking for compat-libstdc++-33-3.2.3-69.el6-x86_64; found compat-libstdc++-33-3.2.3-69.el6-x86_64.	Passed
Checking for compat-libstdc++-33-3.2.3-69.el6-i686; found compat-libstdc++-33-3.2.3-69.el6-i686.	Passed
Checking for libgcc-4.4.4-13.el6-i686; found libgcc-4.4.7-3.el6-i686.	Passed
Checking for libgcc-4.4.4-13.el6-x86_64; found libgcc-4.4.7-3.el6-x86_64.	Passed
Checking for libstdc++-4.4.4-13.el6-x86_64; found libstdc++-4.4.7-3.el6-x86_64.	Passed
Checking for libstdc++-4.4.4-13.el6-i686; found libstdc++-4.4.7-3.el6-i686.	Passed
Checking for libstdc++-devel-4.4.4-13.el6-x86_64; found libstdc++-devel-4.4.7-3.el6-x86_64.	Passed
Checking for sysstat-9.0.4-11.el6-x86_64; found sysstat-9.0.4-20.el6-x86_64.	Passed
Checking for gcc-4.4.4-13.el6-x86_64; found gcc-4.4.7-3.el6-x86_64.	Passed
Checking for gcc-c++-4.4.4-13.el6-x86_64; found gcc-c++-4.4.7-3.el6-x86_64.	Passed
Checking for glibc-2.12-1.7.el6-i686; found glibc-2.12-1.107.el6-i686.	Passed
Checking for glibc-2.12-1.7.el6-x86_64; found glibc-2.12-1.107.el6-x86_64.	Passed
Checking for glibc-devel-2.12-1.7.el6-x86_64; found glibc-devel-2.12-1.107.el6-x86_64.	Passed
Checking for glibc-devel-2.12-1.7.el6; found glibc-devel-2.12-1.107.el6-x86_64.	Passed
Checking for libaio-0.3.107-10.el6-x86_64; found libaio-0.3.107-10.el6-x86_64.	Passed
Checking for libaio-devel-0.3.107-10.el6-x86_64; found libaio-devel-0.3.107-10.el6-x86_64.	Passed
Check complete. The overall result of this check is: Passed
Packages Check: Success.
Checking for VERSION=2.6.32-279.19.1.el6; found VERSION=2.6.32-358.2.1.el6.x86_64.	Passed
Checking for hardnofiles=4096; found hardnofiles=8192.	Passed
Checking for softnofiles=4096; found softnofiles=8192.	Passed
Check complete. The overall result of this check is: Passed
Kernel Check: Success.
Expected result: ATLEAST=2.12-1.7.el6
Actual Result: 2.12-1.107.el6
Check complete. The overall result of this check is: Passed
GLIBC Check: Success.
Expected result: 1024MB
Actual Result: 3832MB
Check complete. The overall result of this check is: Passed
TotalMemory Check: Success.
Verifying data......
Copying Files...
-----------20%----------40%----------60%----------80%--------100%

The installation of Oracle AS Common Toplevel Component, Oracle Service Bus completed successfully.

We could refine the functions in the script, such that the software is copied, unzipped (when necessary), and deleted, for example,

unzip -q ${SOFTWARE_LOCATION}/ofm_osb_generic_11.1.1.6.0_disk1_1of1.zip -d ${SOFTWARE_DIRECTORY}/OSB
cp ${SOFTWARE_LOCATION}/refhost.xml ${SOFTWARE_DIRECTORY}/OSB/Disk1/stage/prereq/linux64
${SOFTWARE_DIRECTORY}/OSB/Disk1/runInstaller -silent -responsefile ${MIDDLEWARE_HOME}/scripts/installation/silent-service-bus.txt -jreLoc ${JAVA_HOME}
rm -Rf ${SOFTWARE_DIRECTORY}/OSB

Configuration

To configure a domain, we can use the following WLST script

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;

def createFile(directory_name, file_name, content):
	dedirectory = java.io.File(directory_name);
	defile = java.io.File(directory_name + '/' + file_name);

	writer = None;
	try:
		dedirectory.mkdirs();
		defile.createNewFile();
		writer = java.io.FileWriter(defile);
		writer.write(content);
	finally:
		try:
			print 'WRITING FILE ' + file_name;
			if writer != None:
				writer.flush();
				writer.close();
		except java.io.IOException, e:
			e.printStackTrace();

print 'CREATE PATHS';
java_home=os.getenv('JAVA_HOME');
middleware_home=os.getenv('MIDDLEWARE_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
fusion_middleware_home=os.getenv('FUSION_MIDDLEWARE_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');

domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=configuration_home + '/nodemanagers/' + domain_name;

weblogic_template=weblogic_home + '/common/templates/domains/wls.jar';
service_bus_template=fusion_middleware_home + '/common/templates/applications/wlsb.jar'
webservice_template=weblogic_home + '/common/templates/applications/wls_webservice.jar';
jrf_template=middleware_home + '/oracle_common/common/templates/applications/jrf_template_11.1.1.jar';
service_bus_owsm_template=fusion_middleware_home + '/common/templates/applications/wlsb_owsm.jar';
owsm_policy_manager_template=middleware_home + '/oracle_common/common/templates/applications/oracle.wsmpm_template_11.1.1.jar';
jrf_upgrade_template=middleware_home + '/oracle_common/common/templates/applications/jrf_uprade_template_11.1.1.4.0.jar';
em_template=middleware_home + '/oracle_common/common/templates/applications/oracle.em_11_1_1_0_0_template.jar';

print 'CREATE DOMAIN';
readTemplate(weblogic_template);
setOption('DomainName', domain_name);
setOption('OverwriteDomain', 'true');
setOption('JavaHome', java_home);
setOption('ServerStartMode', 'prod');
cd('/Security/base_domain/User/weblogic');
cmo.setName(admin_username);
cmo.setUserPassword(admin_password);
cd('/');

print "SAVE DOMAIN";
writeDomain(domain_home);
closeTemplate();

print 'READ DOMAIN';
readDomain(domain_home);

print 'ADD TEMPLATES';
addTemplate(service_bus_template);
# The next two templates are already selected by adding the service bus template
#addTemplate(webservice_template);
#addTemplate(jrf_template);
addTemplate(service_bus_owsm_template);
# The next template is already selected by adding the service bus owsm template
#addTemplate(owsm_policy_manager_template);
# When you want to use the fusion middleware enterprise manager uncomment the following two lines
#addTemplate(jrf_upgrade_template);
#addTemplate(em_template);
setOption('AppDir', domain_application_home);

print 'CREATE MACHINE';
machine = create('osb_machine1','UnixMachine');
machine.setPostBindUIDEnabled(true);
machine.setPostBindUID('osb');
machine.setPostBindGIDEnabled(true);
machine.setPostBindGID('javainstall');
cd('/Machine/osb_machine1');
nodemanager = create('osb_machine1','NodeManager');
nodemanager.setListenAddress('machine1.com');
nodemanager.setNMType('ssl');
cd('/');

print 'CREATE CLUSTER';
cluster = create('osb_cluster','Cluster');
cluster.setClusterMessagingMode('unicast');

print 'ADJUST MANAGED SERVER SETTINGS';
listen_port = 9001;
servers = cmo.getServers();
for server in servers:
	if server.getName() != 'AdminServer':
		server.setListenAddress('machine1.com');
		server.setListenPort(listen_port);
		server.setMachine(machine);
		cd('Servers/' + server.getName());
		serverstart = create(server.getName(),'ServerStart');
		serverstart.setJavaHome(java_home);
		serverstart.setJavaVendor('Oracle');
		serverstart.setArguments('-jrockit -Xms1024m -Xmx1024m -Xgc:throughput -XX:+UseCallProfiling -XX:+UseLargePagesForHeap');
		cd('/');
		listen_port = listen_port + 1;

print 'ADJUST DATA SOURCE SETTINGS';
database_username_prefix='DEV';
jdbcsystemresources = cmo.getJDBCSystemResources();
for jdbcsystemresource in jdbcsystemresources:
	cd ('/JDBCSystemResource/' + jdbcsystemresource.getName() + '/JdbcResource/' + jdbcsystemresource.getName() + '/JDBCConnectionPoolParams/NO_NAME_0');
	cmo.setTestTableName('SQL SELECT 1 FROM DUAL');
	cmo.setConnectionCreationRetryFrequencySeconds(100);
	cd ('/JDBCSystemResource/' + jdbcsystemresource.getName() + '/JdbcResource/' + jdbcsystemresource.getName() + '/JDBCDataSourceParams/NO_NAME_0');
	cmo.setGlobalTransactionsProtocol('EmulateTwoPhaseCommit');
	cd ('/JDBCSystemResource/' + jdbcsystemresource.getName() + '/JdbcResource/' + jdbcsystemresource.getName() + '/JDBCDriverParams/NO_NAME_0');
	cmo.setUrl('jdbc:oracle:thin:@//192.168.1.60:1521/orcl11');
	cmo.setDriverName('oracle.jdbc.OracleDriver');
	cmo.setPasswordEncrypted('magic11g');
	cd ('/JDBCSystemResource/' + jdbcsystemresource.getName() + '/JdbcResource/' + jdbcsystemresource.getName() + '/JDBCDriverParams/NO_NAME_0/Properties/NO_NAME_0/Property/user');
	cmo.setValue(cmo.getValue().replace('DEV',database_username_prefix));
	cd('/');

print 'ASSIGN SERVERS TO CLUSTER';
servers = cmo.getServers();
for server in servers:
	if server.getName() != 'AdminServer':
		assign('Server', server.getName(), 'Cluster', 'osb_cluster');

print 'ADJUST JMS DEPLOYMENT TO USE UNIFORM DISTRIBUTED QUEUES';
jmssystemresources = cmo.getJMSSystemResources();
for jmssystemresource in jmssystemresources:
	cd('/JMSSystemResource/' + jmssystemresource.getName());
	subdeployments = ls('SubDeployment', returnMap = 'true');
	for subdeployment in subdeployments:
		cd('SubDeployment/' + subdeployment);
		if 'jmsserver' in cmo.getName().lower():
			subdeploymentname = cmo.getName();
		cd('../..');
	cd('/JMSSystemResource/' + jmssystemresource.getName() + '/JmsResource/NO_NAME_0');
	distributedqueues = ls('DistributedQueue', returnMap = 'true');
	for distributedqueue in distributedqueues:
		cd('DistributedQueue/' + distributedqueue);
		name = cmo.getName();
		jndiname = cmo.getJNDIName();
		cd('../..');
		delete(name, 'DistributedQueue');
		uniformdistributedqueue = create(name, 'UniformDistributedQueue');
		uniformdistributedqueue.setJNDIName(jndiname);
		uniformdistributedqueue.setSubDeploymentName(subdeploymentname);

print "SET NODE MANAGER CREDENTIALS";
cd("/SecurityConfiguration/" + domain_name);
cmo.setNodeManagerUsername(node_manager_username);
cmo.setNodeManagerPasswordEncrypted(node_manager_password);
print "DISABLE HOSTNAME VERIFICATION";
cd('/Server/AdminServer');
create('AdminServer','SSL');
cd('SSL/AdminServer');
cmo.setHostnameVerificationIgnored(true);
cmo.setHostnameVerifier(None);
cmo.setTwoWaySSLEnabled(false);
cmo.setClientCertificateEnforced(false);

print 'SAVE CHANGES';
updateDomain();
closeDomain();

print 'CREATE FILES';
directory_name = domain_home + '/servers/AdminServer/security';
file_name = 'boot.properties';
content = 'username=' + admin_username + '\npassword=' + admin_password;
createFile(directory_name, file_name, content);

directory_name = domain_application_home;
file_name = 'readme.txt';
content = 'This directory contains deployment files and deployment plans.\nTo set-up a deployment, create a directory with the name of the application.\nSubsequently, create two sub-directories called app and plan.\nThe app directory contains the deployment artifact.\nThe plan directory contains the deployment plan.';
createFile(directory_name, file_name, content);

#directory_name = node_manager_home;
#file_name = 'nodemanager.domains';
#content=domain_name + '=' + domain_home;
#createFile(directory_name, file_name, content);

directory_name = node_manager_home;
file_name = 'nodemanager.properties';
content='DomainsFile=' + node_manager_home + '/nodemanager.domains\nLogLimit=0\nPropertiesVersion=10.3\nDomainsDirRemoteSharingEnabled=false\njavaHome=' + java_home + '\nAuthenticationEnabled=true\nNodeManagerHome=' + node_manager_home + '\nJavaHome=' + java_home + '/jre\nLogLevel=INFO\nDomainsFileEnabled=true\nStartScriptName=startWebLogic.sh \nListenAddress=\nNativeVersionEnabled=true\nListenPort=5556\nLogToStderr=true\nSecureListener=true\nLogCount=1\nDomainRegistrationEnabled=false\nStopScriptEnabled=false\nQuitEnabled=false\nLogAppend=true\nStateCheckInterval=500\nCrashRecoveryEnabled=false\nStartScriptEnabled=true\nLogFile=' + node_manager_home + '/nodemanager.log\nLogFormatter=weblogic.nodemanager.server.LogFormatter\nListenBacklog=50';
createFile(directory_name, file_name, content);

which can be run by using

#!/bin/sh

SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/SetEnvironmentVariables.sh

create_domain() {
	${FUSION_MIDDLEWARE_HOME}/common/bin/wlst.sh -loadProperties ${SCRIPT_PATH}/environment.properties ${SCRIPT_PATH}/create_environment.py
}

change_admin_server_memory_settings() {
	sed '/export WL_HOME/ a\\nif [ "${ADMIN_URL}" = "" ] ; then\n	USER_MEM_ARGS="-Xms1024m -Xmx1024m -Xns256m -Xgc:pausetime -XpauseTarget=500ms"\n	export USER_MEM_ARGS\nfi' ${CONFIGURATION_HOME}/domains/osb_domain/bin/setDomainEnv.sh > ${SCRIPT_PATH}/setDomainEnv.sh
	mv ${SCRIPT_PATH}/setDomainEnv.sh ${CONFIGURATION_HOME}/domains/osb_domain/bin/setDomainEnv.sh
}

create_domain

change_admin_server_memory_settings

The environment.properties file has the following contents

domain_name=osb_domain
node_manager_username=nodemanager
node_manager_password=magic11g
node_manager_listen_port=5556
admin_server_name=AdminServer
admin_username=weblogic
admin_password=magic11g
admin_server_listen_port=7001

When the configuration script is run the following output is observed

[osb@machine1 scripts]$ ./CreateEnvironmentService.sh 

CLASSPATH=/home/osb/osb11.1.1.6/installation/patch_wls1036/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/osb/osb11.1.1.6/installation/patch_ocp371/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/osb/osb11.1.1.6/jrockit-jdk1.6.0_37/lib/tools.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/server/lib/weblogic_sp.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/server/lib/weblogic.jar:/home/osb/osb11.1.1.6/installation/modules/features/weblogic.server.modules_10.3.6.0.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/server/lib/webservices.jar:/home/osb/osb11.1.1.6/installation/modules/org.apache.ant_1.7.1/lib/ant-all.jar:/home/osb/osb11.1.1.6/installation/modules/net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar::/home/osb/osb11.1.1.6/installation/oracle_common/modules/oracle.jrf_11.1.1/jrf-wlstman.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/lib/adfscripting.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/lib/adf-share-mbeans-wlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/lib/mdswlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/auditwlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/igfwlsthelp.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/jps-wlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/jrf-wlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/oamap_help.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/oamAuthnProvider.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/ossoiap_help.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/ossoiap.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/ovdwlsthelp.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/sslconfigwlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/wsm-wlst.jar:/home/osb/osb11.1.1.6/installation/utils/config/10.3/config-launch.jar::/home/osb/osb11.1.1.6/installation/wlserver_10.3/common/derby/lib/derbynet.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/common/derby/lib/derbyclient.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/common/derby/lib/derbytools.jar::

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

CREATE PATHS
CREATE DOMAIN
SAVE DOMAIN
READ DOMAIN
ADD TEMPLATES
CREATE MACHINE
CREATE CLUSTER
ADJUST MANAGED SERVER SETTINGS
ADJUST DATA SOURCE SETTINGS
ASSIGN SERVERS TO CLUSTER
ADJUST JMS DEPLOYMENT TO USE UNIFORM DISTRIBUTED QUEUES
drw-   WseeJmsServer508465802
drw-   dist_WseeMessageQueue_auto
drw-   dist_WseeCallbackQueue_auto
drw-   weblogic.wlsb.jms.transporttask.QueueConnectionFactory
drw-   wlsbJMSServer509231833
drw-   dist_wlsb.internal.transport.task.queue.ftp_auto
drw-   dist_wlsb.internal.transport.task.queue.sftp_auto
drw-   dist_wlsb.internal.transport.task.queue.email_auto
drw-   dist_wlsb.internal.transport.task.queue.file_auto
drw-   dist_QueueIn_auto
drw-   dist_wli.reporting.jmsprovider.queue_auto
drw-   dist_wli.reporting.jmsprovider_error.queue_auto
drw-   dist_wli.reporting.purge.queue_auto
SET NODE MANAGER CREDENTIALS
DISABLE HOSTNAME VERIFICATION
SAVE CHANGES
CREATE FILES
WRITING FILE boot.properties
WRITING FILE readme.txt
WRITING FILE nodemanager.properties

Next, the node manager must be enrolled. This can be accomplished by using the following WLST script

import socket;
admin_server_listen_address = socket.gethostname();
admin_server_url = 't3://' + admin_server_listen_address + ':' + admin_server_listen_port;

print 'CREATE PATHS';
java_home=os.getenv('JAVA_HOME');
installation_home=os.getenv('INSTALLATION_HOME');
weblogic_home=os.getenv('WEBLOGIC_HOME');
osb_home=os.getenv('OSB_HOME');
configuration_home = os.getenv('CONFIGURATION_HOME');

domain_home=configuration_home + '/domains/' + domain_name;
domain_application_home=configuration_home + '/applications/' + domain_name;
node_manager_home=configuration_home + '/nodemanagers/' + domain_name;

print 'START ADMIN SERVER AND DO NOT WORRY ABOUT THE EXCEPTIONS';
startServer(admin_server_name, domain_name, admin_server_url, admin_username, admin_password, domain_home);

print 'CONNECT TO ADMIN SERVER';
connect(admin_username, admin_password, admin_server_url);

print 'ENROLL NODE MANAGER AND CREATE NODEMANAGER.DOMAINS';
nmEnroll(domain_home,node_manager_home);

print 'SHUTDOWN ADMIN SERVER';
shutdown('AdminServer','Server','true',1000,'true');

which can be run by using

#!/bin/sh

SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/SetEnvironmentVariables.sh

${FUSION_MIDDLEWARE_HOME}/common/bin/wlst.sh -loadProperties ${SCRIPT_PATH}/environment.properties ${SCRIPT_PATH}/enroll_node_manager.py

When this script is run the following output is observed

CLASSPATH=/home/osb/osb11.1.1.6/installation/patch_wls1036/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/osb/osb11.1.1.6/installation/patch_ocp371/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/osb/jrockit-jdk1.6.0_37-R28.2.5-4.1.0/lib/tools.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/server/lib/weblogic_sp.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/server/lib/weblogic.jar:/home/osb/osb11.1.1.6/installation/modules/features/weblogic.server.modules_10.3.6.0.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/server/lib/webservices.jar:/home/osb/osb11.1.1.6/installation/modules/org.apache.ant_1.7.1/lib/ant-all.jar:/home/osb/osb11.1.1.6/installation/modules/net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar::/home/osb/osb11.1.1.6/installation/oracle_common/modules/oracle.jrf_11.1.1/jrf-wlstman.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/lib/adfscripting.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/lib/adf-share-mbeans-wlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/lib/mdswlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/auditwlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/igfwlsthelp.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/jps-wlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/jrf-wlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/oamap_help.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/oamAuthnProvider.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/ossoiap_help.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/ossoiap.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/ovdwlsthelp.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/sslconfigwlst.jar:/home/osb/osb11.1.1.6/installation/oracle_common/common/wlst/resources/wsm-wlst.jar:/home/osb/osb11.1.1.6/installation/utils/config/10.3/config-launch.jar::/home/osb/osb11.1.1.6/installation/wlserver_10.3/common/derby/lib/derbynet.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/common/derby/lib/derbyclient.jar:/home/osb/osb11.1.1.6/installation/wlserver_10.3/common/derby/lib/derbytools.jar::

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

START ADMIN SERVER AND DO NOT WORRY ABOUT THE EXCEPTIONS
...
WLST-WLS-1358848073802: <Jan 22, 2013 10:49:05 AM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to RUNNING>
WLST-WLS-1358848073802: <Jan 22, 2013 10:49:05 AM CET> <Notice> <WebLogicServer> <BEA-000360> <Server started in RUNNING mode>
Server started successfully.
Server started successfully.
CONNECT TO ADMIN SERVER
Connecting to t3://machine1.com:7001 with userid weblogic ...
Successfully connected to Admin Server 'AdminServer' that belongs to domain 'osb_domain'.

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

ENROLL NODE MANAGER AND CREATE NODEMANAGER.DOMAINS
Enrolling this machine with the domain directory at /home/osb/osb11.1.1.6/configuration/domains/osb_domain ...
Successfully enrolled this machine with the domain directory at /home/osb/osb11.1.1.6/configuration/domains/osb_domain.
SHUTDOWN ADMIN SERVER
Shutting down the server AdminServer with force=true while connected to AdminServer ...
...
WLST-WLS-1358848073802: <Jan 22, 2013 10:49:11 AM CET> <Notice> <WebLogicServer> <BEA-000365> <Server state changed to FORCE_SHUTTING_DOWN>
...
WLST-WLS-1358848073802: <Jan 22, 2013 10:49:11 AM CET> <Notice> <Server> <BEA-002607> <Channel "Default" listening on 192.168.1.155:7001 was shutdown.>
...
WLST lost connection to the WebLogic Server that you were
connected to, this may happen if the server was shutdown or
partitioned. You will have to re-connect to the server once the
server is available.
Disconnected from weblogic server: AdminServer
Disconnected from weblogic server:

Enrolling the node manager is to prevent the java.io.IOException: Read did not get bytes, but bytes are available. Another vague exception weblogic.ldap.EmbeddedLDAPException: Unable to open initial replica url can be prevented by making sure the hostnames between machines, managed servers and confgured host files and DNS correspond.

Lifecycle

Start and stop scripts are presented in the WLST Starting and Stopping a WebLogic Environment post.

References

[1] Installation Guide for Oracle Service Bus.
[2] Repository Creation Utility User’s Guide.


Free JBoss AS7 (EAP 6) Course

In the vain of its creator (Red Hat): “… we gain the most when we share. It is core to our business and our development models.” As a result, we are bringing you a free course on JBoss AS 7 (EAP 6). In the course you will learn the following:

  • Introduction
    • JBoss Application Server architecture (standalone, process controller, host controller, domain)
    • JBoss Application Server internal architecture (listen threads, threads pools, containers)
    • Standalone configuration
    • Command-line utility
    • Admin console
  • JVM Tuning
    • Code generation
    • Memory management
    • Garbage collection performance
    • JConsole and JVisualVM
  • Deployment
    • Packaging applications recommendations
    • Deployment descriptors
    • Server logging
    • Front-end configuration using the Apache HTTP Server and mod_jk
  • Class Loading
    • Modules
  • Security
    • JAAS introduction
    • Role-based security
    • Secure communications (SSL and TLS)
  • Configure Resources
    • Domain configuration
    • Configure data sources
    • Monitoring resources
    • Configure JMS environment
  • Clustering
    • Unicast or multicast?
    • Denial of service configuration
    • Vertical and horizontal scaling
    • Caching
    • Apache HTTP Server and mod_cluster
    • Load balancing
    • Load testing

Note that this is a course you can do at your own pace. The exercises lead you step-by-step through the process of installing, configuring, deploying etcetera. The material consists of the following:

Have fun!


Coherence and WebLogic

In this post, we configure WebLogic and an in-memory data grid, such as Coherence and present scripts to start and stop the environment. We start with creating a Coherence Server (which will be our storage enabled node in the cluster). The steps to create a Coherence Server are provided here. When the server is created, click on the created server and subsequently on the server start, configuration tab, in order to set the class path and some JVM parameters. Enter the following properties:

  • Java Home: Specify the location of the JDK installation directory such that /bin/java exists, in our example we will use /home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0
  • Java Vendor: Oracle
  • Class Path: /home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar: /home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules.coherence.server_12.1.1.0.jar: /home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar
  • Arguments: -jrockit -Xms256m -Xmx256m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200m -XX:+UseCallProfiling -XX:+UseLargePagesForHeap -Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true

Above, we have specified the class path to included coherence.jar and weblogic.server.modules.coherence.server_12.1.1.0.jar, which are needed to make Coherence available. The test.jar contains our Coherence configuration and serializable classes. These are presented in the post JBoss RichFaces, Facelets and Coherence on WebLogic.

Note that the JVM parameters also included Coherence system settings, such as, -Dtangosol.coherence.mode=prod and -Dtangosol.coherence.cacheconfig=security-cache-config.xml. With the first one, we tell Coherence to run with production settings. The second one defines the cache configuration file to use. Unfortunately, the configuration provided in a Coherence override is not picked up.

<?xml version='1.0'?>
<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"       xsi:schemaLocation="http://xmlns.oracle.com/coherence/coherence-operational-config coherence-operational-config.xsd">
    <cluster-config>
        <member-identity>
            <cluster-name system-property="tangosol.coherence.cluster">SecurityCoherenceCluster</cluster-name>
        </member-identity>
        <unicast-listener>
            <well-known-addresses>
                <socket-address id="1">
                    <address>192.168.1.150</address>
                    <port>8088</port>
                </socket-address>
            </well-known-addresses>
        </unicast-listener>
    </cluster-config>
    <configurable-cache-factory-config>
        <class-name>com.tangosol.net.DefaultConfigurableCacheFactory</class-name>
        <init-params>
            <init-param>
                <param-type>java.lang.String</param-type>
                <param-value system-property="tangosol.coherence.cacheconfig">security-cache-config.xml</param-value>
            </init-param>
        </init-params>
    </configurable-cache-factory-config>
    <license-config>
        <license-mode system-property="tangosol.coherence.mode">prod</license-mode>
    </license-config>
</coherence>

But the well-known-address definition is (as we will shortly see when the server is started).

With the Coherence Server in place, something like the following should be present in the WebLogic configuration file (config.xml)

<coherence-server>
    <name>coherence-server1</name>
    <machine>machine1</machine>
    <coherence-cluster-system-resource xsi:nil="true"></coherence-cluster-system-resource>
    <unicast-listen-address>localhost</unicast-listen-address>
    <unicast-listen-port>8088</unicast-listen-port>
    <unicast-port-auto-adjust>true</unicast-port-auto-adjust>
    <coherence-server-start>
		<java-vendor>Oracle</java-vendor>
		<java-home>/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0</java-home>
		<class-path>/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules.coherence.server_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar</class-path>
		<arguments>-jrockit -Xms256m -Xmx256m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200m -XX:+UseCallProfiling -XX:+UseLargePagesForHeap -Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true</arguments>
    </coherence-server-start>
</coherence-server>

Before, we can start the Coherence Server, the node manager must be running (examples of stop and start scripts for the node manager can be found in the post WLST Starting and Stopping a WebLogic Environment). When the node manager is running, in the WebLogic admin console, click in the created server, click the control tab, select the Coherence Server and click start.

The output log is present in the ${DOMAIN_HOME}/servers_coherence/${COHERENCE_SERVER_NAME}/logs

<Jan 9, 2013 11:37:08 AM> <INFO> <NodeManager> <Starting Coherence server with command line: /home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0/bin/java -Dtangosol.coherence.member=coherence-server1 -Dtangosol.coherence.localport=8088 -Dtangosol.coherence.localhost=localhost -Djava.class.path=/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules.coherence.server_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar -jrockit -Xms256m -Xmx256m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200m -XX:+UseCallProfiling -XX:+UseLargePagesForHeap -Dtangosol.coherence.mode=prod -Dtangosol.coherence.cacheconfig=security-cache-config.xml -Dtangosol.coherence.management=all -Dtangosol.coherence.management.remote=true -Dweblogic.RootDirectory=/home/weblogic/weblogic12.1.1/configuration/domains/base_domain weblogic.nodemanager.server.provider.WeblogicCacheServer >
<Jan 9, 2013 11:37:08 AM> <INFO> <NodeManager> <Working directory is '/home/weblogic/weblogic12.1.1/configuration/domains/base_domain'>
<Jan 9, 2013 11:37:08 AM> <INFO> <NodeManager> <Server output log file is '/home/weblogic/weblogic12.1.1/configuration/domains/base_domain/servers_coherence/coherence-server1/logs/coherence-server1.out'>
2013-01-09 11:37:09.756/1.432 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence.xml"
2013-01-09 11:37:09.785/1.460 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational overrides from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/tangosol-coherence-override-prod.xml"
2013-01-09 11:37:09.803/1.478 Oracle Coherence 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded operational overrides from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/tangosol-coherence-override.xml"
2013-01-09 11:37:09.809/1.484 Oracle Coherence 3.7.1.1 <D5> (thread=Main Thread, member=n/a): Optional configuration override "/custom-mbeans.xml" is not specified

Oracle Coherence Version 3.7.1.1 Build 28901
 Grid Edition: Production mode
Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

2013-01-09 11:37:10.679/2.354 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Loaded Reporter configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/reports/report-group.xml"
2013-01-09 11:37:11.456/3.131 Oracle Coherence GE 3.7.1.1 <D4> (thread=Main Thread, member=n/a): TCMP bound to /192.168.1.150:8088 using SystemSocketProvider
2013-01-09 11:37:42.014/33.689 Oracle Coherence GE 3.7.1.1 <Info> (thread=Cluster, member=n/a): Created a new cluster "SecurityCoherenceCluster" with Member(Id=1, Timestamp=2013-01-09 11:37:11.526, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:5877,member:coherence-server1, Role=WeblogicWeblogicCacheServer, Edition=Grid Edition, Mode=Production, CpuCount=4, SocketCount=1) UID=0xC0A801960000013C1EE295E6FE391F98
2013-01-09 11:37:42.065/33.740 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=n/a): Started cluster Name=SecurityCoherenceCluster

WellKnownAddressList(Size=1,
  WKA{Address=192.168.1.150, Port=8088}
  )

MasterMemberSet(
  ThisMember=Member(Id=1, Timestamp=2013-01-09 11:37:11.526, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:5877,member:coherence-server1, Role=WeblogicWeblogicCacheServer)
  OldestMember=Member(Id=1, Timestamp=2013-01-09 11:37:11.526, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:5877,member:coherence-server1, Role=WeblogicWeblogicCacheServer)
  ActualMemberSet=MemberSet(Size=1
    Member(Id=1, Timestamp=2013-01-09 11:37:11.526, Address=192.168.1.150:8088, MachineId=65081, Location=site:,machine:middleware-magic,process:5877,member:coherence-server1, Role=WeblogicWeblogicCacheServer)
    )
  MemberId|ServiceVersion|ServiceJoined|MemberState
    1|3.7.1|2013-01-09 11:37:42.019|JOINED
  RecycleMillis=1200000
  RecycleSet=MemberSet(Size=0
    )
  )

TcpRing{Connections=[]}
IpMonitor{AddressListSize=0}

2013-01-09 11:37:42.195/33.870 Oracle Coherence GE 3.7.1.1 <D5> (thread=Invocation:Management, member=1): Service Management joined the cluster with senior service member 1
2013-01-09 11:37:42.428/34.103 Oracle Coherence GE 3.7.1.1 <Info> (thread=DistributedCache, member=1): Loaded POF configuration from "jar:file:/home/weblogic/weblogic12.1.1/configuration/applications/base_domain/security/test.jar!/security-pof-config.xml"
2013-01-09 11:37:42.436/34.111 Oracle Coherence GE 3.7.1.1 <Info> (thread=DistributedCache, member=1): Loaded included POF configuration from "jar:file:/home/weblogic/weblogic12.1.1/installation/coherence_3.7/lib/coherence.jar!/coherence-pof-config.xml"
2013-01-09 11:37:42.545/34.220 Oracle Coherence GE 3.7.1.1 <D5> (thread=DistributedCache, member=1): Service DistributedCache joined the cluster with senior service member 1
2013-01-09 11:37:42.627/34.302 Oracle Coherence GE 3.7.1.1 <Info> (thread=Main Thread, member=1):
Services
  (
  ClusterService{Name=Cluster, State=(SERVICE_STARTED, STATE_JOINED), Id=0, Version=3.7.1, OldestMemberId=1}
  InvocationService{Name=Management, State=(SERVICE_STARTED), Id=1, Version=3.1, OldestMemberId=1}
  PartitionedCache{Name=DistributedCache, State=(SERVICE_STARTED), LocalStorage=enabled, PartitionCount=257, BackupCount=1, AssignedPartitions=257, BackupPartitions=0}
  )

Started DefaultCacheServer...

The application (presented in the post JBoss RichFaces, Facelets and Coherence on WebLogic, which also includes details on how to create shared libraries) will be deployed on a WebLogic managed server with the following settings

<server>
    <name>security-server</name>
    <ssl>
		<enabled>false</enabled>
    </ssl>
    <machine>machine1</machine>
    <listen-port>8001</listen-port>
    <cluster xsi:nil="true"></cluster>
    <web-server>
		<web-server-log>
			<number-of-files-limited>false</number-of-files-limited>
		</web-server-log>
    </web-server>
    <listen-address>middleware-magic.com</listen-address>
    <server-start>
		<java-vendor>Oracle</java-vendor>
		<java-home>/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0</java-home>
		<arguments>-jrockit -Xms512m -Xmx512m -Xns128m -XXkeepAreaRatio:25 -Xgc:pausetime -XpauseTarget:200ms -XX:+UseCallProfiling -XX:+UseLargePagesForHeap -Dtangosol.coherence.mode=prod -Dtangosol.coherence.distributed.localstorage=false</arguments>
    </server-start>
</server>

Note that this server has the storage disabled (-Dtangosol.coherence.distributed.localstorage=false). The cache configuration is set here by using a Coherence override as was present above. When the WebLogic server and the application are started, the following is observed in the Coherence Server logging

2013-01-09 11:44:19.563/431.240 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member(Id=2, Timestamp=2013-01-09 11:44:19.326, Address=192.168.1.150:8090, MachineId=65081, Location=site:,machine:middleware-magic,process:3852, Role=WeblogicServer) joined Cluster with senior member 1
2013-01-09 11:44:19.658/431.334 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service Management with senior member 1
2013-01-09 11:44:19.710/431.385 Oracle Coherence GE 3.7.1.1 <D5> (thread=Cluster, member=1): Member 2 joined Service DistributedCache with senior member 1

To monitor the Coherence cache server, we have added -Dtangosol.coherence.management=all and -Dtangosol.coherence.management.remote=true as JVM parameters. By using an MBean browser (for example, JRockit Mission Control), we get an idea what is going on in the server

In order to start and stop the Coherence cache servers we can use WLST. The CoherenceServerLifeCycleRuntimeMBean provides methods that transition servers from one state to another. This class is instantiated only on the Admin Server, but we can use it to transition the states of all managed Coherence cache servers. To start Coherence cache servers, we must first configure a Node Manager on each Coherence cache server’s host machine. In order to start Coherence cache servers we can use the following script:

import socket;
admin_server_listen_address = socket.gethostname();
admin_server_url = 't3://' + admin_server_listen_address + ':' + admin_server_listen_port;

print 'CONNECT TO ADMIN SERVER';

connect(admin_username, admin_password, admin_server_url);

domainRuntime();
coherence_server_lifecycles = cmo.getCoherenceServerLifeCycleRuntimes();

for coherence_server_lifecycle in coherence_server_lifecycles:
	if (coherence_server_lifecycle.getState() != 'RUNNING'):
		print 'START COHERENCE SERVER ' + coherence_server_lifecycle.getName();
		task = coherence_server_lifecycle.start();
		while (task.isRunning() == 1):
			print 'STARTING COHERENCE SERVER ' + coherence_server_lifecycle.getName();
			java.lang.Thread.sleep(2000);

print 'DISCONNECT FROM THE ADMIN SERVER';
disconnect();

and the following bash script

#!/bin/sh

# SCRIPT_PATH=$(dirname $0)
SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/SetEnvironment.sh

${WL_HOME}/common/bin/wlst.sh -loadProperties ${SCRIPT_PATH}/environment.properties ${SCRIPT_PATH}/startCoherence.py

When this script is run the following output is observed

[weblogic@middleware-magic scripts]$ ./CoherenceStartService.sh 

CLASSPATH=/home/weblogic/weblogic12.1.1/installation/patch_wls1211/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/weblogic/weblogic12.1.1/installation/patch_ocp371/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0/lib/tools.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/server/lib/weblogic_sp.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/server/lib/weblogic.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/server/lib/webservices.jar:/home/weblogic/weblogic12.1.1/installation/modules/org.apache.ant_1.7.1/lib/ant-all.jar:/home/weblogic/weblogic12.1.1/installation/modules/net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar::/home/weblogic/weblogic12.1.1/installation/utils/config/10.3/config-launch.jar::/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbynet.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbyclient.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbytools.jar::

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

CONNECT TO ADMIN SERVER
Connecting to t3://middleware-magic.com:7001 with userid weblogic ...
Successfully connected to Admin Server 'AdminServer' that belongs to domain 'base_domain'.

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

Location changed to domainRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help(domainRuntime)

START COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
STARTING COHERENCE SERVER coherence-server1
DISCONNECT FROM THE ADMIN SERVER
Disconnected from weblogic server: AdminServer

To stop Coherence cache servers we can use

import socket;
admin_server_listen_address = socket.gethostname();
admin_server_url = 't3://' + admin_server_listen_address + ':' + admin_server_listen_port;

print 'CONNECT TO ADMIN SERVER';

connect(admin_username, admin_password, admin_server_url);

domainRuntime();
coherence_server_lifecycles = cmo.getCoherenceServerLifeCycleRuntimes();

for coherence_server_lifecycle in coherence_server_lifecycles:
	if (coherence_server_lifecycle.getState() == 'RUNNING'):
		print 'SHUT DOWN COHERENCE SERVER ' + coherence_server_lifecycle.getName();
		task = coherence_server_lifecycle.forceShutdown();
		while (task.isRunning() == 1):
			print 'SHUTTING DOWN COHERENCE SERVER ' + coherence_server_lifecycle.getName();
			java.lang.Thread.sleep(2000);

print 'DISCONNECT FROM THE ADMIN SERVER';
disconnect();

with the following bash script

#!/bin/sh

# SCRIPT_PATH=$(dirname $0)
SCRIPT=$(readlink -f $0)
SCRIPT_PATH=$(dirname $SCRIPT)

. ${SCRIPT_PATH}/SetEnvironment.sh

${WL_HOME}/common/bin/wlst.sh -loadProperties ${SCRIPT_PATH}/environment.properties ${SCRIPT_PATH}/stopCoherence.py

When this script is run the following output is observed

[weblogic@middleware-magic scripts]$ ./CoherenceStopService.sh 

CLASSPATH=/home/weblogic/weblogic12.1.1/installation/patch_wls1211/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/weblogic/weblogic12.1.1/installation/patch_ocp371/profiles/default/sys_manifest_classpath/weblogic_patch.jar:/home/weblogic/jrockit-jdk1.6.0_29-R28.2.2-4.1.0/lib/tools.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/server/lib/weblogic_sp.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/server/lib/weblogic.jar:/home/weblogic/weblogic12.1.1/installation/modules/features/weblogic.server.modules_12.1.1.0.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/server/lib/webservices.jar:/home/weblogic/weblogic12.1.1/installation/modules/org.apache.ant_1.7.1/lib/ant-all.jar:/home/weblogic/weblogic12.1.1/installation/modules/net.sf.antcontrib_1.1.0.0_1-0b2/lib/ant-contrib.jar::/home/weblogic/weblogic12.1.1/installation/utils/config/10.3/config-launch.jar::/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbynet.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbyclient.jar:/home/weblogic/weblogic12.1.1/installation/wlserver_12.1/common/derby/lib/derbytools.jar::

Initializing WebLogic Scripting Tool (WLST) ...

Welcome to WebLogic Server Administration Scripting Shell

Type help() for help on available commands

CONNECT TO ADMIN SERVER
Connecting to t3://middleware-magic.com:7001 with userid weblogic ...
Successfully connected to Admin Server 'AdminServer' that belongs to domain 'base_domain'.

Warning: An insecure protocol was used to connect to the
server. To ensure on-the-wire security, the SSL port or
Admin port should be used instead.

Location changed to domainRuntime tree. This is a read-only tree with DomainMBean as the root.
For more help, use help(domainRuntime)

SHUT DOWN COHERENCE SERVER coherence-server1
SHUTTING DOWN COHERENCE SERVER coherence-server1
DISCONNECT FROM THE ADMIN SERVER
Disconnected from weblogic server: AdminServer

This is certainly a step in the right direction to integrate data-grids with application servers. Some more information on where it is going have a look at the Coherence Roadmap, or what do you think about this one: Grid Archive.

References

[1] Using ActiveCache.


Bridging JMS HornetQ to JBossAS7

In this post we are going to set-up a (JMS) bridge in order to forward messages from a stand-alone HornetQ Server to JBoss AS7. We end the post by looking at the performance, such as Operating System and JVM tuning, and make a suggestion in chosing a Java Virtual Machine when dealing with very large heaps (> 100GB).

Set-up HornetQ

HornetQ distributions can be obtained here. In the examples we will work with the 2.2.14.Final distribution. To install HornetQ just unzip the downloaded distribution. Let us start with a basic HornetQ set-up and create a connection factory and a queue. Open the hornetq-jms.xml (located in the ${HORNETQ_HOME}/config/stand-alone/non-clustered directory) and add the following

<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hornetq /schema/hornetq-jms.xsd">
	<connection-factory name="SomeConnectionFactory">
		<xa>false</xa>
		<connectors>
			<connector-ref connector-name="netty"/>
		</connectors>
		<entries>
			<entry name="jms/SomeConnectionFactory"/>
		</entries>
	</connection-factory>

	<queue name="SomeQueue">
		<entry name="jms/queue/SomeQueue"/>
	</queue>
</configuration>

The connectors are defined in the hornetq-configuration.xml file, i.e.,

<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hornetq /schema/hornetq-configuration.xsd">

	<security-enabled>false</security-enabled>
	<cluster-user>employee</cluster-user>
	<cluster-password>welcome1</cluster-password>

	<connectors>
		<connector name="netty">
			<factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
			<param key="host"  value="${hornetq.remoting.netty.host:middleware-magic.com}"/>
			<param key="port"  value="${hornetq.remoting.netty.port:4445}"/>
		</connector>
		<connector name="netty-throughput">
			<factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
			<param key="host"  value="${hornetq.remoting.netty.host:middleware-magic.com}"/>
			<param key="port"  value="${hornetq.remoting.netty.batch.port:4455}"/>
			<param key="batch-delay" value="50"/>
		</connector>
	</connectors>

	<acceptors>
		<acceptor name="netty">
			<factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
			<param key="host"  value="${hornetq.remoting.netty.host:middleware-magic.com}"/>
			<param key="port"  value="${hornetq.remoting.netty.port:4445}"/>
		</acceptor>
		<acceptor name="netty-throughput">
			<factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
			<param key="host"  value="${hornetq.remoting.netty.host:middleware-magic.com}"/>
			<param key="port"  value="${hornetq.remoting.netty.batch.port:4455}"/>
			<param key="batch-delay" value="50"/>
			<param key="direct-deliver" value="false"/>
		</acceptor>
	</acceptors>

	<security-settings>
		<security-setting match="#">
			<permission type="createNonDurableQueue" roles="guest"/>
			<permission type="deleteNonDurableQueue" roles="guest"/>
			<permission type="consume" roles="guest"/>
			<permission type="send" roles="guest"/>
		</security-setting>
	</security-settings>

	<address-settings>
		<address-setting match="#">
			<dead-letter-address>jms.queue.DLQ</dead-letter-address>
			<expiry-address>jms.queue.ExpiryQueue</expiry-address>
			<redelivery-delay>0</redelivery-delay>
			<max-size-bytes>10485760</max-size-bytes>
			<message-counter-history-day-limit>10</message-counter-history-day-limit>
			<address-full-policy>BLOCK</address-full-policy>
		</address-setting>
	</address-settings>

</configuration>

Apart from the addition of the security-enabled, cluster-user and cluster-password elements and the host and port settings, all is present by default. Next, we are going to define a different user. In order to do this open the hornetq-user.xml and add the following

<configuration xmlns="urn:hornetq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:hornetq /schema/hornetq-users.xsd">
	<!-- the default user.  this is used where username is null-->
	<defaultuser name="employee" password="welcome1">
		<role name="guest"/>
	</defaultuser>
</configuration>

Start the HornetQ Server by running run.sh (located in the ${HORNETQ_HOME}/bin directory. Before we can execute run.sh, we have to make sure it points to the right JAVA_HOME, for example, open run.sh and add the following lines

#!/bin/sh

export JAVA_HOME=/home/jboss/jdk1.6.0_31
export PATH=${JAVA_HOME}/bin:${PATH}

With everything in place we can start the HornetQ Server

[jboss@middleware-magic bin]$ ./run.sh
***********************************************************************************
java  -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M -Dhornetq.config.dir=../config/stand-alone/non-clustered -Djava.util.logging.config.file=../config/stand-alone/non-clustered/logging.properties -Djava.library.path=. -classpath ../lib/twitter4j-core.jar:../lib/netty.jar:../lib/log4j.jar:../lib/jnpserver.jar:../lib/jnp-client.jar:../lib/jbossts-common.jar:../lib/jboss-mc.jar:../lib/jbossjta.jar:../lib/jboss-jms-api.jar:../lib/jboss-javaee.jar:../lib/jboss-client-7.1.0.Final.jar:../lib/hornetq-twitter-integration.jar:../lib/hornetq-spring-integration.jar:../lib/hornetq-logging.jar:../lib/hornetq-jms.jar:../lib/hornetq-jms-client-java5.jar:../lib/hornetq-jms-client.jar:../lib/hornetq-jboss-as-integration.jar:../lib/hornetq-core.jar:../lib/hornetq-core-client-java5.jar:../lib/hornetq-core-client.jar:../lib/hornetq-bootstrap.jar:../lib/commons-logging.jar:../config/stand-alone/non-clustered:../schemas/ org.hornetq.integration.bootstrap.HornetQBootstrapServer hornetq-beans.xml
***********************************************************************************
* [main] 28-Nov 11:7:50,967 INFO [HornetQBootstrapServer]  Starting HornetQ Server
* [main] 28-Nov 11:7:51,753 INFO [HornetQServerImpl]  live server is starting with configuration HornetQ Configuration (clustered=false,backup=false,sharedStore=true,journalDirectory=../data/journal,bindingsDirectory=../data/bindings,largeMessagesDirectory=../data/large-messages,pagingDirectory=../data/paging)
* [main] 28-Nov 11:7:51,753 INFO [HornetQServerImpl]  Waiting to obtain live lock
* [main] 28-Nov 11:7:51,774 INFO [JournalStorageManager]  Using AIO Journal
* [main] 28-Nov 11:7:51,937 INFO [AIOFileLockNodeManager]  Waiting to obtain live lock
* [main] 28-Nov 11:7:51,937 INFO [AIOFileLockNodeManager]  Live Server Obtained live lock
* [main] 28-Nov 11:7:54,350 INFO [HornetQServerImpl]  trying to deploy queue jms.queue.DLQ
* [main] 28-Nov 11:7:54,369 INFO [HornetQServerImpl]  trying to deploy queue jms.queue.ExpiryQueue
* [main] 28-Nov 11:7:54,374 INFO [HornetQServerImpl]  trying to deploy queue jms.queue.SomeQueue
* [main] 28-Nov 11:7:54,476 INFO [NettyAcceptor]  Started Netty Acceptor version 3.2.5.Final-a96d88c middleware-magic.com:4455 for CORE protocol
* [main] 28-Nov 11:7:54,477 INFO [NettyAcceptor]  Started Netty Acceptor version 3.2.5.Final-a96d88c middleware-magic.com:4445 for CORE protocol
* [main] 28-Nov 11:7:54,478 INFO [HornetQServerImpl]  Server is now live
* [main] 28-Nov 11:7:54,478 INFO [HornetQServerImpl]  HornetQ Server version 2.2.11.Final (HQ_2_2_11_FINAL_AS7, 122) [0ba4fa8d-3895-11e2-a23c-01d224a63402]) started

In order to test our set-up, we can use the following

package model.test;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Properties;

public class HornetQTest {

    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
        properties.put(Context.PROVIDER_URL, "jnp://192.168.1.150:1099");
        properties.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");
        properties.put(Context.SECURITY_PRINCIPAL, "employee");
        properties.put(Context.SECURITY_CREDENTIALS, "welcome1");

        ConnectionFactory connectionFactory = null;
        Destination destination = null;

        try {
            Context context = new InitialContext(properties);
            connectionFactory = (ConnectionFactory) context.lookup("jms/SomeConnectionFactory");
            destination = (Destination) context.lookup("jms/queue/SomeQueue");

            System.out.println(connectionFactory);
            System.out.println(destination);

            sendMessage(connectionFactory, destination);
            receiveMessage(connectionFactory, destination);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    private static void sendMessage(ConnectionFactory connectionFactory, Destination destination) {
        Connection connection = null;
        Session session = null;
        MessageProducer messageProducer = null;

        try {
            connection = connectionFactory.createConnection("guest", "guest");
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            messageProducer = session.createProducer(destination);

            TextMessage text = session.createTextMessage();
            text.setText("Send some useful message");
            messageProducer.send(text);
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException f) {
                    f.printStackTrace();
                }
            }
        }
    }

    private static void receiveMessage(ConnectionFactory connectionFactory, Destination destination) {
        Connection connection = null;
        Session session = null;
        MessageConsumer messageConsumer = null;

        try {
            connection = connectionFactory.createConnection("guest", "guest");
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            messageConsumer = session.createConsumer(destination);

            connection.start();

            Message message = messageConsumer.receive(1000);
            System.out.println(message.getJMSDestination() + ", " + message);
            if (message instanceof TextMessage) {
                TextMessage text = (TextMessage) message;
                System.out.println(text.getText());
            }

            connection.stop();
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException f) {
                    f.printStackTrace();
                }
            }
        }
    }
}

To run this, we need jnpserver.jar on the class path. This jar can be obtained from the HornetQ distribution (${HORNETQ_HOME}/lib). The following output is observed when the program is run

HornetQConnectionFactory [serverLocator=ServerLocatorImpl [initialConnectors=[org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=4445&host=middleware-magic-com], discoveryGroupConfiguration=null], clientID=null, dupsOKBatchSize=1048576, transactionBatchSize=1048576, readOnly=false]
HornetQQueue[SomeQueue]
HornetQQueue[SomeQueue], HornetQMessage[ID:e5d0ecc8-3944-11e2-b6cb-005056c00001]:PERSISTENT
Send some useful message

Make sure the host returned in this case middleware-magic-com can be resolved to the right IP address. More information can be found in the Spring and JBoss AS7 JMS post.

Set-up JBoss AS7

Next, we set-up the JBoss environment. To this end, we add the following to the domain.xml (located in the ${JBOSS_HOME}/domain/configuration directory)

<domain xmlns="urn:jboss:domain:1.1">
    <extensions>...</extensions>
    <system-properties>...</system-properties>
    <profiles>
        <profile name="standalone">...</profile>
        <profile name="cluster">
		    ...
            <subsystem xmlns="urn:jboss:domain:messaging:1.1">
                <hornetq-server>
                    <security-enabled>false</security-enabled>
                    <persistence-enabled>true</persistence-enabled>
                    <create-journal-dir>true</create-journal-dir>
                    <journal-type>ASYNCIO</journal-type>
                    <journal-buffer-timeout>500000</journal-buffer-timeout>
                    <journal-buffer-size>1048576</journal-buffer-size>
                    <journal-sync-transactional>true</journal-sync-transactional>
                    <journal-sync-non-transactional>true</journal-sync-non-transactional>
                    <journal-file-size>10485760</journal-file-size>
                    <journal-min-files>2</journal-min-files>
                    <journal-compact-min-files>10</journal-compact-min-files>
                    <journal-compact-percentage>30</journal-compact-percentage>
                    <journal-max-io>1024</journal-max-io>
                    <journal-directory path="data/messaging" relative-to="messaging.journal.base.directory"/>

                    <cluster-user>employee</cluster-user>
                    <cluster-password>welcome1</cluster-password>

                    <connectors>
                        <netty-connector name="netty" socket-binding="messaging"/>
                        <netty-connector name="netty-throughput" socket-binding="messaging-throughput">
                            <param key="batch-delay" value="50"/>
                        </netty-connector>
                        <in-vm-connector name="in-vm" server-id="0"/>
                    </connectors>

                    <acceptors>
                        <netty-acceptor name="netty" socket-binding="messaging"/>
                        <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
                            <param key="batch-delay" value="50"/>
                            <param key="direct-deliver" value="false"/>
                        </netty-acceptor>
                        <in-vm-acceptor name="in-vm" server-id="0"/>
                    </acceptors>

                    <security-settings>
                        <security-setting match="#">
                            <permission type="send" roles="guest"/>
                            <permission type="consume" roles="guest"/>
                            <permission type="createNonDurableQueue" roles="guest"/>
                            <permission type="deleteNonDurableQueue" roles="guest"/>
                        </security-setting>
                    </security-settings>

                    <address-settings>
                        <address-setting match="#">
                            <dead-letter-address>jms.queue.DLQ</dead-letter-address>
                            <expiry-address>jms.queue.EQ</expiry-address>
                            <redelivery-delay>0</redelivery-delay>
                            <max-size-bytes>10485760</max-size-bytes>
                            <address-full-policy>BLOCK</address-full-policy>
                            <message-counter-history-day-limit>10</message-counter-history-day-limit>
                        </address-setting>
                        <address-setting match="jms.queue.testQueue">
                            <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
                            <expiry-address>jms.queue.expiryQueue</expiry-address>
                            <redelivery-delay>5000</redelivery-delay>
                            <max-delivery-attempts>3</max-delivery-attempts>
                            <max-size-bytes>104857600</max-size-bytes>
                            <address-full-policy>BLOCK</address-full-policy>
                            <last-value-queue>true</last-value-queue>
                            <redistribution-delay>0</redistribution-delay>
                            <send-to-dla-on-no-route>true</send-to-dla-on-no-route>
                        </address-setting>
                    </address-settings>

                    <jms-connection-factories>
                        <connection-factory name="InVmConnectionFactory">
                            <connectors>
                                <connector-ref connector-name="in-vm"/>
                            </connectors>
                            <entries>
                                <entry name="java:/ConnectionFactory"/>
                            </entries>
                        </connection-factory>
                        <connection-factory name="RemoteConnectionFactory">
                            <connectors>
                                <connector-ref connector-name="netty"/>
                            </connectors>
                            <entries>
                                <entry name="RemoteConnectionFactory"/>
                                <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                            </entries>
                        </connection-factory>
                        <pooled-connection-factory name="hornetq-ra">
                            <transaction mode="xa"/>
                            <connectors>
                                <connector-ref connector-name="in-vm"/>
                            </connectors>
                            <entries>
                                <entry name="java:/JmsXA"/>
                            </entries>
                        </pooled-connection-factory>
                    </jms-connection-factories>

                    <jms-destinations>
                        <jms-queue name="testQueue">
                            <entry name="java:/queue/test"/>
                            <entry name="java:jboss/exported/jms/queue/test"/>
                        </jms-queue>
                        <jms-queue name="deadLetterQueue">
                            <entry name="java:/queue/deadLetterQueue"/>
                            <entry name="java:jboss/exported/jms/queue/deadLetterQueue"/>
                            <durable>false</durable>
                        </jms-queue>
                        <jms-queue name="expiryQueue">
                            <entry name="java:/queue/expiryQueue"/>
                            <entry name="java:jboss/exported/jms/queue/expiryQueue"/>
                            <durable>false</durable>
                        </jms-queue>
                        <jms-topic name="testTopic">
                            <entry name="java:/topic/test"/>
                            <entry name="java:jboss/exported/jms/topic/test"/>
                        </jms-topic>
                    </jms-destinations>
                </hornetq-server>
            </subsystem>
			...
        </profile>
    </profiles>
    <interfaces>...</interfaces>
    <socket-binding-groups>...</socket-binding-groups>
    <deployments>
        <deployment name="LoadTest6.ear" runtime-name="LoadTest6.ear">
            <content sha1="161f51dde7f085c822cc4c68b306d57f1bee902d"/>
        </deployment>
        <deployment name="SpringHibernate.war" runtime-name="SpringHibernate.war">
            <content sha1="7d11daad8702ecc31321f41089b32ded945c6d7f"/>
        </deployment>
    </deployments>
    <server-groups>
        <server-group name="standalone-group" profile="standalone">
            <jvm name="default"/>
            <socket-binding-group ref="standalone-sockets"/>
        </server-group>
        <server-group name="cluster-group" profile="cluster">
            <jvm name="default"/>
            <socket-binding-group ref="cluster-sockets"/>
            <deployments>
                <deployment name="LoadTest6.ear" runtime-name="LoadTest6.ear" enabled="false"/>
                <deployment name="SpringHibernate.war" runtime-name="SpringHibernate.war"/>
            </deployments>
        </server-group>
    </server-groups>
</domain>

In the host.xml we have the following

<host name="jboss" xmlns="urn:jboss:domain:1.1">
    <management>...</management>
    <domain-controller><local/></domain-controller>
    <interfaces>...</interfaces>
    <jvms>
    	<jvm name="default">
            <heap size="512m" max-size="512m"/>
            <permgen size="256m" max-size="256m"/>
            <jvm-options>
                <option value="-server"/>
                <option value="-XX:NewRatio=2"/>
                <option value="-XX:+UseParallelGC"/>
                <option value="-XX:ParallelGCThreads=2"/>
                <option value="-XX:MaxGCPauseMillis=200"/>
                <option value="-XX:GCTimeRatio=19"/>
                <option value="-XX:+UseParallelOldGC"/>
                <option value="-XX:+UseTLAB"/>
                <option value="-XX:LargePageSizeInBytes=2048k"/>
                <option value="-XX:+UseLargePages"/>
            </jvm-options>
        </jvm>
    </jvms>
    <servers>
        <server name="standalone-server" group="standalone-group" auto-start="false"/>
        <server name="cluster-server1" group="cluster-group" auto-start="false">
            <paths>
                <path name="messaging.journal.base.directory" path="/home/jboss/temp/cluster-server1"/>
            </paths>
        </server>
        <server name="cluster-server2" group="cluster-group" auto-start="false">
            <socket-bindings port-offset="1"/>
            <paths>
                <path name="messaging.journal.base.directory" path="/home/jboss/temp/cluster-server2"/>
            </paths>
        </server>
    </servers>
</host>

Note that we have also configured the messaging journal in the domain.xml

  • journal-directory – This is the directory in which the message journal lives. For the best performance, it is recommended that the journal is located on its own physical volume in order to minimise disk head movement. If the journal is on a volume which is shared with other processes which might be writing other files (e.g. bindings journal, database, or transaction coordinator) then the disk head may well be moving rapidly between these files as it writes them, thus drastically reducing performance. When the message journal is stored on a SAN it is recommended that each journal instance that is stored on the SAN is given its own LUN (logical unit).
  • create-journal-dir – If this is set to true then the journal directory will be automatically created at the location specified in journal-directory if it does not already exist.
  • journal-type – Valid values are NIO or ASYNCIO. The NIO option uses the Java NOI Journal. The ASYNCIO option uses the Linux asynchronous IO journal. If we choose ASYNCIO and are not running Linux or do not have libaio installed then HornetQ will detect this and automatically fall back to using NIO. The ASYNCIO option uses a thin native code wrapper to talk to the Linux asynchronous IO library (AIO). With AIO, HornetQ will be called back when the data has made it to disk, allowing HornetQ to avoid explicit syncs altogether and simply send back confirmation of completion when AIO informs HornetQ that the data has been persisted. Using AIO will typically provide better performance than using Java NIO.
  • journal-sync-transactional – If this is set to true then HornetQ will make sure all transaction data is flushed to disk on transaction boundaries (commit, prepare and rollback).
  • journal-sync-non-transactional – If this is set to true then HornetQ will make sure non transactional message data (sends and acknowledgements) are flushed to disk each time.
  • journal-file-size – The size of each journal file in bytes.
  • journal-min-files – The minimum number of files the journal will maintain. When HornetQ starts and there is no initial message data, HornetQ will pre-create journal-min-files number of files. Creating journal files and filling them with padding is a fairly expensive operation and we want to minimise doing this at run-time as files get filled. By precreating files, as one is filled the journal can immediately resume with the next one without pausing to create it. Depending on how much data we expect our queues to contain at steady state we should tune this number of files to match that total amount of data.
  • journal-max-io – Write requests are queued up before being submitted to the system for execution. This parameter controls the maximum number of write requests that can be in the IO queue at any one time. If the queue becomes full then writes will block until space is freed up. When using NIO, this value should always be equal to 1. When using ASYNCIO, the default value is 500. The maximum value of ASYNCIO can not be higher than the value configured in the operating system (i.e., /proc/sys/fs/aio-max-nr).
  • journal-buffer-timeout – Instead of flushing on every write that requires a flush, HornetQ maintains an internal buffer, and flush the entire buffer either when it is full, or when a timeout expires. This allows the system to scale better with many concurrent writes that require flushing. Note that The second implementation uses a thin native code wrapper to talk to the Linux asynchronous IO library (AIO). With AIO, HornetQ will be called back when the data has made it to disk, allowing us to avoid explicit syncs altogether and simply send back confirmation of completion when AIO informs us that the data has been persisted. Note that ASYNCIO can cope with a higher flush rate than NIO (the default values are 3333333 nanoseconds (300 times per second) for NOI and 500000 nanoseconds (2000 times per second) for ASYNCIO.
  • journal-buffer-size – The size of the buffer.
  • journal-compact-min-files – The minimal number of files before HornetQ can consider compacting the journal. The compacting algorithm will not start until there are at least journal-compact-min-files.
  • journal-compact-percentage – The threshold to start compacting. When less than this percentage is considered live data, HornetQ starts compacting.

For the testQueue we have also specified address settings

  • max-delivery-attempts – defines how many times a cancelled message can be redelivered before sending to the dead-letter-address.
  • redelivery-delay – defines how long to wait before attempting redelivery of a cancelled message.
  • expiry-address defines where to send a message that has expired (the time is set by using a time-to-live).
  • last-value-queue – defines whether a queue only uses last values or not. Last-Value queues are special queues which discard any messages when a newer message with the same value for a well-defined Last-Value property is put in the queue.
  • redistribution-delay – defines how long to wait when the last consumer is closed on a queue before redistributing any messages. Server side message load balancing round robins messages across the cluster. If forward-when-no-consumers is false, then messages will not be forwarded to nodes which do not have matching consumers, this is great and ensures that messages do not arrive on a queue which has no consumers to consume them, however there is a situation it does not solve: What happens if the consumers on a queue close after the messages have been sent to the node? If there are no consumers on the queue the message will not get consumed and we have a starvation situation. This is where message redistribution comes in. With message redistribution HornetQ can be configured to automatically redistribute messages from queues which have no consumers back to other nodes in the cluster which do have matching consumers. Message redistribution can be configured to kick in immediately after the last consumer on a queue is closed, or to wait a configurable delay after the last consumer on a queue is closed before redistributing.
  • send-to-dla-on-no-route – if a message is sent to an address, but the server does not route it to any queues, for example, there might be no queues bound to that address, or none of the queues have filters that match, then normally that message would be discarded. However if this parameter is set to true for that address, if the message is not routed to any queues it will instead be sent to the dead letter address for that address, if it exists.
  • address-full-policy – this attribute can have one of the following values: PAGE, DROP or BLOCK and determines what happens when an address where max-size-bytes is specified becomes full. If the value is PAGE then further messages will be paged to disk. If the value is DROP then further messages will be silently dropped. If the value is BLOCK then client message producers will block when they try and send further messages.

To test the JBoss side, we can use

package model.test;

import javax.jms.*;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.util.Properties;

public class JNDITest {
    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        properties.put(Context.PROVIDER_URL, "remote://192.168.1.150:4447");
        properties.put(Context.SECURITY_PRINCIPAL, "employee");
        properties.put(Context.SECURITY_CREDENTIALS, "welcome1");

        ConnectionFactory connectionFactory = null;
        Destination destination = null;

        try {
            Context context = new InitialContext(properties);
            connectionFactory = (ConnectionFactory) context.lookup("jms/RemoteConnectionFactory");
            destination = (Destination) context.lookup("jms/queue/test");

            System.out.println(connectionFactory);
            System.out.println(destination);

            sendMessage(connectionFactory, destination);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }

    private static void sendMessage(ConnectionFactory connectionFactory, Destination destination) {
        Connection connection = null;
        Session session = null;
        MessageProducer messageProducer = null;

        try {
            connection = connectionFactory.createConnection("employee", "welcome1");
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            messageProducer = session.createProducer(destination);

            TextMessage text = session.createTextMessage();
            text.setText("Send some useful message");
            messageProducer.send(text);
        } catch (JMSException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                try {
                    connection.close();
                } catch (JMSException f) {
                    f.printStackTrace();
                }
            }
        }
    }
}

To run this we need jboss-client-7.1.0.Final.jar in the class path. When the program is run the following is observed on the client side

Nov 28, 2012 1:48:05 PM org.xnio.Xnio <clinit>
INFO: XNIO Version 3.0.3.GA
Nov 28, 2012 1:48:05 PM org.xnio.nio.NioXnio <clinit>
INFO: XNIO NIO Implementation Version 3.0.3.GA
Nov 28, 2012 1:48:05 PM org.jboss.remoting3.EndpointImpl <clinit>
INFO: JBoss Remoting version 3.2.2.GA
HornetQConnectionFactory [serverLocator=ServerLocatorImpl [initialConnectors=[org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5445&host=middleware-magic-com], discoveryGroupConfiguration=null], clientID=null, dupsOKBatchSize=1048576, transactionBatchSize=1048576, readOnly=false]
HornetQQueue[testQueue]

On the server side (in the JBoss logging) the following is observed

13:48:07,450 INFO  [stdout] (org.springframework.jms.listener.DefaultMessageListenerContainer#0-1) RECEIVED TEXT MESSAGE Send some useful message
13:48:07,502 INFO  [org.jboss.as.naming] (Remoting "jboss:cluster-server1" task-4) JBAS011806: Channel end notification received, closing channel Channel ID 3df88b53 (inbound) of Remoting connection 08fa0f67 to null

The message is picked-up by the Spring/Hibernate application introduced in the Spring and Hibernate4 post.

Monitoring

HermesJMS is an extensible console that helps you interact with JMS providers making it simple to publish and edit messages, browse or seach queues and topics, copy messages around and delete them. By using HermesJMS we are able to browse destinations:

  • Edit the file hermes.sh located in the directory <HermesJMS-Home>/bin.
  • Make sure the variable JAVA_HOME points to a valid JDK installation directory.
  • Run the file hermes.sh.
  • Click in the menu on options, configuration.
  • Click on the providers tab at the bottom.
  • Right click on classpath groups and select add group.
  • Enter a name, for example JBossAS7.
  • Click on the + to expand the JBossAS7 tree, right click library and select add jar(s).
  • Browse to ${JBOSS_HOME}/bin/client and select jboss-client-7.1.0.jar.
  • Click do not scan and click ok.
  • Right click sessions and select new, new session.
  • In the connection factory section enter the following parameters:
    • class: hermes.JNDIConnectionFactory
    • loader: JBossAS7 (this is the provider we create above)
  • Subsequently, add some properties (right click under property and choose from the drop-down-box)
    • securityCredentials: welcome1 (password of an application user with guest as role)
    • initialContextFactory: org.jboss.naming.remote.client.InitialContextFactory
    • securityPrincipal: employee (username of an application user with guest as role)
    • binding: jms/RemoteConnectionFactory (a connection factory configured on the server, which has a prefix java:jboss/exported)
    • providerURL: remote://192.168.1.150:4447 (url to the server)
    • urlPkgPrefixes: org.jboss.naming.remote.client
  • Add the destination that we want to monitor in the destinations section (right click and choose add)
    • name: JNDI name of the destination, for example, jms/queue/test
  • Click ok.
  • Double click the MiddlewareMagic session to browse the destination.

In hermes-config.xml the following has been added

...
<classpathGroup id="jbossas7">
	<library factories="org.hornetq.jms.client.HornetQJMSConnectionFactory,org.hornetq.jms.client.HornetQQueueConnectionFactory,org.hornetq.jms.client.HornetQTopicConnectionFactory,org.hornetq.jms.client.HornetQXAConnectionFactory,org.hornetq.jms.client.HornetQXAQueueConnectionFactory,org.hornetq.jms.client.HornetQXATopicConnectionFactory" noFactories="false" jar="/home/jboss/jboss-as-7.1.0.Final/bin/client/jboss-client-7.1.0.Final.jar"/>
</classpathGroup>
...
<factory classpathId="jbossas7">
	<provider className="hermes.JNDIConnectionFactory">
		<properties>
			<property value="jms/RemoteConnectionFactory" name="binding"/>
			<property value="org.jboss.naming.remote.client.InitialContextFactory" name="initialContextFactory"/>
			<property value="remote://192.168.1.150:4447" name="providerURL"/>
			<property value="welcome1" name="securityCredentials"/>
			<property value="employee" name="securityPrincipal"/>
			<property value="org.jboss.naming.remote.client" name="urlPkgPrefixes"/>
		</properties>
	</provider>
	<connection connectionPerThread="false" clientID="">
		<session useConsumerForQueueBrowse="false" audit="false" transacted="true" reconnects="0" id="&lt;new&gt;"/>
	</connection>
	<destination durable="false" domain="1" name="jms/queue/test"/>
	<extension className="hermes.ext.DefaultHermesAdminFactory">
		<properties/>
	</extension>
</factory>
...

An example output after sending a message

Create the Bridge

Our next goal is to forward messages put into the HornetQ queue (by, for example, the client introduced above) by using a HornetQ bridge. The HornetQ bridge will forward the messages to the JBoss Server. To configure the bridge we can use the following in the hornetq-configuration.xml file

<configuration ...>
	...
	<connectors>
		...
		<connector name="remote-connector">
			<factory-class>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</factory-class>
			<param key="host"  value="${hornetq.remoting.netty.host:middleware-magic.com}"/>
			<param key="port"  value="${hornetq.remoting.netty.batch.port:5445}"/>
		</connector>
	</connectors>
	<acceptors>...</acceptors>
	<queues>
		<queue name="jms.queue.SomeQueue">
			<address>jms.queue.SomeQueue</address>
		</queue>
	</queues>
	<bridges>
		<bridge name="SomeBridge">
			<queue-name>jms.queue.SomeQueue</queue-name>
			<forwarding-address>jms.queue.testQueue</forwarding-address>
			<reconnect-attempts>-1</reconnect-attempts>
			<static-connectors>
				<connector-ref>remote-connector</connector-ref>
			</static-connectors>
		</bridge>
	</bridges>
	<security-settings>...</security-settings>
	<address-settings>...</address-settings>
</configuration>

As we are connecting to a JBoss Server we need some extra classes in the class path of the HornetQ Server that are contained in the jboss-client-7.1.0.Final.jar file. With the configuration in place start the HornetQ Server

[jboss@middleware-magic bin]$ ./run.sh
***********************************************************************************
java  -XX:+UseParallelGC -XX:+AggressiveOpts -XX:+UseFastAccessorMethods -Xms512M -Xmx1024M -Dhornetq.config.dir=../config/stand-alone/non-clustered -Djava.util.logging.config.file=../config/stand-alone/non-clustered/logging.properties -Djava.library.path=. -classpath ../lib/twitter4j-core.jar:../lib/netty.jar:../lib/jnpserver.jar:../lib/jnp-client.jar:../lib/jboss-mc.jar:../lib/jboss-jms-api.jar:../lib/jboss-client-7.1.0.Final.jar:../lib/hornetq-twitter-integration.jar:../lib/hornetq-spring-integration.jar:../lib/hornetq-logging.jar:../lib/hornetq-jms.jar:../lib/hornetq-jms-client-java5.jar:../lib/hornetq-jms-client.jar:../lib/hornetq-jboss-as-integration.jar:../lib/hornetq-core.jar:../lib/hornetq-core-client-java5.jar:../lib/hornetq-core-client.jar:../lib/hornetq-bootstrap.jar:../config/stand-alone/non-clustered:../schemas/ org.hornetq.integration.bootstrap.HornetQBootstrapServer hornetq-beans.xml
***********************************************************************************
* [main] 28-Nov 14:2:49,29 INFO [HornetQBootstrapServer]  Starting HornetQ Server
* [main] 28-Nov 14:2:50,964 INFO [HornetQServerImpl]  live server is starting with configuration HornetQ Configuration (clustered=false,backup=false,sharedStore=true,journalDirectory=../data/journal,bindingsDirectory=../data/bindings,largeMessagesDirectory=../data/large-messages,pagingDirectory=../data/paging)
* [main] 28-Nov 14:2:50,964 INFO [HornetQServerImpl]  Waiting to obtain live lock
* [main] 28-Nov 14:2:50,985 INFO [JournalStorageManager]  Using AIO Journal
* [main] 28-Nov 14:2:51,173 INFO [AIOFileLockNodeManager]  Waiting to obtain live lock
* [main] 28-Nov 14:2:51,173 INFO [AIOFileLockNodeManager]  Live Server Obtained live lock
* [main] 28-Nov 14:2:53,787 INFO [HornetQServerImpl]  trying to deploy queue jms.queue.SomeQueue
* [main] 28-Nov 14:2:53,851 INFO [HornetQServerImpl]  trying to deploy queue jms.queue.DLQ
* [main] 28-Nov 14:2:53,871 INFO [HornetQServerImpl]  trying to deploy queue jms.queue.ExpiryQueue
* [main] 28-Nov 14:2:53,876 INFO [HornetQServerImpl]  trying to deploy queue jms.queue.SomeQueue
* [main] 28-Nov 14:2:54,57 INFO [NettyAcceptor]  Started Netty Acceptor version 3.2.5.Final-a96d88c middleware-magic.com:4455 for CORE protocol
* [main] 28-Nov 14:2:54,59 INFO [NettyAcceptor]  Started Netty Acceptor version 3.2.5.Final-a96d88c middleware-magic.com:4445 for CORE protocol
* [main] 28-Nov 14:2:54,343 INFO [HornetQServerImpl]  Server is now live
* [main] 28-Nov 14:2:54,344 INFO [HornetQServerImpl]  HornetQ Server version 2.2.11.Final (HQ_2_2_11_FINAL_AS7, 122) [0ba4fa8d-3895-11e2-a23c-01d224a63402]) started

* [Thread-3 (HornetQ-server-HornetQServerImpl::serverUUID=0ba4fa8d-3895-11e2-a23c-01d224a63402-1332226643)] 28-Nov 14:2:58,112 INFO [BridgeImpl]  Bridge BridgeImpl@7b712193 [name=SomeBridge, queue=QueueImpl[name=jms.queue.SomeQueue, postOffice=PostOfficeImpl [server=HornetQServerImpl::serverUUID=0ba4fa8d-3895-11e2-a23c-01d224a63402]]@40537935 targetConnector=ServerLocatorImpl [initialConnectors=[org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5445&host=middleware-magic-com], discoveryGroupConfiguration=null]] is connected

* [Thread-1 (HornetQ-client-global-threads-851009394)] 28-Nov 15:35:13,698 WARNING [RemotingConnectionImpl]  Connection failure has been detected: The connection was disconnected because of server shutdown [code=4]
* [Thread-1 (HornetQ-client-global-threads-851009394)] 28-Nov 15:35:13,699 WARNING [BridgeImpl]  BridgeImpl@7b712193 [name=SomeBridge, queue=QueueImpl[name=jms.queue.SomeQueue, postOffice=PostOfficeImpl [server=HornetQServerImpl::serverUUID=0ba4fa8d-3895-11e2-a23c-01d224a63402]]@40537935 targetConnector=ServerLocatorImpl [initialConnectors=[org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5445&host=middleware-magic-com], discoveryGroupConfiguration=null]]::Connection failed with failedOver=false-HornetQException[errorCode=4 message=The connection was disconnected because of server shutdown]
HornetQException[errorCode=4 message=The connection was disconnected because of server shutdown]
	at org.hornetq.core.client.impl.ClientSessionFactoryImpl$Channel0Handler$1.run(ClientSessionFactoryImpl.java:1467)
	at org.hornetq.utils.OrderedExecutorFactory$OrderedExecutor$1.run(OrderedExecutorFactory.java:100)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

* [Thread-29 (HornetQ-server-HornetQServerImpl::serverUUID=0ba4fa8d-3895-11e2-a23c-01d224a63402-1332226643)] 28-Nov 15:36:17,997 INFO [BridgeImpl]  Bridge BridgeImpl@7b712193 [name=SomeBridge, queue=QueueImpl[name=jms.queue.SomeQueue, postOffice=PostOfficeImpl [server=HornetQServerImpl::serverUUID=0ba4fa8d-3895-11e2-a23c-01d224a63402]]@40537935 targetConnector=ServerLocatorImpl [initialConnectors=[org-hornetq-core-remoting-impl-netty-NettyConnectorFactory?port=5445&host=middleware-magic-com], discoveryGroupConfiguration=null]] is connected

As the last logging line indicates, we are connected. Note that the logging also shows what happens when the JBoss servers are shutdown and started (disconnect and connect). Running the client a few times leads to in the JBoss Server log.

14:04:06,384 INFO  [stdout] (org.springframework.jms.listener.DefaultMessageListenerContainer#0-1) RECEIVED TEXT MESSAGE Send some useful message
14:04:11,950 INFO  [stdout] (org.springframework.jms.listener.DefaultMessageListenerContainer#0-1) RECEIVED TEXT MESSAGE Send some useful message
14:04:17,943 INFO  [stdout] (org.springframework.jms.listener.DefaultMessageListenerContainer#0-1) RECEIVED TEXT MESSAGE Send some useful message
14:04:20,462 INFO  [stdout] (org.springframework.jms.listener.DefaultMessageListenerContainer#0-1) RECEIVED TEXT MESSAGE Send some useful message

Performance

When running a JMS system some performance tweaks could be necessary, such as

When dealing with large message flows, it is beneficial to put as many messages in the JVM heap as possible. Or better yet, just put them all in the JVM heap, sometimes this leads to creating very large heaps (with of course garbage collection as a very potential bottleneck). Usually, when using the common JVMs, such as HotSpot, garbage collection becomes a bottleneck. When dealing with very large heaps it shows beneficial to use the Zing JVM (created by Azul Systems) instead.

References

[1] HornetQ User Manual.
[2] Performance Tuning.


  • Testimonials

  • RSS Middleware Magic – JBoss

  • Receive FREE Updates


    FREE Email updates of our new posts Enter your email address:



  • Magic Archives

  • Sitemeter Status

  • ClusterMap 7-Nov-2011 till Date

  • ClusterMap 6-Nov-2010 till 7-Nov-2011

  • Copyright © 2010-2012 Middleware Magic. All rights reserved. | Disclaimer