Wednesday, August 31, 2011

Installing SOA Suite, cheatsheet

After installing OracleXE 10g Express Edition,
run SQLPlus
conn system/oracle (or whatever password)
show parameter processes

by default “processes” should be 40. We should make it 300:

alter system set processes=300 scope=spfile;

conn / as sysdba
shutdown immediate

startup

conn / as sysdba

show parameter sga

(sga_target should be 768MB)
alter system set sga_target=350M scope=spfile;
alter system set sga_max_size=350M scope=spfile;
shutdown immediate
startup

INSTALLATION WEBLOGIC WLS

Make sure you have a JDK in C:\Oracle\Middleware\jdk160_18

In your environment variables:
set JAVA_HOME=C:\Oracle\Middleware\jdk160_18
set PATH=%JAVA_HOME%\bin;%PATH%
(ou bien
set JAVA_HOME=“C:\Program Files\Java\jre6_64bit”
set PATH=%JAVA_HOME%\bin;%PATH%
)

To verify, type “java -version” and make sure it's a 1.6

To install WLS:

java -jar wls1033_generic.jar

specify target directory C:\Oracle1\Middleware

INSTALLATION OSB

After installation of WLS, you can install OSB:
path/to/ofm_osb_generic_11.1.1.3.0_disk1_1of1/osb/Disk1/setup.exe

when asked JDK, enter C:\Oracle\Middleware\jdk160_18

unckeck “IDE Oracle Service Bus” and “Oracle Service Bus Examples”

as target directory specify C:\Oracle1\Middleware\

At the end of the installation you should have a C:\Oracle1\Middleware\Oracle_OSB1 directory

INSTALLATION SOA SUITE

At this point let's install Oracle SOA Suite:

path/to/ofm_soa_generic_11.1.1.2.0_disk1_1of1/osb/Disk1/setup

Just give same parameters as for OSB installation.

At this point let's install the patchset path/to 11.3: /ofm_soa_generic_11.1.1.3.0_disk1_1of1/osb/Disk1/setup

To create the DB schemas in Oracle, run rcu.bat
point to localhost:1521
username: sys
as role, choose SYSDBA

ignore the warning about the ENCODING AL32UTF8, and the “DB version not supported” warning

choose “DEV” as a prefix, so as to distinguish the tables belonging to this environment

choose
DEV_SOAINFRA
DEV_ORASDPM
DEV_MDS

choose “use same password for all schemas”

accept DEV_IASTEMP as temporary tablespace

Now you can create a domain:

cd C:\Oracle1\Middleware\wlserver_10.3\common\bin\
config.cmd

choose: “Oracle Enterprise Manager”,
“Oracle SOA Suite”,
“Oracle Service Bus Extension, Single Domain”
“Oracle WSM Policy Manager”
“Oracle Service Bus OWSM Extension”

and all the components selected by default with the above options (JAX_RPC, JRF).

name the domain soadev

choose development mode and the usual JDK C:\Oracle\Middleware\jdk160_18

for DB sconfiguration, select all schemas, and set “localhost” for host name, and XE for Service Name, Select “Oracle” as provider, and “Oracle Driver (thin) for instance connections” as driver.

make sure that OSB JMS Reporting Provider points to SOA_INFRA

remove creation of Managed Server (we shall create only AdminServer)

Open C:\Oracle1\Middleware\user_projects\domains\soadev\bin
setSOADomainEnv.cmd

set DEFAULT_MEM_ARGS=”-Xms1024m -Xmx1024m”
set PORT_MEM_ARGS=-Xms768m -Xmx1536m

do startWebLogic.cmd

For JDeveloper, in jdev.conf you might have to set:
AddVMOption -XX:MaxPermSize=128M
AddVMOption -Xmx512M
AddVMOption -Xms512M

javap ERROR:could not find class

Make sure you do the following:

set CLASSPATH=/path/to/your/class
javap -c MyClass

(without .class)

Anyway what is produced is the bytecode, of limited interest unless you are troubleshooting something tremendously iffy


Recursive decompilation of your JARs

get your jad.exe here:
http://www.varaneckas.com/jad


follow the instructions here:
http://www.adarshr.com/papers/recursive


in a nutshell:


create a directory c:\myjars\
copy jad.exe to c:\myjars
copy your jars to c:\myjars\ (for /r %x in (*.jar) do copy /Y "%x" c:\myjars)
cd c:\myjars\
for %x in (*.jar) do jar xvf %x
#(del *.jar - if you want)
jad.exe -r -o -sjava -d . ./**/*.class
#(-r means recursive, -o means overwite, -sjava means create .java files instead of .jad files)
#(del /S /Q *.class - if you want)



as simple as that

This is also a quick and dirty way to dump the content of all jars into a txt file:

del alljars.txt
for /r %x in (*.jar) do myecho %x >> alljars.txt

where myecho.bat contains:

@echo OFF
echo %1
jar tf %1
echo ______________________________________________________________

the option -lnc adds the line number in the generated code!

2015-10-23: using jd http://jd.benow.ca/ you can open a jar and File/Save Sources...



Unicast cluster tuning

there are 2 properties you can set:

weblogic.cluster.unicastHeartbeatTimeoutMillis (default 15000)
weblogic.cluster.unicastDiscoveryPeriodMillis (default 3000)

If you get a message like:
add Leader BLA to unreliableSet

(you get it only if UnicastMessaging debug flag is enabled)


and your cluster is divided in multiple groups each one with its own Group Leader, and this is annoying you,
you MIGHT consider changing the timeout value (do it at your own risk, side effects are still unknown by the author of this blog!).

In fact unicastHeartbeatTimeoutMillis determines how long after the last heartbeat (LAT=Last Arrival Time) the "slave" should declare that the Group Leader is unrealiable.


The cluster's GroupLeader sends heartbeat messages every LeaderHeartbeatPeriod seconds:

http://download.oracle.com/docs/cd/E11035_01/wls100/schemaref/security/http.www.bea.com.ns.weblogic.920.domain/types/database-less-leasing-basistype.leader-heartbeat-period.html

default value 10.


to view the value of the heartbeat period:



wlst.sh

connect('weblogic', 'welcome1', 't3://localhost:7011')
cd(‘/Clusters/myCluster/DatabaseLessLeasingBasis/myCluster’)
cmo.getLeaderHeartbeatPeriod()


and it’s 10



and to set it I tried:

cmo.setLeaderHeartbeatPeriod(20)

but I get

java.lang.RuntimeException: The requested attribute is not exposed through JMX: setLeaderHeartbeatPeriod

Caused by: javax.management.AttributeNotFoundException: Attribute is readonly. : com.bea:Name=myCluster,Type=DatabaseLessLeasingBasis,Cluster=myCluster:LeaderHeartbeatPeriod

So I guess you can only set it by hacking the the config.xml – I don’t see it in the WebLogic console.

Tuesday, August 30, 2011

The Silence of the Logs


Having noticed that an application server occasionally freezes, with dire consequences for the stability of the cluster, I set out to compute the longest pauses in the logs, using this indicator as a "freezing marker".
Here is the Java "script", it parses all logs in a directory, and for each log it prints the longest period without any activity in the log.
Enjoy.


package com.pierre.loggrepper;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.SimpleDateFormat;



public class WebLogicLogGrepper {
	/** reads "Aug 28, 2011 8:02:45 PM" */

	DateFormat formatter = new SimpleDateFormat("MMM dd, yyyy h:mm:ss aaaa");
	String previousTimeString = null;
	long previousTime = 0;
	String topTimeString = "";
	long topDiff = 0;

	public static void main(String[] args) throws Exception {

		String DIR = "/home/oracle/Downloads/Temp-MSLogs/1/ms1logs/";
		File dir = new File(DIR);
		for (File file : dir.listFiles()) {
			if (file.getName().startsWith("eposprd_ManagedServer")) {
				WebLogicLogGrepper webLogicLogGrepper = new WebLogicLogGrepper();
				webLogicLogGrepper.run(file.getAbsolutePath());
			}
		}


	}

	public void run(String filename) throws Exception {
		FileInputStream fis = new FileInputStream(filename);
		BufferedReader br = new BufferedReader(new InputStreamReader(fis));

		String line = null; 

		while ((line = br.readLine()) != null ) {
			if (line.startsWith("####<")) {
				String currentTimeString = line.substring(5, 29);
				long currentTime = getTimeFromString(currentTimeString);
				if (previousTimeString == null) {
					previousTimeString = currentTimeString;
					previousTime = currentTime;
				}
				else {
					long timeDiff = currentTime - previousTime;
					if ( timeDiff > topDiff ) {
						topDiff = timeDiff;
						topTimeString = previousTimeString;
					}
					previousTime = currentTime;
					previousTimeString = currentTimeString;
				}

			}
		}
		System.out.println("topDiff=" + topDiff + " topTimeString=" + topTimeString);
	}

	/**
	 * Receives a "Aug 28, 2011 8:02:45 PM" and returns its Epoch
	 * @param timeAsString
	 * @return
	 * @throws Exception 
	 */
	public long getTimeFromString(String source) throws Exception {
		return formatter.parse(source).getTime();
	}



}




Monday, August 29, 2011

Causes for system failures

Today I heard an interesting real life experience from a production support engineer: he watched for 3 weeks a network which was failing every day around 5pm.



One day he casually noticed that the electrician on shift was taking his tea break, unplugging the network repeater and plugging his kettle...

Saturday, August 27, 2011

Installing OSB 10.3.4 on Ubuntu

The installation was not free from problems:

It is very well documented here:
http://soa-playground.blogspot.com/2011/03/oracle-service-bus-osb-on-ubuntu-linux.html

but something must be added:

ignore the warning you get about the insufficient swap space:

Starting Oracle Universal Installer...

Checking if CPU speed is above 300 MHz. Actual 2094 MHz Passed
Checking Temp space: must be greater than 150 MB. Actual 10273 MB Passed
Checking swap space: 509 MB available, 512 MB required. Failed <<<< Checking monitor: must be configured to display at least 256 colors. Actual 16777216 Passed Some requirement checks failed. You must fulfill these requirements before continuing with the installation, Continue? (y/n) [n] y



just say yes...


>>> Ignoring required pre-requisite failures. Continuing...
Preparing to launch Oracle Universal Installer from /tmp/OraInstall2011-08-27_02-56-56PM. Please wait ...
Please specify JRE/JDK location ( Ex. /home/jre ), /bin/java should exist :/ora1034/jdk160_21/
oracle@ubuntu:~/Downloads/osbgeneric/Disk1/install/linux$ Log: /home/oracle/oraInventory/logs/install2011-08-27_02-56-56PM.log
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found
sh: /bin/rpm: not found



just ignore the message "sh: /bin/rpm: not found"

Plenty of prerequisite checks fail... I could not find a way to display the cause of their failure. Yet if you click on the upper button (ignore the lowermost ones) "continue" the installation proceeds without other issues.... weird...






VMWare: autologon is not supported for this guest operating system


I am running Windows 7 64 bit and I get this message.... really weird... no time to investigate now... I can't find any info on the web...


Thursday, August 25, 2011

java.lang.ClassNotFoundException: com.bea.wli.config.deployment.server.ServerVersion

java.lang.ClassNotFoundException: com.bea.wli.config.deployment.server.ServerVersion

This error could indicate that a component was deployed on a cluster member but not other members of that cluster. Make sure that any component deployed on a server that is part of a cluster is also deployed on all other members of that cluster

Solution:

add
C:\Oracle2\Middleware\Oracle_OSB1\modules\com.bea.common.configfwk.wlinterop_10.3.1.0.jar

to the Server Start/ Classpath parameters of the Managed Server

If you get

FATAL ERROR in native method: JDWP No transports initialized, jvmtiError=AGENT_ERROR_TRANSPORT_INIT(197)

then you must set
set ALSB_DEBUG_FLAG=false
and
set debugFlag=false

in setDomainEnv.cmd (sh)



startWebLogic.cmd and other scripts

Often it's VERY confusing to find out the hierarchy of scripts:

$DOMAIN_HOME\startWebLogic.cmd ->
    %DOMAIN_HOME%\bin\startWebLogic.cmd ->
        %DOMAIN_HOME%\bin\setDomainEnv.cmd ->
           %WL_HOME%\common\derby\bin\startNetworkServer.cmd
           %WL_HOME%\common\bin\commEnv.cmd  ->
               %WL_HOME%\common\bin\setPatchEnv.cmd
           %DOMAIN_HOME%\bin\setOSBDomainEnv.cmd



$DOMAIN_HOME\bin\startManagedWebLogic.cmd ->
     %DOMAIN_HOME%\bin\startWebLogic.cmd


%WL_HOME%\server\bin\startNodeManager.cmd  ->
       %WL_HOME%\common\bin\commEnv.cmd

Wednesday, August 24, 2011

Cleaning up old OSB Proxy Services

OSB old proxy services still lingering around in deployments:

Sometimes even if you delete a Proxy Service, the deployment remains in the console:
C:\Oracle2\Middleware\user_projects\domains\osb_domain\sbgen\_ALSB_1314101342219.ear

even if the ear file doesn't exist;
in config.xml you find:

<app-deployment>
    <name>_ALSB_1314101342219</name>
    <target>myCluster</target>
    <module-type>ear</module-type>
    <source-path>sbgen\_ALSB_1314101342219.ear</source-path>
    <sub-deployment>
      <name>ejb.jar</name>
      <target>myCluster</target>
    </sub-deployment>
    <plan-dir>osb\config\plan</plan-dir>
    <plan-path>Plan-_ALSB_1314101342219.ear.xml</plan-path>
    <security-dd-model>DDOnly</security-dd-model>
    <staging-mode>nostage</staging-mode>
  </app-deployment>

workaround: just delete the entry from config.xml.

you should also remove the associated plan:

C:\Oracle2\Middleware\user_projects\domains\osb_domain\osb\config\plan\Plan-_ALSB_1314101342219.ear.xml

anyway all those EARs are normally deployed with staging-mode=stage (the case above is an exception), so you should check also in the DOMAIN_HOME/servers/SERVERNAME/stage folder. See also http://docs.oracle.com/cd/E23943_01/web.1111/e13702/deploy.htm#i1027041

The Administration Server first copies the deployment unit source files to the staging directories of target servers. (The staging directory is named stage by default, and it resides under the target server's root directory.) The target servers then deploy using their local copy of the deployment files.

Tuesday, August 23, 2011

WebLogic JMS Runtime Message Management in a Nutshell, by Kathiravan Sengodan

http://jeanfrancoisoracle.free.fr/Tools/JMS_Message_Management.doc

The document is really complete and exhaustive. Kudos, Kats!

ESB Architectures from SonicMQ

A series of videos about federated ESBs, from Sonic.

A bit too abstract, drawings really crappy, but quite captivating.

1:



2:



3:



4:



5:



6:



7:



8:






Sunday, August 21, 2011

Weblogic network channel bindings on multihomed servers

I have a cluster myCluster, Unicast,
For every managed server, I have created a Network Channel unicastChannel, supporting a single protocol "cluster-broadcast" (menu server/protocols/channels)

Even if I specify a ListenAddress - giving localhost or 127.0.0.1 as an address, WebLogic creates a ServerConnectionRuntime for each IP bound to my host (including the VMWare and VirtualBox IPs):

(Server/Monitoring/Channel)


This behavior is documented here

"If you use a network channel with a server instance on a multi-homed machine, you must enter a valid Listen Address either in ServerMBean or in the channel. If the channel and ServerMBean Listen Address are blank or specify the localhost address (IP address 0.0.0.0 or 127.*.*.*), the server binds the network channel listen port and SSL listen ports to all available IP addresses on the multi-homed machine."

If I enter "pierrepc" - that it the actual hostname - the binding is limited to 1 IP:




Log file rotation

In the Managed Server configuration, Logging, "Log file name" you can assign a file name.
If you say
"logs/myserver.log"

it will generate rotated filenames like

myserver.log00001


You can insert a timestamp information in the file name.

Example:
myserver_%yyyy%_%MM%_%dd%_%hh%_%mm%.log

The documentation says:

"To include a time and date stamp in the file name when the log file is rotated, add java.text.SimpleDateFormat variables to the file name. Surround each variable with percentage (%) characters.

For example, if the file name is defined to be myserver_%yyyy%_%MM%_%dd%_%hh%_%mm%.log, the log file will be named myserver_yyyy_mm_dd_hh_mm.log.

When the log file is rotated, the rotated file name contains the date stamp. For example, if the log file is rotated for the first time on 2 April, 2003 at 10:05 AM, the log file that contains the old messages will be named myserver_2003_04_02_10_05.log00001."



If you do not include a time and date stamp, the rotated log files are numbered in order of creation. For example, myserver.log00007.

However this is slightly incorrect:
myserver_%yyyy%_%MM%_%dd%_%hh%_%mm%.log

generates a rotated log file:
myserver_2011_08_21_12_22.log

and not
myserver_2011_08_21_12_22.log00001
as the documentation says.

Anyway the "Limit number of retained files" is respected, even is the progressive number is not the extension.




Saturday, August 20, 2011

OSB PKI credential mapper provider

There is no PKI credential mapper provider configured in your security realm. Service key provider management will be disabled. Configure a PKI credential mapper provider if you need service provider support. This is typically the case if you have Oracle Service Bus proxy services with web service security enabled or outbound 2-way SSL connections.


http://download.oracle.com/docs/cd/E17904_01/doc.1111/e15866/model.htm Security in OSB.


"If a proxy service uses public key infrastructure (PKI) technology for digital signatures, encryption, or SSL authentication, create a service key provider to provide private keys paired with certificates."

http://download.oracle.com/docs/cd/E17904_01/doc.1111/e15867/service_key_providers.htm#OSBAG982 Service Key Providers.

http://download.oracle.com/docs/cd/E17904_01/doc.1111/e15866/model.htm#OSBDV1498 how to create a PKI credential mapper in WLS

see this nice post http://tim.blackamber.org.uk/?p=831

First, use keytool to generate a JKS store. keytool.exe is in your JAVA_HOME/bin directory (example: C:\Oracle2\Middleware\jdk160_21\bin)

keytool -genkey -keystore keystorename -storepass keystorepassword
(enter all information, it will generate a keystorename file)
(default keystore type is "jks")

In WL console, go to your myrealm security realm, tab "Providers", "Credential Mappings",

there is a "DefaultCredentialMapper" "WebLogic Credential Mapping Provider".
Create a new one, of type "PKICredentialMapper", edit and go to "Provider Specific"
enter the name of the file you created with keytool (it should have been moved to the DOMAIN_HOME directory), and the password you assigned with keytool

RESTART THE SERVERS NOW

Now in OSB you can create a new Service Key Provider, and enter the 3 keys
Encryption Key , Digital Signature Key, SSL Client Authentication Key
providing the relative password.





Handy script to create a WL Server in a cluster

servername='ms3'
debugport='8890'
domainname='osb_domain'
clustername='myCluster'
listenport=7031



edit()
startEdit()
cd('/')
cmo.createServer(servername)

cd('/Servers/' + servername)
cmo.setListenAddress('')
cmo.setListenPort(listenport)
cmo.setCluster(getMBean('/Clusters/' + clustername))
cmo.setListenPortEnabled(true)
cmo.setAdministrationPort(9002)
cmo.setWeblogicPluginEnabled(false)
cmo.setJavaCompiler('javac')
cmo.setStartupMode('RUNNING')
cmo.setVirtualMachineName(domainname + '_' + servername)
cmo.setClientCertProxyEnabled(false)
cmo.setMachine(getMBean('/Machines/myMachine'))

cd('/Servers/' + servername + '/SSL/' + servername)
cmo.setEnabled(false)

cd('/Servers/' + servername + '/ServerDiagnosticConfig/' + servername)
cmo.setWLDFDiagnosticVolume('Low')

cd('/Servers/' + servername + '/ServerStart/' + servername)
cmo.setArguments('-Xms356m -Xmx1024m -XX:CompileThreshold=8000 -XX:PermSize=128m  -XX:MaxPermSize=512m -Dweblogic.debug.DebugUnicastMessaging=true -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port='+ debugport + ' -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dweblogic.unicast.HttpPing=true')



cd('/Servers/' + servername)
cmo.createNetworkAccessPoint('unicastChannel')

cd('/Servers/ms1/NetworkAccessPoints/unicastChannel')
cmo.setProtocol('cluster-broadcast')
cmo.setListenPort(listenport + 100)
cmo.setEnabled(true)
cmo.setHttpEnabledForThisProtocol(false)
cmo.setTunnelingEnabled(false)
cmo.setOutboundEnabled(true)
cmo.setTwoWaySSLEnabled(false)
cmo.setClientCertificateEnforced(false)


activate()


In order to run it, connect first to the AdminServer
connect('weblogic', 'welcome1', 't3://localhost:7001')




Friday, August 19, 2011

setting a WLDF watch to monitor a cluster

Here the official Oracle documentation on WLDF


Here my previous post on WLDF.



Here the WLST to create a WLDF Diagnostic Module with a watch on the number of members in the cluster:

domain=osb_domain
managed server=ms1
cluster=myCluster

It will generate a SNMP trap every time the number of AliveServerCount on ms1 is less than 3:

edit()
startEdit()
cd('/')
cmo.createWLDFSystemResource('ClusterMonitor')

cd('/SystemResources/ClusterMonitor')
cmo.setDescription('')

cd('/WLDFSystemResources/ClusterMonitor/WLDFResource/ClusterMonitor/Harvester/ClusterMonitor')
cmo.createHarvestedType('weblogic.management.runtime.ClusterRuntimeMBean')

cd('/WLDFSystemResources/ClusterMonitor/WLDFResource/ClusterMonitor/Harvester/ClusterMonitor/HarvestedTypes/weblogic.management.runtime.ClusterRuntimeMBean')
set('HarvestedAttributes',jarray.array([String('AliveServerCount'), String('CurrentSecondaryServer'), String('ForeignFragmentsDroppedCount'), String('FragmentsReceivedCount'), String('FragmentsSentCount'), String('MulticastMessagesLostCount'), String('PrimaryCount'), String('ResendRequestsCount'), String('SecondaryCount'), String('SecondaryServerDetails')], String))
set('HarvestedInstances',jarray.array([String('com.bea:Name=myCluster,ServerRuntime=ms1,Type=ClusterRuntime')], String))
cmo.setNamespace('ServerRuntime')

cd('/WLDFSystemResources/ClusterMonitor/WLDFResource/ClusterMonitor/WatchNotification/ClusterMonitor')
cmo.createWatch('clusterGone')

cd('/WLDFSystemResources/ClusterMonitor/WLDFResource/ClusterMonitor/WatchNotification/ClusterMonitor/Watches/clusterGone')
cmo.setRuleType('Harvester')
cmo.setEnabled(true)
cmo.setRuleExpression('(${ServerRuntime//[weblogic.management.runtime.ClusterRuntimeMBean]com.bea:Name=myCluster,ServerRuntime=ms1,Type=ClusterRuntime//AliveServerCount} < 3)')
cmo.setAlarmType('AutomaticReset')
cmo.setAlarmResetPeriod(60000)

cd('/WLDFSystemResources/ClusterMonitor/WLDFResource/ClusterMonitor/WatchNotification/ClusterMonitor')
cmo.createSNMPNotification('snmptrap')

cd('/WLDFSystemResources/ClusterMonitor/WLDFResource/ClusterMonitor/WatchNotification/ClusterMonitor/SNMPNotifications/snmptrap')
cmo.setEnabled(true)

cd('/WLDFSystemResources/ClusterMonitor/WLDFResource/ClusterMonitor/WatchNotification/ClusterMonitor/Watches/clusterGone')
set('Notifications',jarray.array([ObjectName('com.bea:Name=snmptrap,Type=weblogic.diagnostics.descriptor.WLDFSNMPNotificationBean,Parent=[osb_domain]/WLDFSystemResources[ClusterMonitor],Path=WLDFResource[ClusterMonitor]/WatchNotification[ClusterMonitor]/SNMPNotifications[snmptrap]')], ObjectName))

activate()


When the watch triggers, it logs this in the Server log:

####<16-Aug-2011 15:29:21 o'clock BST> <notice> <diagnostics> <pierrepc> <ms1> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <<wls Kernel>> <> <1b7e5955c26b51de:219aeffc:131d2f16195:-8000-0000000000000369> <1313504961943> <BEA-320068> <watch 'clusterGone' with severity 'Notice' on server 'ms1' has triggered at 16-Aug-2011 15:29:21 o'clock BST. Notification details: 
WatchRuleType: Harvester 
WatchRule: (${ServerRuntime//[weblogic.management.runtime.ClusterRuntimeMBean]com.bea:Name=myCluster,ServerRuntime=ms2,Type=ClusterRuntime//AliveServerCount} <3) ) 
WatchData: com.bea:Name=myCluster,ServerRuntime=ms1,Type=ClusterRuntime//AliveServerCount < 3  
WatchAlarmType: AutomaticReset 
WatchAlarmResetPeriod: 60000 
> 
If you need a free SNMP manager, download this Some snaphots here if you setup Watches and Notification through the WebLogic console: Selecting metrics to collect with the Harvester: select MBean
Selecting metrics to collect with the Harvester: select MBean attributes
selecting Managed Server instances from which to collect metrics
adding a clusterInTrouble notification which takes a diagnosticImage when the watch triggers:
assiging the clusterInTrouble notification to the clusterGone watch:







Admin on Sun, Managed on JRockit

Today I ended up in a weird situation:
my Admin was started with Sun JDK (JAVA_VENDOR=Sun)
but my Managed Servers were runnning on JRockit (JAVA_VENDOR=Oracle). They were started using Node Manager.

I have no clue how I have done that.
Anyway here is the fix to run everything with Sun (I hate Sun and I love JRockit, but some customers use Sun, so...):

in C:\Oracle\Middleware\wlserver_10.3\common\bin\commEnv.cmd :
@rem Reset JAVA Home
rem set JAVA_HOME=C:\Oracle2\Middleware\jrockit_160_22_D1.1.1-3
set JAVA_HOME=C:\Oracle2\Middleware\jdk160_21

rem set JAVA_VENDOR=Oracle
set JAVA_VENDOR=Sun


That's all.


So now the second part of this psychodrama:
With Sun JDK, the Managed Server fails with:

java.lang.OutOfMemoryError: PermGen space

In JRockit there is no concept of PermGen, so there is no need to worry about it. But Sun must be taught how to behave itself.

If you think that fixing the C:\Oracle2\Middleware\wlserver_10.3\common\bin\commEnv.cmd is enough, you are wrong:

I changed it by using
set MEM_ARGS=-Xms32m -Xmx1024m -XX:MaxPermSize=512m -XX:+UseSpinning

but this doesn't affect the way a Managed Server is run.
You must rather change the Server Start Arguments (beware, they are all mixed up in the same tab, the JVM parameters and the System parameters !)




Thursday, August 18, 2011

weblogic.unicast.HttpPing in Unicast clusters

If you have the impression that your Cluster Members are vanishing from the cluster and have difficulty joining it back, read this:

http://download.oracle.com/docs/cd/E21764_01/doc.1111/e15731/weblogic_server_issues.htm#CIHEAFDH

9.4.1 Threads Are Blocked on Cluster Messaging in Unicast Mode

When using Unicast mode for cluster communication, many threads are blocked on cluster messaging, which may result in cluster members having difficulty sending heartbeat messages. In this situation, some cluster members drop out from the cluster and may take some time to rejoin the cluster.

Workaround

Set the following system property to resolve this issue:

-Dweblogic.unicast.HttpPing=true




If any member of the cluster is down, you will see:

####<21-Aug-2011 12:36:30 o'clock BST> <debug> <unicastmessaging> <pierrepc> <ms1> <Timer-2> <<anonymous>> <> <> <1313926590111> <BEA-000000> <[HttpPingRoutine] HttpPing Caught IOException: java.net.SocketException: Socket Closed>


These messages follow the ping attempts:

####<21-Aug-2011 12:39:27 o'clock BST> <Debug> <UnicastMessaging> <pierrepc> <ms1> <[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1313926767511> <BEA-000000> <[UnicastFragmentSocket] sending ' server ms1, id=1313926767511' to local group>
####<21-Aug-2011 12:39:27 o'clock BST> <Debug> <UnicastMessaging> <pierrepc> <ms1> <[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1313926767511> <BEA-000000> <[Group] [LocalGroup [[ms1]]] we are the seniormost. Send message to group>
####<21-Aug-2011 12:39:27 o'clock BST> <Debug> <UnicastMessaging> <pierrepc> <ms1> <[ACTIVE] ExecuteThread: '2' for queue: 'weblogic.kernel.Default (self-tuning)'> <<WLS Kernel>> <> <> <1313926767512> <BEA-000000> <[Group] [LocalGroup [[ms1]]] we are the seniormost. Send message to group>

The SocketException will go away once you start all members of the cluster.


if you get this:


####<21-Aug-2011 13:11:59 o'clock BST> <Warning> <Socket> <pierrepc> <ms1> <ExecuteThread: '2' for queue: 'weblogic.socket.Muxer'> <<WLS Kernel>> <> <> <1313928719011> <BEA-000442> <Connection attempt was rejected because the incoming protocol is not enabled on channel "unicastChannel".>

here is what they say : enable the protocol on the channel



And if you get this:


####<21-Aug-2011 13:12:05 o'clock BST> <Debug> <UnicastMessaging> <pierrepc> <ms1> <Timer-2> <<anonymous>> <> <> <1313928725736> <BEA-000000> <[HttpPingRoutine] HttpPing Caught IOException: java.io.EOFException: Response contained no data>


then you might try this (as suggested here): -Dhttp.keepAlive=false (it didn't work for me :o( )

Here http://download.oracle.com/docs/cd/E12840_01/wls/docs103/issues/known_resolved.html they mention that in pre 10.3 versions of WebLogic the cluster gets in trouble when you suspend one of the Managed Servers. This is known as CR370084, yet the workaround of setting -Dweblogic.unicast.HttpPing=true is recommended only for test environments.






DevPollSocketMuxer was built on Apr 25 2007 15:08:20.... why should I care?

As explained very well by Jose Kuzhivelil
http://jojovedder.blogspot.com/2009/05/weblogic-socket-muxers-are-not-stuck.html

"The socket Muxer manages the server’s existing socket connections.
It first determines which sockets have incoming requests waiting to be processed. It then reads enough data to determine the protocol and dispatches the socket to an appropriate runtime layer based on the protocol.
In the runtime layer, the socket muxer threads determine which execute thread queue to be used and delegates the request accordingly."


Another great post on the Muxer topic is this

http://m-button.blogspot.com/2008/08/how-does-weblogic-handle-socket-muxers.html

An alternative to DevPollSocketMuxer is PosixSocketMuxer on Unix, and NTSocketMuxer on Windows



HttpPingRoutineImpl and wls_does_not_exist_url

cd C:\Oracle2\Middleware\user_projects\domains\osb_domain\bin
setDomainEnv.cmd


java weblogic.cluster.messaging.internal.HttpPingRoutineImpl -host localhost -port 7001

if the server is running, this returns:
HttpPing returns: 1

otherwise
HttpPing returns: 0


This routine try to establish a URLConnection to
http://host:port/wls_does_not_exist_url

of course wls_does_not_exist_url simply doesn't exist, but if the WL server is running you get a HTTP 404, while if it's not running you get an HTTP error code between 300 and 400, or between 500 and 600.

This routing is used in the cluster members discovery mechanism.

When you see "starting remote group discovery" in the log, you are in
weblogic.cluster.messaging.internal.GroupImpl, then calls PingRoutine.ping

If the property weblogic.unicast.HttpPing is set, you use the HttpPingRoutine, otherwise the Socket-based PingRoutine

To debug all the messages set the weblogic.debug.DebugUnicastMessaging property.

You can set timeout values on these pings with these System properties:

httpPing.connectTimeout (default "3000")

httpPing.readTimeout (default "6000")



There are some cluster parameters you can try to tune if your "starting remote group discovery" is taking too long:

Member Warmup Timeout:
"Maximum number of seconds that a cluster member will wait to discover and synchronize with other servers in the cluster. Normally, the member will be able to sync in 30 seconds. If the value of this attribute is higher, that does not necessarily mean that it will take longer for the member to warmup. Instead it defines an upper bound on the time that a server will wait to sync with the servers that it has discovered. If the value is set 0, servers will not attempt to discover other running server in the cluster during server initialization"






NON-BLOCKING java entropy configuration

Today these lines caught my attention in the WL MS log:

####<17-Aug-2011 22:53:41 o'clock BST> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <> <> <> <1313618021317> "securerandom.source= file:/dev/urandom"; Blocking Config= false; JDK version= 1.6.0_22; Operating System= Windows 7.>
####<17-Aug-2011 22:53:41 o'clock BST> <[ACTIVE] ExecuteThread: '0' for queue: 'weblogic.kernel.Default (self-tuning)'> <> <> <> <1313618021319> <Detected NON-BLOCKING java entropy configuration. This setting will provide the best performance on machines with few sources of entropy, but is less secure than a blocking entropy configuration.>


Random number generation - necessary to the encryption framework - can be a source of slowness in WebLogic startup
http://www.itonguard.com/20090313/weblogic-starts-slow/

so it's better to keep an eye on this setting.

See here http://download.oracle.com/javase/1.4.2/docs/guide/security/jaas/JAASRefGuide.html#AppendixA

"# The entropy gathering device is described as a URL and can
# also be specified with the property "java.security.egd". For example,
# -Djava.security.egd=file:/dev/urandom
# Specifying this property will override the securerandom.source setting."



See also this post of mine (I am getting old, I keep repeating the same stuff over and over!)



Unicast Cluster, reconnecting servers

Create a cluster myCluster with 3 MS: ms1, ms2, ms3
Create a unicastChannel on the 3 MS to dedicate for the unicast communication.

#connect to NodeManager
nmConnect('weblogic', 'welcome1', 'localhost', '5556', 'osb_domain', 'C:/Oracle2/Middleware/user_projects/domains/osb_domain')

#start ms1
nmStart('ms1')
#connect to ms1
connect('weblogic', 'welcome1', 't3://localhost:7011')

cd('/ClusterRuntime/myCluster/')
ls()


you should get:
AliveServerCount=1
ServerNames=java.lang.String[ms1]

Start ms2:
nmStart('ms2')

ls()

you should get:
AliveServerCount=2
ServerNames=java.lang.String[ms2,ms1]


nmKill('ms2')

Successfully killed server ms2 ...

ls

AMAZING:
AliveServerCount=2
ServerNames=java.lang.String[ms2,ms1]


how can it be... we have just killed ms2!

In fact, it takes some time for ms1 to notice that ms2 is dead. After some more seconds, you get
AliveServerCount=1
ServerNames=java.lang.String[ms1]
as it should be.






nmConnect: weblogic.nodemanager.NMException: Configuration error while reading domain directory

The command syntax for nmConnect() is:

nmConnect([username, password], [host], [port], [domainName], [domainDir], [nmType])

example:

nmConnect('weblogic', 'welcome1', 'localhost', '5556', 'osb_domain', 'C:/Oracle2/Middleware/user_projects/domains/osb_domain')


see also http://www.javamonamour.org/2013/07/configuration-error-while-reading.html





Wednesday, August 17, 2011

Oracle Guardian JVM terminated exit code -1

I am trying to run Guardian on my 64bit Windows..... no matter which heap parameters I put in the guardian.ini file, it keeps failing on startup with this error:




I have really no clue how to proceed.

Even
guardianHeadless.cmd -g help

fails with the same error.

I have tried providing a 32bit JVM, to no avail.

Funnily, the Linux installation works without a glitch.

WLST, redirecting all output to a file

if you do
redirect('myfile.lot')
the result of "print" statements will still go to stdout.

If you do

from java.io import File
from java.io import FileOutputStream
f = File("./wlst.log")
fos = FileOutputStream(f)
theInterpreter.setOut(fos)
print "start the script"

(see https://forums.oracle.com/forums/thread.jspa?threadID=826716)

you will be able to send everything to the file.

The problem is how to get back to normal mode of operations... apart from restarting WLST, I mean.
One way could be
prev = theInterpreter.getOut()
theInterpreter.setOut(fos)
....
theInterpreter.setOut(prev)





Book: Professional Oracle WebLogic Server

http://www.amazon.com/Professional-Oracle-WebLogic-Server-Programmer/dp/0470484306


Awesome technical content, a must have for all WebLogic professionals.

Friday, August 12, 2011

OSB customization from a environment dependent property file with WLST

I proceed as follows:

- create customization file from OSB console
- replace all environment dependent values (mostly URIs) with tokens:

{$REPLACE_PROPERTY_MQ_QUEUE}

- create a import.properties."env" file ("env" depends on the environment you are targetting)

in this property file you have:

adminUrl=t3://localhost:7009
importUser=pierluigi
importPassword=welcome1

customizationFile=ALSBCustomizationFile.xml

REPLACE_PROPERTY_MQ_QUEUE=VALUE_TO_BE_USED_IN_THIS_ENV
#here all other properties, they must start with REPLACE_PROPERTY_
REPLACE_PROPERTY_HOST=acme.com


run the customize.py script :

cd $DOMAIN_HOME/wlstscripts

. $DOMAIN_HOME/bin/setDomainEnv.sh

java weblogic.WLST customize.py dev


for tst, the file will be import.properties.tst and you call

java weblogic.WLST customize.py tst

customize.py (largely copied from import.py provided by Oracle):

from java.util import HashMap
from java.util import HashSet
from java.util import ArrayList
from java.io import FileInputStream

from com.bea.wli.sb.util import Refs
from com.bea.wli.config.customization import Customization
from com.bea.wli.sb.management.importexport import ALSBImportOperation

import fileinput


import sys

#=======================================================================================
# Entry function to customize a ALSB domain
#=======================================================================================

def customizeDomain(envname):
    try:
        SessionMBean = None
        importConfigFile = 'import.properties.' + envname
        print 'Loading Deployment config from :', importConfigFile
        exportConfigProp = loadProps(importConfigFile)
        adminUrl = exportConfigProp.get("adminUrl")
        importUser = exportConfigProp.get("importUser")
        importPassword = exportConfigProp.get("importPassword")

        customFile = exportConfigProp.get("customizationFile")

        connectToServer(importUser, importPassword, adminUrl)

        print 'Attempting to customize ALSB Admin Server listening on :', adminUrl


        configProperties = loadProps('import.properties.' + envname)

        #select only properties starting with REPLACE_
        mylist = Properties()
        for property in configProperties:
            if property.startswith('REPLACE_'):
                mylist.put(property, configProperties.get(property))



        targetCustomizationFile = customFile + envname + '.xml'	 

        output=open(targetCustomizationFile, 'w')

        #read all lines and replace all tokens
        for line in fileinput.input([customFile]):
           for property in mylist:
               line = line.replace('{$' + property + '}', mylist.get(property))
           output.write(line)

        output.close()

		
		
        sessionName = createSessionName()
        print 'Created session', sessionName
        SessionMBean = getSessionManagementMBean(sessionName)
        print 'SessionMBean started session'
        ALSBConfigurationMBean = findService(String("ALSBConfiguration.").concat(sessionName), "com.bea.wli.sb.management.configuration.ALSBConfigurationMBean")
        print "ALSBConfiguration MBean found", ALSBConfigurationMBean
       

        #customize if a customization file is specified
        #affects only the created resources
        if customFile != None :
            print 'Loading customization File', targetCustomizationFile
            iStream = FileInputStream(targetCustomizationFile)
            customizationList = Customization.fromXML(iStream)
            ALSBConfigurationMBean.customize(customizationList)

        SessionMBean.activateSession(sessionName, "Complete customization using wlst")

    except:
        print "Unexpected error:", sys.exc_info()[0]
        if SessionMBean != None:
            SessionMBean.discardSession(sessionName)
        raise

#=======================================================================================
# Utility function to load properties from a config file
#=======================================================================================

def loadProps(configPropFile):
    propInputStream = FileInputStream(configPropFile)
    configProps = Properties()
    configProps.load(propInputStream)
    return configProps

#=======================================================================================
# Connect to the Admin Server
#=======================================================================================

def connectToServer(username, password, url):
    connect(username, password, url)
    domainRuntime()


#=======================================================================================
# Utility function to create an arbitrary session name
#=======================================================================================
def createSessionName():
    sessionName = String("SessionScript"+Long(System.currentTimeMillis()).toString())
    return sessionName

#=======================================================================================
# Utility function to load a session MBeans
#=======================================================================================
def getSessionManagementMBean(sessionName):
    SessionMBean = findService("SessionManagement", "com.bea.wli.sb.management.configuration.SessionManagementMBean")
    SessionMBean.createSession(sessionName)
    return SessionMBean



# IMPORT script init
try:
    # import the service bus configuration
    # argv[1] is the environment you are customizing
    customizeDomain(sys.argv[1])

except:
    print "Unexpected error: ", sys.exc_info()[0]
    dumpStack()
    raise





The WLST task can be run from Ant of course...



Wednesday, August 10, 2011

WLST for OSB

I had some trouble running the wlst.sh script associated with OSB:

. $ORACLE_HOME/Oracle_OSB1/common/bin/wlst.sh

I get:

$ORACLE_HOME ... wlserver_10.3/common/bin/wlst.sh: line 23: /bin/java: No such file or directory

in fact JAVA_HOME was not defined. Weird, because if I do "echo $JAVA_HOME" I get a valid value.

Well, wlst.sh invokes a bunch os other shell scripts, and one of them resets JAVA_HOME if JAVA_VENDOR is not defined. No warning given. Grunt!

So, you need to
export JAVA_VENDOR=Sun

before you run the script.


Yet when I use this version of wlst.sh to rnu the import.py, I get an error:
ImportError: no module named wli


At this point I would rather use the traditional way:

(make sure you type the leading ".")
. $ORACLE_HOME/user_projects/domains/mydomain/bin/setDomainEnv.sh
java weblogic.WLST


which works without any issue.

Weird-oh.



Generating graphs in Java

Here I was mentioning some products.

Generating directly the GraphML XML in Java is a pain. Too awkward.


Here an example of how to generate a basic graph in Java using yFiles of yWorks.
It looks really professional and impressive, but the licence is very expensive.

http://en.wikipedia.org/wiki/YEd

http://en.wikipedia.org/wiki/GraphML

Other interesting products:

http://www.jgrapht.org/

http://www.graphviz.org/Gallery.php
http://www2.research.att.com/~john/Grappa/


As by comments, Cytoscape seems also very professionally done.


Tuesday, August 9, 2011

OSB Javadoc

wew, I finally managed to write a tool to generate "Javadoc" from a sbconfig.jar file.

It outputs a HTML file with each entry in the sbconfig.jar, description, list of efferent and afferent artifacts with hyperlink to them...

pretty cool!


example:

GlobalResources/ACMEEventMQ.MQConnection MQ connection to read messages from MQ Server
Uses:
    GlobalResources/a447.sa

Is used by:
    GlobalResources/ACMEMQBS.BusinessService


GlobalResources/a447.ServiceAccount security credentials to access mq queue
Uses:


Is used by:
    GlobalResources/ACMEEventMQ.MQConnection

org.xml.sax.SAXParseException: Premature end of file

http://www.danielschneller.com/2008/01/saxparseexception-1-1-premature-end-of.html

exactly as he says: when using a XPathAccessor, you cannot reuse the InputSource.
Bummer.
Crap.


OSB: description getting lost in Import/Export process

If you create an XQuery in OSB Console, you assign a description to it,
and export it to a sbconfig.jar file, it is packaged this way:



<?xml version="1.0" encoding="UTF-8"?>
<con:xqueryEntry xmlns:con="http://www.bea.com/wli/sb/resources/config">
<con:description>la mia mamma</con:description>
<con:xquery><ciao/></con:xquery>
</con:xqueryEntry>


But if you import this sbconfig.jar into Eclipse, and export it again to another sbconfig.jar, the description is lost.

The same goes for Project-level descriptions - stored in the LocationData file.

Under certain circumstances the description goes into the ExportInfo file....
For instance for a MQConnection you have this entry in the ExportInfo file:
imp:property name="custom DESC" value="MQ connection to read messages from MQ Server"


Incidentally in the sbconfig.jar "description" can be stored as:

con:description where con="http://www.bea.com/wli/sb/resources/config" (in WSDL)

ser:description where ser="http://www.bea.com/wli/sb/services" (in Proxy Services)

proj:description where proj="http://www.bea.com/wli/config/project" (in LocationData)

aler:description where aler="http://www.bea.com/wli/monitoring/alert" (in Alerts)





Monday, August 8, 2011

QBrowser for WebLogic - keep your JMS queues under surveillance

http://sourceforge.net/projects/qbrowserv2/

open run_wls_mq.bat and add:

set WL_HOME=C:\Oracle\Middleware\wlserver_10.3

it's really cool!

If you compare it to HermesJMS, it's so much simpler to setup!


Sunday, August 7, 2011

Using the JMS Request/Reply service

Create a RRBS, Any XML, protocol JMS,
URL jms://localhost:7001/weblogic.jms.XAConnectionFactory/RRPSRequest (it's the Queue on which the RRPS listens)

Response Queue: One for all Request URIs
Response Pattern : JMSCorrelationID
Response URI: jms://localhost:7001/weblogic.jms.XAConnectionFactory/RRPSResponse



Create a HTTP Any XML Request/Reply "entryWS", route to RRBS ("pass all headers")

So:

Proxy Service entryWS writes to Business Service RRBS
Business Service RRBS writes to Queue RRPSRequest
Proxy Service RRPS reads from Queue RRPSRequest and writes to Queue RRPSResponse
Business Service RRBS reades from Queue RRPSResponse and returns to entryWS


If you log $inbound, you will see that the RRBS sets a correlation Id on the message sent to RRPSRequest.
The messageId of the message in RRPSRequest is different from the messageId in the message in RRPSResponse, but the correlationId is the same.
The correlationId is required by the RRBS to match the response to the request on the 2 Queues.

Here the OSB jar file with the code

Oracle Service Bus JMS request reply with correlationId

http://download.oracle.com/docs/cd/E13159_01/osb/docs10gr3/interopjms/transport.html


http://eelzinga.wordpress.com/2009/10/28/oracle-service-bus-jms-requestresponse-pattern/

So here we go:

create a project "MyRRJMS"

create a PS "RRPS",
Any XML Service,
protocol=JMS,
endpoint URL="jms://localhost:7001/weblogic.jms.XAConnectionFactory/RRPSRequest",
is response required=yes,
response pattern=JMSCorrelationID,
response URL="jms://localhost:7001/weblogic.jms.XAConnectionFactory/RRPSResponse"

the moment you activate the session, in the Server's JNDI tree you find 2 new objects with Binding Name:
RRPSRequest (weblogic.jms.common.DestinationImpl)
RRPSResponse (weblogic.jms.common.DestinationImpl)

Where do they come from? Look at
C:\Oracle2\Middleware\user_projects\domains\osb_domain\config\jms\xbusResources-jms.xml and there they are, all the JMS resources are declared in there.

You find out also that in
C:\Oracle2\Middleware\user_projects\domains\osb_domain\servers\AdminServer\tmp\_WL_user\_ALSB_1312707027768\6v4trg\META-INF

you have an exploded EAR with

application.xml =

<?xml version='1.0' encoding='UTF-8'?>
<jav:application xmlns:jav="http://java.sun.com/xml/ns/javaee">
  <jav:display-name>ProxyService MyRRJMS/RRPS</jav:display-name>
  <jav:module>
    <jav:ejb>ejb.jar</jav:ejb>
  </jav:module>
</jav:application>


and a weblogic-application.xml:

<?xml version='1.0' encoding='UTF-8'?>
<web:weblogic-application xmlns:web="http://xmlns.oracle.com/weblogic/weblogic-application">
  <web:ejb>
    <web:start-mdbs-with-application>false</web:start-mdbs-with-application>
  </web:ejb>
  <web:application-param>
    <web:param-name>service-ref</web:param-name>
    <web:param-value>ProxyService$MyRRJMS$RRPS</web:param-value>
  </web:application-param>
  <web:listener>
    <web:listener-class>com.bea.wli.sb.transports.jms.JmsEndPointAppListener</web:listener-class>
  </web:listener>
</web:weblogic-application>

and the ejb.jar contains:


weblogic-ejb-jar.xml:

<?xml version='1.0' encoding='UTF-8'?>
<web:weblogic-ejb-jar xmlns:web="http://xmlns.oracle.com/weblogic/weblogic-ejb-jar">
  <web:weblogic-enterprise-bean>
    <web:ejb-name>RequestEJB-2434504941437409959-3df8b25b.131a331d3f9.-7fdb</web:ejb-name>
    <web:message-driven-descriptor>
      <web:pool>
        <web:max-beans-in-free-pool>1000</web:max-beans-in-free-pool>
        <web:initial-beans-in-free-pool>1</web:initial-beans-in-free-pool>
      </web:pool>
      <web:destination-jndi-name>RRPSRequest</web:destination-jndi-name>
      <web:provider-url>t3://localhost:7001</web:provider-url>
      <web:connection-factory-jndi-name>weblogic.jms.XAConnectionFactory</web:connection-factory-jndi-name>
    </web:message-driven-descriptor>
    <web:transaction-descriptor>
      <web:trans-timeout-seconds>600</web:trans-timeout-seconds>
    </web:transaction-descriptor>
    <web:resource-description>
      <web:res-ref-name>jms/ConnectionFactory</web:res-ref-name>
      <web:jndi-name>weblogic.jms.XAConnectionFactory</web:jndi-name>
    </web:resource-description>
    <web:resource-description>
      <web:res-ref-name>jms/QueueName</web:res-ref-name>
      <web:jndi-name>RRPSRequest</web:jndi-name>
    </web:resource-description>
  </web:weblogic-enterprise-bean>
  <web:weblogic-enterprise-bean>
    <web:ejb-name>ResponseEJB-2434504941437409959-3df8b25b.131a331d3f9.-7fdb</web:ejb-name>
    <web:message-driven-descriptor>
      <web:pool>
        <web:max-beans-in-free-pool>1000</web:max-beans-in-free-pool>
        <web:initial-beans-in-free-pool>1</web:initial-beans-in-free-pool>
      </web:pool>
      <web:destination-jndi-name>RRPSResponse</web:destination-jndi-name>
      <web:provider-url>t3://localhost:7001</web:provider-url>
      <web:connection-factory-jndi-name>weblogic.jms.XAConnectionFactory</web:connection-factory-jndi-name>
    </web:message-driven-descriptor>
    <web:transaction-descriptor>
      <web:trans-timeout-seconds>600</web:trans-timeout-seconds>
    </web:transaction-descriptor>
    <web:resource-description>
      <web:res-ref-name>jms/ConnectionFactory</web:res-ref-name>
      <web:jndi-name>weblogic.jms.XAConnectionFactory</web:jndi-name>
    </web:resource-description>
    <web:resource-description>
      <web:res-ref-name>jms/QueueName</web:res-ref-name>
      <web:jndi-name>RRPSResponse</web:jndi-name>
    </web:resource-description>
  </web:weblogic-enterprise-bean>
  <web:disable-warning>BEA-010001</web:disable-warning>
  <web:disable-warning>BEA-010054</web:disable-warning>
  <web:disable-warning>BEA-010200</web:disable-warning>
  <web:disable-warning>BEA-010202</web:disable-warning>
</web:weblogic-ejb-jar>


and ejb-jar.xml

<?xml version='1.0' encoding='UTF-8'?>
<jav:ejb-jar xmlns:jav="http://java.sun.com/xml/ns/javaee">
  <jav:display-name>BEA ALSB JMS Inbound Endpoint</jav:display-name>
  <jav:enterprise-beans>
    <jav:message-driven>
      <jav:display-name>BEA ALSB JMS Inbound Endpoint (Request)</jav:display-name>
      <jav:ejb-name>RequestEJB-2434504941437409959-3df8b25b.131a331d3f9.-7fdb</jav:ejb-name>
      <jav:ejb-class>com.bea.wli.sb.transports.jms.JmsInboundMDB</jav:ejb-class>
      <jav:transaction-type>Container</jav:transaction-type>
      <jav:message-destination-type>javax.jms.Queue</jav:message-destination-type>
      <jav:env-entry>
        <jav:env-entry-name>service-ref</jav:env-entry-name>
        <jav:env-entry-type>java.lang.String</jav:env-entry-type>
        <jav:env-entry-value>ProxyService$MyRRJMS$RRPS</jav:env-entry-value>
      </jav:env-entry>
      <jav:env-entry>
        <jav:env-entry-name>XA-supported</jav:env-entry-name>
        <jav:env-entry-type>java.lang.Boolean</jav:env-entry-type>
        <jav:env-entry-value>true</jav:env-entry-value>
      </jav:env-entry>
      <jav:env-entry>
        <jav:env-entry-name>checksum</jav:env-entry-name>
        <jav:env-entry-type>java.lang.Integer</jav:env-entry-type>
        <jav:env-entry-value>-319661414</jav:env-entry-value>
      </jav:env-entry>
    </jav:message-driven>
    <jav:message-driven>
      <jav:description>BEA ALSB JMS Inbound Endpoint (Response) (AdminServer)</jav:description>
      <jav:ejb-name>ResponseEJB-2434504941437409959-3df8b25b.131a331d3f9.-7fdb</jav:ejb-name>
      <jav:ejb-class>com.bea.wli.sb.transports.jms.JmsAsyncResponseMDB</jav:ejb-class>
      <jav:transaction-type>Container</jav:transaction-type>
      <jav:message-destination-type>javax.jms.Queue</jav:message-destination-type>
      <jav:activation-config>
        <jav:activation-config-property>
          <jav:activation-config-property-name>messageSelector</jav:activation-config-property-name>
          <jav:activation-config-property-value>JMSCorrelationID LIKE 'ID:424541534594cf52%'</jav:activation-config-property-value>
        </jav:activation-config-property>
      </jav:activation-config>
      <jav:env-entry>
        <jav:env-entry-name>service-ref</jav:env-entry-name>
        <jav:env-entry-type>java.lang.String</jav:env-entry-type>
        <jav:env-entry-value>ProxyService$MyRRJMS$RRPS</jav:env-entry-value>
      </jav:env-entry>
      <jav:env-entry>
        <jav:env-entry-name>XA-supported</jav:env-entry-name>
        <jav:env-entry-type>java.lang.Boolean</jav:env-entry-type>
        <jav:env-entry-value>true</jav:env-entry-value>
      </jav:env-entry>
    </jav:message-driven>
  </jav:enterprise-beans>
  <jav:assembly-descriptor>
    <jav:container-transaction>
      <jav:method>
        <jav:ejb-name>RequestEJB-2434504941437409959-3df8b25b.131a331d3f9.-7fdb</jav:ejb-name>
        <jav:method-name>*</jav:method-name>
      </jav:method>
      <jav:trans-attribute>Required</jav:trans-attribute>
    </jav:container-transaction>
    <jav:container-transaction>
      <jav:method>
        <jav:ejb-name>ResponseEJB-2434504941437409959-3df8b25b.131a331d3f9.-7fdb</jav:ejb-name>
        <jav:method-name>*</jav:method-name>
      </jav:method>
      <jav:trans-attribute>Required</jav:trans-attribute>
    </jav:container-transaction>
  </jav:assembly-descriptor>
</jav:ejb-jar>


To inject messages in the Request queue, write a Business Service "writeToRequestQueue"

Any XML Service
protocol=JMS
Endpoint URI=jms://localhost:7001/weblogic.jms.XAConnectionFactory/RRPSRequest
No response

To read messages from the Response queue, write a Proxy Service "readFromResponseQueue"

Any XML Service
protocol=JMS
Endpoint URI=jms://localhost:7001/weblogic.jms.XAConnectionFactory/RRPSResponse
No response
in its Message Flow, add a pipeline, stage, add action "log" expression "$body"

Everything is operational: when you writeToRequestQueue, the message is consumed by the RRPS, put to the ResponseQueue where it is consumed by readFromResponseQueue.

So what is the big deal, we could have achieved the same without all this circus of Request/Reply and correlationId. Where is the correlationId by the way?
We will discover all this in the next installment.

Saturday, August 6, 2011

Muppets, the beauty of Counterpoint, Hans Christian Andersen and the inchworm

http://www.youtube.com/v/xZivb3zjlo0

starting from minute 2 and 24 seconds

(embedding disabled by request)


So much beauty and harmony in a small song

http://en.wikipedia.org/wiki/Inchworm_%28song%29


Two and two are four
Four and four are eight
Eight and eight are sixteen
Sixteen and sixteen are thirty-two


Here the original (not as harmonious as the Muppets')



Dependency analysis in a set of OSB Projects

It is very important to keep track of dependencies in a OSB project.

* Who does what
* Who uses what
* Who is used by whom

In a sbconfig.jar, ExportInfo contains all info on the dependencies amongst artifacts, using a list of properties "extrefs"


NB: in order to evaluate these XPaths with XmpSpy/Xml/Evaluate XPath, you might have to tweak the document adding xmlns:imp definition to the root element:

xml-fragment name="" version="v2" xmlns:imp="http://www.bea.com/wli/config/importexport"



Xpath to retrieve all artifacts:
/xml-fragment/imp:exportedItemInfo/@instanceId

Xpath to retrieve all artifacts of a given type:
/xml-fragment/imp:exportedItemInfo[@typeId='Xquery']/@instanceId


Xpath to retrieve all dependencies of a given artifact:
/xml-fragment/imp:exportedItemInfo[@instanceId='InterfacesBLA/CommonSchemas/FilterTypes']/imp:properties/imp:property[@name='extrefs']/@value


At this point it's not difficult to write a small HTML Report Writer who formats all this info in a nice way

Friday, August 5, 2011

Upgrading to Hudson 2.1.0

I am very pleased for this upgrade:

* support of Maven 3.0.3 (cool)
* improved statistics on the build
* Maven 3 view of artifacts
* One click access to last build console output
* Possibility to rename Jobs (

http://hudson-ci.org/

What is new in Hudson 2.1.0:
http://hudson-ci.org/docs/news.html

Hudson complete guide

Quick and dirty mavenization of a non-Maven project with plenty of JARs

Problem is: I have lots of JARs which I cannot express as dependency.
I know that including JARs in SVN is BAD, BUT...
I know that using scope=system in Maven is BAD, BUT...


Following this link

I write this tool to generate me the dependencies:

import java.io.File;


public class PrintPOM {
 public static void main(String[] args) {
  File dir = new File("C:\\pierre\\maventests\\GUFunctionalTests\\lib");
  for (File file : dir.listFiles()) {
   if (file.getName().endsWith(".jar")) {
    System.out.println("");
    System.out.println("mylibs");
    System.out.println("" + file.getName() + "");
    System.out.println("1.0");
    System.out.println("system");
    System.out.println("${project.basedir}/lib/" + file.getName() + "");
    System.out.println("");
   }
  }

 }
}


and I stick the result in my pom.xml (its POM, not PORN, you dirty man)

Here the POM documentation page, priceless!

hudson.tasks.test.TestResult error

java.lang.ClassCastException: hudson.tasks.test.AggregatedTestResultPublisher$TestResultAction cannot be cast to hudson.tasks.test.TestResult


now I understand why my JUnit tests were not showing in the "Test Result Trend" graph... WTF....

I clean up all the past files, including the exploded war, and restart Hudson...

Now the "Test Result Trend" is showing... hurrah!

Java classpath: get all JARs in a folder

Perhaps not everybody know that

java -cp "lib/*" YourClassHere

builds a classpath with ALL the JARs in the lib folder. Cool! No more horrible shell scripts to dynamically build a CLASSPATH.

Thursday, August 4, 2011

Java XPath evaluation

I have put together a simple XPath parser.

Everything is very easy as long as you don't use Namespaces.

Here is a very nice trick to extract a NamespaceContext from the document you are parsing.

The alternative is providing your own implementation of NamespaceContext, either this way (see "public class MyNamespaceContext") or as shown in this post with NamespaceContextMap class

My first instance was using:

Document xmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile);

XPath xPath = XPathFactory.newInstance().newXPath();
NamespaceContext nsContext = new NamespaceContextMap("foo", "http://foo","bar", "http://bar", "def", "http://def");

xPath.setNamespaceContext(nsContext);
String expression = ".//con3:xqueryTransform/con3:resource[1]/@ref";
XPathExpression xPathExpression = xPath.compile(expression);
return xPathExpression.evaluate(xmlDocument, XPathConstants.STRING);




Well, it doesn' work. Using "Document xmlDocument" in xPathExpression.evaluate fails to interpret namespaces.

I had to convert it to:
InputSource inputSource = new InputSource(xmlFile);
...
return xPathExpression.evaluate(inputSource, XPathConstants.STRING);


to make it work.

Amazing.

2 hours wasted.

I love XML, Xpaths and so on. What a solid technology.

This is Software Development

maintaining balance under lot of solicitation and in a team
courage, imagination, perseverance




Wednesday, August 3, 2011

Ant, Junit and the forked JVM

I have a classpath defined as:


<path id="classpath.test">
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
<pathelement location="/path/to/user_projects/domains/acme_osb/config/osb/"/>
</path>


I can trace it this way:

<echo message="${toString:classpath.test}"/>


and I use it in a junit task

<junit printsummary="true">
<classpath refid="classpath.test" />
<formatter type="brief" usefile="false"/>
<test name="com.acme.gu.ft.GUFT" outfile="junitout/GUFT">
<formatter type="xml"/>
</test>
</junit>



The alarming thing is that the Unit test is run NOT with the classpath I specify (classpath.test), but with the classpath being used to run ant.

I can trace it with System.getProperty("java.class.path")


The only way to run the Unit Test with the new Classpath is by specifying fork="on"

<junit printsummary="true" fork="on">


one hour wasted for this....

Installing OSB 11.1.1.4 on Windows 7 64bit

Download JDK 6 64 Bit and install it http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u26-download-400750.html

Download Weblogic 11.1.1.4 GENERIC, if it saves it as .ZIP just rename it to .JAR, then run "java -jar wls1034_generic.jar" and install it http://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-main-097127.html

Download and install OSB 11.1.1.4 generic (ofm_osb_generic_11.1.1.4.0_disk1_1of1), and run the 64 bit installer using the 64 bit JDK

Download OEPE 11.1.1.6.1 (!!!!!) http://www.oracle.com/technetwork/developer-tools/eclipse/downloads/oepe-1116-161753.html and unzip it to C:\Oracle64\Middleware\oepe_11gR1PS3

see here http://forums.oracle.com/forums/thread.jspa?threadID=2254372&tstart=0&messageID=9749311
here http://forums.oracle.com/forums/thread.jspa?threadID=1088517
here http://forums.oracle.com/forums/thread.jspa?threadID=2214239&tstart=165


all of a sudden I feel old and tired

Tuesday, August 2, 2011

Firefox REST plugin made in China

https://addons.mozilla.org/en-US/firefox/addon/restclient/

https://github.com/chao/RESTClient


just install it, restart Firefox, then enter

chrome://restclient/content/restclient.xul

(I know, we are using Firefox, not chrome...)

and it's pretty straightforward to use.... EXCELLENT STUFF!

You can do simple POST. I can't think of anything simpler to use.

Remember that for SOAP request you must post the entire SOAP Envelope:

http://www.w3schools.com/soap/soap_example.asp


Since lately the above plugin  is failing, I am not using this one, the Poster plugin

Dissecting the OSB JMS Reporting Provider

I have created a new Oracle user DEV_SOAINFRA, granted all privileges, created the reporting tables as per Oracle_OSB1/dbscripts/oracle/reporting_runtime.sql script.

In WL Console I have created a DataSource pointing to this schema,
using wlsbjmsrpDataSource as JNDI name (I first needed to rename the existing Derby datasource JNDI name, otherwise it would give conflict).

I restarted WebLogic, because the JNDI entry was being cached by the provider and it would keep pointing to Derby.

Each time I do a Report action, a row is created in WLI_QS_REPORT_DATA and in WLI_QS_REPORT_ATTRIBUTE tables.

WLI_QS_REPORT_DATA.DATA_VALUE (blob) contains the data associated with the Report action (if you do "report $body", the payload will end up here)

the labels are in WLI_QS_REPORT_ATTRIBUTE.MSG_LABELS, in a list:

keyone=24;keytwo=pierre


WLI_QS_REPORT_ATTRIBUTE.INBOUND_SERVICE_NAME is filled with ProxyService$ReportingTest$reportingPS
(ReportingTest = project name, reportingPS = proxy name)

WLI_QS_REPORT_ATTRIBUTE.INBOUND_SERVICE_URI = /ReportingTest/reportingPS

WLI_QS_REPORT_ATTRIBUTE.OUTBOUND* are NULL, such as WLI_QS_REPORT_ATTRIBUTE.*

WLI_QS_REPORT_ATTRIBUTE.STATE = REQUEST

node, pipeline name and stage info are duly filled.



Things change radically if the Report action is in a Error Handler.
I trigger the error with a "Raise Error" action, error code="MYERRORCODE" and error reason "MYERRORREASON".

This is the $fault originated:

<con:fault   xmlns:con="http://www.bea.com/wli/sb/context">
 <con:errorCode>MYERRORCODE</con:errorCode>
 <con:reason>MYERRORREASON</con:reason>
 <con:location>
 <con:node>PipelinePairNode1</con:node>
 <con:pipeline>PipelinePairNode1_request</con:pipeline>
 <con:stage>stage1</con:stage>
 <con:path>request-pipeline</con:path>
 </con:location>
 </con:fault>



In this case:


WLI_QS_REPORT_ATTRIBUTE.STATE = ERROR

WLI_QS_REPORT_ATTRIBUTE.ERROR_CODE = MYERRORCODE

WLI_QS_REPORT_ATTRIBUTE.ERROR_REASON = MYERRORREASON


and all the node, pipeline name and stage info are blank.

WLI_QS_REPORT_ATTRIBUTE.ERROR_DETAILS is empty




The ReportingMDB consumes messages from the JMS queue wli.reporting.jmsprovider.queue, and inserts them into the DB.
If you pause consumption on the jmsResources!wli.reporting.jmsprovider.queue you can see the XML message itself, which is a:

ObjectMessage[ID:<997757.1312300601672.0>,com.bea.wli.reporting.jmsprovider.runtime.ReportMessage@368701b]

with some custom JMS properties like
REPORTINGDATATYPE=2
MSGTYPE=1

the meaning of REPORTINGDATATYPE should be:
STRING_MSGCONTENT = 1;
XML_MSGCONTENT = 2;
BINARY_MSGCONTENT = 3;

as defined in com.bea.wli.reporting.jmsprovider.utils.ReportingConstants

The ReportingMDB is deployed as a EJB module of:
C:\Oracle\Middleware\Oracle_OSB1\lib\common\jmsreportprovider.ear

Connecting to Derby with Eclipse

I have posted how to connect with NetBeans


With Eclipse:

Windows/Open Perspective/Database Development
Database Connections/New/Derby , name derbyLocal


database location = //localhost:1527/osbexamples;create=true;ServerName=localhost;databaseName=osbexamples

username = DEV_SOAINFRA
password = DEV_SOAINFRA or welcome1

save password


test connection

if you get

java.lang.Exception: Connection failed with unspecified error. at org.eclipse.datatools.connectivity.DriverConnectionBase.internalCreateConnection(DriverConnectionBase.java:110)


then you are screwed - what a crappy error message is that, "unspecified error".... this is ridiculous!




you can still use

C:\Oracle\Middleware\wlserver_10.3\common\derby\bin\ij.bat

see here for manual

for help type:
help;

(don' forget the ";" at the end)


I give up. I will just switch to Oracle DB. Screw Derby.

Monday, August 1, 2011

JMS Reporting Provider is not deployed, or it is not active

Provider Not Available
JMS Reporting Provider is not deployed, or it is not active


If you get this message when you click on Operations/Message Reports

open WL console,
check if "JMS Reporting Provider" is deployed;

this application should use the
Module jmsResources ->
Queue wli.reporting.jmsprovider.queue ->
Server wlsbJMSServer

and the wlsbjmsrpDataSource - mapped to a DB

When you do a Report action, a message is queued to the JMS queue, and asynchronously dequeued to the DB.

PurgingMDB listens on the queue wli.reporting.purge.queue, which is part of the same module jmsResources .

DB scripts are in $ORACLE_HOME/Oracle_OSB1/dbscripts/oracle/reporting_runtime.sql, tables WLI_QS_REPORT_ATTRIBUTE and WLI_QS_REPORT_DATA

The JMS Reporting Provider is in $ORACLE_HOME/Oracle_OSB1/lib/common/jmsreportprovider.ear, so you can redeploy it from there.




See here for list of resources


Here the full doc on reporting

Here how to untarget the JMS Reporter

Build path entry is missing: GROOVY_SUPPORT

in Eclipse, after installing the Groovy Plugin, I add library "Groovy Runtime Libraries" to my project:



If I define (Window/Preferences/Java/BuildPath/Classpath variables)

GROOVY_SUPPORT=C:/Oracle4/Middleware/oepe_11gR1PS3/plugins/org.codehaus.groovy_1.8.0.xx-20110627-1300-e36/lib/groovy-all-1.8.0.jar


all is fine, and my first test of embedding Groovy into Java works:

package com.pierre.osb;

import groovy.lang.Binding;
import groovy.lang.GroovyShell; 

public class GroovyCalloutTest {
 public static void main(String[] args) {
  GroovyCalloutTest test = new GroovyCalloutTest();
  test.run();
 }

 private void run() {
  // call groovy expressions from Java code
  Binding binding = new Binding();
  binding.setVariable("foo", new Integer(2));
  GroovyShell shell = new GroovyShell(binding);

  Object value = shell.evaluate("println 'Hello World!'; x = 123; return foo * 10");
  System.out.println("value=" + value);
  
 }
}



Groovy WSDL Parser

class PVWSDLParser {
 public static void main(String[] args) {
  PVWSDLParser parser = new PVWSDLParser();
  parser.parse("/path/to/your.wsdl");
 }
 
 public void parse(String filename) {
  
  def nsxsd = new groovy.xml.Namespace("http://www.w3.org/2001/XMLSchema", 'xsd')
  def nswsdl = new groovy.xml.Namespace("http://schemas.xmlsoap.org/wsdl/", 'wsdl')
  
  def wsdlDocument = new XmlParser().parse(new File(filename));
  def targetNamespace = wsdlDocument.'@targetNamespace';
  
  def imports = wsdlDocument[nswsdl.types][nsxsd.schema][nsxsd.import];
  imports.each { theimport ->
   System.out.println(theimport.'@schemaLocation');  
   System.out.println(theimport.'@namespace');
  } 
 }
}



A LOT easier than in Java!

ORA-44410: XE edition single instance violation error

I am trying to run Oracle XE on Oracle Virtual Box

/oracle/db/xe/app/oracle/product/10.2.0/server/bin/sqlplus

"Error 6 initializing SQL*Plus
Message file sp1<lang>.msb not found
SP2-0750: You may need to set ORACLE_HOME to your Oracle software directory
"


cd
vi .bash_profile

export ORACLE_BASE=/oracle/db/xe/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/server/
export ORACLE_SID=XE

PATH=$PATH:$HOME/bin:$ORACLE_HOME/bin



source .bash_profile

sqlplus / as sysdba

"connected to an idle instance"

select * from dual
"ORA-01034: ORACLE not available"

startup

"ORA-44410: XE edition single instance violation error"

shutdown abort
"ORACLE instance shut down"

startup
"ORA-44410: XE edition single instance violation error"

GRRRRRR!


lsnrctl status

"Instance "PLSExtProc", status UNKNOWN"


The solution is provided by Paulo (thank you soooo much) in his comment:


I've run into the exactly same problem and made exactly the same mistake:

export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/server/

Remove the trailing backslash from the path. Also add TNS_ADMIN. Here is my complete .bash_profile:

$ cat .bash_profile
export ORACLE_BASE=/usr/lib/oracle/xe/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/server
export ORACLE_SID=XE
export TNS_ADMIN=$ORACLE_HOME/network/admin
export PATH=$PATH:$ORACLE_HOME/bin