Thursday, February 12, 2015

JMS - Store-And-Forward

As the concept of message bridges is specially designed for communication with other JMS implementations, WebLogic Server offers us Store-And-Forward (SAF) to establish JMS communication between recent WLS versions.

Compared with JMS bridges, the practical implementation of SAF is a little bit different.

The SAF-architecture looks like this:



First, we configure the target domain.
This is quite straight forward.  Define a JMS server, a JMS module with a connection factory and a queue.

The source configuration is different.

  • You need a JMS server as well.
  • You'll need to create a "Store-And-Forward Agent" connected with a persistent store.
  • A "Connection Factory" must be configured.
  • The queue doesn't have to configured in the system module directly.
  • A "SAF Remote Context" needs to be created; there we will define the t3 connection url.
  • As last component, a "SAF Imported Destination" must be configured.  In that component, we'll make a queue that points to the target queue.

SAF Agent:

The components of the system module:


The SAF Remote Context:


The SAF Imported Destination:



The SAF Queue within the imported destination:



When the architecture is completely configured, we can now test our setup.
In a small web application, we send messages to the source queue:

And the output on our target queue looks like this:

[oracle@wls12c2 jms]$ java SAFQueueTargetReceive t3://wls12c2:8011
JMS Ready To Receive Messages (To quit, send a "quit" message).
Text Message Received: this is a test message 0
Text Message Received: this is a test message 1
Text Message Received: this is a test message 2
Text Message Received: this is a test message 3
Text Message Received: this is a test message 4
Text Message Received: this is a test message 5
Text Message Received: this is a test message 6
Text Message Received: this is a test message 7
Text Message Received: this is a test message 8
Text Message Received: this is a test message 9


Conclusion: our SAF configuration works like a charm!

JMS - Message Bridge

The message bridge in WebLogic is nice if you want to have communications between several JMS implementations, e.g.

  • different WebLogic Server versions
  • WebLogic and other JMS implementations (JBoss, GlassFish,...)
For this demo purpose, I will define message bridges between two WLS 12c domains.  I know that this setup is not the right one to demonstrate message bridges because therefore you'll have to use the Store-And-Forward (SAF) feature.
I will show the SAF feature in one of my following blog posts.

But to show you the architecture and implementation, I guess it is a good example.

This is the architecture of my setup:



On both domains, a JMS server must be created, a JMS module which contains a "Connection Factory" and a "Queue".

Source domain:


Target domain:



In the source domain, 2 "JMS Bridge Destinations" must be created and 1 overarching brigde:


The destination for the source:



The destination for the target:


And the combination of the 2 destinations:


From this moment (= creation of the bridge itself), WLS deploys automatically the correct resource adapter:



Now, we can test our setup.
I wrote a small web application that I deployed in the source domain (port 8001) to send messages to the source queue:


And I wrote a Java class that listens on the target queue deployed in the target domain.  If I push on the "Send Message" button in my web application, I see this output on my listener:

[oracle@wls12c2 jms]$ java QueueTargetReceive t3://wls12c2:8011
JMS Ready To Receive Messages (To quit, send a "quit" message).
Text Message Received: this is a test message 0
Text Message Received: this is a test message 1
Text Message Received: this is a test message 2
Text Message Received: this is a test message 3
Text Message Received: this is a test message 4
Text Message Received: this is a test message 5
Text Message Received: this is a test message 6
Text Message Received: this is a test message 7
Text Message Received: this is a test message 8
Text Message Received: this is a test message 9


Conclusion: my setup works successfully!

WebLogic 12c : Dynamic Clusters

Oracle introduced a new interesting feature in WebLogic release 12.1.2: dynamic clusters.  With this option you can easily roll out new clusters and scale them out.

In this blog post, I will try to describe this new feature.

Starting point:
WebLogic development domain "dynamic_domain" with the admin server running on port 7001.
Domain is located on 1 machine where the NM is running on.

Navigate to the WLS console and go to the clusters section.
Choose for "New - Dynamic Cluster":

Choose an appropriate name for the cluster, e.g. "MyDynamicCluster".

In the next step, you can define a number of dynamic servers and a server name prefix.  I keep the defaults here:

Next, you can choose the machines for the managed servers.  Because I have only one machine, I keep the default here.

Next, you can define the listen ports for the servers; you have the choice between unique and fixed listen ports.  I keep the default unique value.

The last screen shows an overview.

Terminating this wizard results in the following:
(1)
Of course, the cluster itself: "MyDynamicCluster".

(2)
A server template called "MyDynamicCluster-Template".  Afterwards, you can change the settings of it.

(3)
Two automatically created managed servers.
Both servers can be started in the console through the NM.

When you go into the dynamic cluster, and navigate then to the "Configuration - Servers" tab, you can see the 2 created servers.  Also, you have the possibility to change some parameters of the dynamic cluster.

For example, if you modify the "Maximum Number of Servers" from 2 to 3, WLS will automatically create a third server for you.

When all servers of the dynamic cluster are down, you can delete the cluster.  If at least one server is still running, you'll get an error and you are not able to delete the cluster.
After the cluster has been deleted, you'll notify that the managed servers are deleted as well.  The server template still exists, but has of course no more a link with the cluster.


Node Manager : High Availability & Crash Recovery

If you want to have a highly available WLS-environment, it is a very good practice to use the Node Manager (NM).  I have done some tests and I will share here my findings.

Note:
This blog post just focuses on the recovery aspects of the Node Manager and will not handle the basic issues.

On a Linux machine, I created a domain with the following components:

  • AdminServer : started through the "startWebLogic.sh" script
  • One single machine + NM configuration : NM started through the "startNodeManager.sh" script
  • One managed server : started through the NM in the console

Search the process id of the managed server through the command line, and execute the following command:
kill <<pid_managed_server>>
Result:
No automatically restart of the managed server.

I restarted the server through the WLS console, and I executed this command:
kill -9 <<pid_managed_server>>
Result:
Auto-restart of the managed server OK!

I did a cold restart of the server machine, and after the reboot, I started back the NM.
Result:
No automatically restart of the managed server.  I restarted manually the server through the WLS console.

To solve this (= enable the crash recovery), the parameter "CrashRecoveryEnabled" must be changed from "false" to "true" in the file "$WL_HOME/common/nodemanager/nodemanager.properties".  Thereafter, restart the NM.

Now, again I did a cold restart of the server machine, started back the NM.
Result:
Auto-restart (= recovery) of the managed server OK!



Conclusion:
It is a good practice to start automatically the NM when booting the server machine.  This will bring automatically the servers under the NM-control in the original state.  That means, if your server process was down, when your machine crashed, it will not be recovered.  If it was up and running, NM will restart your process.

Generating your WLS-domain to a WLST-script through configToScript

If you want to generate a WLST-script from your domain, you can use the configToScript WLST-command.
This command has 4 optional parameters:
  • configPath : your domain directory; if null, your current directory will be taken
  • pyPath : the directory where the script files will be generated
  • overwrite : if the script already exists, it will be overwritten
  • propertiesFile : path to the properties file of the script
  • createDeploymentScript : boolean that indicates if a script will be generated to redeploy the applications in the domain (default value = false)
Start WLST through the wlst.sh script.

wls:/offline> configToScript('/opt/oracle/Oracle/Middleware/user_projects/domains/base_domain/','/home/oracle/wlst_scripts','true','/home/oracle/wlst_scripts/base_domain.properties','true')
configToScript is loading configuration from /opt/oracle/Oracle/Middleware/user_projects/domains/base_domain/config/config.xml ...
Completed configuration load, now converting resources to wlst script...
Creating the key file can reduce the security of your system if it is not kept in a secured location after it is created. Creating new key...
Using existing user key file...
Using existing user key file...
Using existing user key file...
Using existing user key file...
Using existing user key file...
Using existing user key file...
Using existing user key file...
Using existing user key file...
configToScript completed successfully The WLST script is written to /home/oracle/wlst_scripts/config.py and the properties file associated with this script is written to /home/oracle/wlst_scripts/base_domain.properties
WLST found encrypted passwords in the domain configuration. 
These passwords are stored encrypted in /home/oracle/wlst_scripts/c2sConfigbase_domain 
and /home/oracle/wlst_scripts/c2sSecretbase_domain. WLST will use these password values 
while the script is run.
wls:/offline> exit()


Exiting WebLogic Scripting Tool.


After this, you can verify the created files:

[oracle@wls12c wlst_scripts]$ pwd
/home/oracle/wlst_scripts
[oracle@wls12c wlst_scripts]$ ls
base_domain.properties  c2sSecretbase_domain  deploy.py
c2sConfigbase_domain    config.py

Optionally, open the base_domain.properties file and modify the value of the domainDir parameter.

Now, we will recreate the domain with the scripts.
Therefore, we first backup and then delete the WLS-domain directory.  Also, it is a good advice to backup your application sources.
Then, we can execute the config.py script through WLST.

Normally, during the first run, you will encounter this error:
Exception in thread "Main Thread" java.lang.AssertionError: JAX-WS 2.2 API is required, but an older version was found in the JDK.

To solve this, go to the $JAVA_HOME/jre/lib directory and create the "endorsed" directory, if not exists.
Copy the jars in the $WL_HOME/endorsed directory to this new directory.

Now try again to run the Jython script in WLST.  If successful, you can start up your environment.

I noticed afterwards that my application was not deployed, so I redeployed it with WLST.

Deassociating OID from Reports 11g

At a customer site, I faced this problem when trying to activate the showjobs-url of the reports server.
The installation was done by someone else. On the server machine (OS: Windows Server 2008 SP2), the IDM 11g Suite was first installed and then the Fusion Middleware 11g Suite. During the configuration, they associated the OID to the Reports components.
When I arrived a few months later to do some other configuration changes, the customer wanted to deassociate the link between OID and Reports. When we did the deassociation, we received this error in the showjobs-url:
REP-52266: The in-process Reports Server rep_wls_name failed to start.oracle.reports.RWException: IDL:oracle/reports/RWException:1.0

In the rwserver_diagnostics.log file, we found these 2 errors:
* REP-50125 : An internal exception occurred: oracle.security.jps.service.credstore.CredStoreException: Could not find the key specified.
* REP-50125 : An internal exception occurred: oracle.security.jps.service.credstore.CredStoreException: JPS-01050: Opening of wallet based credential store failed. Reason java.io.IOException: PKI-02002: Unable to open the wallet. Check password.

We could solve this issue by commenting some tags:
(1) rwservlet.properties -> we commented the oidconnection-tag
(2) rwserver.conf -> we commented the security-tag

After that, we stopped our environment and restarted all the processes. Result: everything worked fine!

Forms 11g - Windows Java client hangs with message "The application's digital signature cannot be verified."

After modifying the webconfiguration values for the paremeters "webutilArchive" and "archive", I had a very annoying problem.
When I activated the application url, I got the following popup message and I couldn't accept/deny this message.

Warning - Security
The application's digital signature cannot be verified.
Do you want to run the application?

Name:      ... 
Publisher: ... 
From:      ... 
[ ] Always trust content from this publisher. 

[Run] [Cancel]

Although, there is a checkbox in the message and 2 buttons, I couldn't do anything else than shutting down my browser through the Windows Task Manager.

There are 2 solutions for this problem:

(1) Using this sequence of jar-files for webutilArchive
webutilArchive=jacob.jar, frmwebutil.jar
More info on Oracle Support:
WebUtil Form HangsWhen Acknowledging Security Warning - The application's digital signature cannot be verified [ID 1328039.1]

(2) Applying patch 9463433 if the archive parameter is the cause of the problem
More info on Oracle Support:
Windows Java Client Hangs On Accepting Not Verified Signature Of jar Files [ID 1173365.1]