Beranda · · · ·

New Hung Threads with BO SDK - Solution By Patricbensen

Many developers seem to be facing the dreaded 'Hung threads' issue when they you the BO SDK in their java applications.

The symptoms:
The issue usually manifests itself with a line in the SystemOut.log or equivalent reporting the following:
WSVR0605W: Thread "THREAD NAME : ID" (55c8824f) has been active for 600,112 milliseconds and may be hung. There are 1 threads in total in the server that may be hung.

If you do a thread dump in your App Server at this point, you will see something like so:

- waiting on <0x93d29020> (a java.lang.Object)
at java.lang.Object.wait(Object.java:429)
at com.crystaldecisions.thirdparty.com.ooc.OB.Downcall.waitUntilCompleted(Downcall.java:831)
- locked <0x93d29020> (a java.lang.Object)
at com.crystaldecisions.thirdparty.com.ooc.OB.GIOPClientWorkerThreaded.receive(GIOPClientWorkerThreaded.java:327)
at com.crystaldecisions.thirdparty.com.ooc.OB.GIOPClientWorkerThreaded.sendReceive(GIOPClientWorkerThreaded.java:353)
at com.crystaldecisions.thirdparty.com.ooc.OB.Downcall.request(Downcall.java:336)
at com.crystaldecisions.thirdparty.com.ooc.OB.DowncallStub.invoke(DowncallStub.java:583)
at com.crystaldecisions.thirdparty.com.ooc.CORBA.Delegate.invoke(Delegate.java:579)
at com.crystaldecisions.thirdparty.org.omg.CORBA.portable.ObjectImpl._invoke(ObjectImpl.java:125)
at com.crystaldecisions.enterprise.ocaframework.idl.OCA.OCAi._InfoStoreEx3Stub.queryEx3(_InfoStoreEx3Stub.java:62)
at com.crystaldecisions.enterprise.ocaframework.j.a(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.j.find(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.AbstractServerHandler.buildServerInfo(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.AbstractServerHandler.buildClusterInfo(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.aa.for(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.ServiceMgr.for(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.o.a(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.o.a(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.o.a(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.p.a(Unknown Source)
at com.crystaldecisions.enterprise.ocaframework.ServiceMgr.getManagedService(Unknown Source)
at com.crystaldecisions.sdk.occa.managedreports.ras.internal.CECORBACommunicationAdapter.connect(Unknown Source)
at com.crystaldecisions.sdk.occa.managedreports.ras.internal.RASReportAppFactory.a(Unknown Source)
at com.crystaldecisions.sdk.occa.managedreports.ras.internal.RASReportAppFactory.a(Unknown Source)
at com.crystaldecisions.sdk.occa.managedreports.ras.internal.RASReportAppFactory.openDocument(Unknown Source)
at com.crystaldecisions.sdk.occa.managedreports.ras.internal.RASReportAppFactory.openDocument(Unknown Source)
at com.talic.pi.utils.ReportingEngine.generateReport(ReportingEngine.java:86)
at com.talic.pi.cms.dao.ReportsDAO.generateReport(ReportsDAO.java:31)
at com.talic.pi.cms.component.ReportGeneratorComponentImpl.generateReport(ReportGeneratorComponentImpl.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at com.ibm.ws.sca.internal.java.handler.JavaReflectionAdapter$2.run(JavaReflectionAdapter.java:152)


The cause:
This is mainly caused by reports that take a great deal of time to execute causing the application server to report that the processing thread is 'hung'. A worse side effect of this is when the application server runs out of threads and is unable to process any further requests due to these hung threads.

The solution:
The problem is due to the fact that the Corba Timeout has not been set. You've missed the clientSDKOptions.xml in your deployment. This causes the RAS SDK to probably never timeout its call to the RAS.

Create a file called clientSDKOptions.xml and place it in your application's WEB-INF/classes folder, or alternatively, you could place it in a server wide classpath folder like 'applib' on OC4J or $WASPROFILE/properties on WebSphere.
The contents of the file should be as follows:


<CrystalReports.ClientSDKOptions
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
version="2"
xsi:type="CrystalReports.ClientSDKOptions">
<CORBARequestTimeout>120000</CORBARequestTimeout>
</CrystalReports.ClientSDKOptions>

Restart your app and your done. Your call should now timeout within 2 minutes (something with you can change) and you can say goodbye to your Hung Threads issue.

New Install and configure CVS on Solaris 10 By Patricbensen

Download the appropriate binary from
http://www.nongnu.org/cvs

# create a "cvs" user. This user will be used to impersonate cvs' users
$ mkdir  /export/home/cvsroot
$ useradd -d /home/cvs -c "CVS Owner" cvs
# create the CVS repository
$ cvs -d /path_to_repository
#Add the following to /etc/services
cvspserver 2401/tcp # CVS Client/server operations
cvspserver 2401/udp # CVS Client/server operations
#Place this following line in a file called "cvs_inetd"
cvspserver stream tcp nowait root /path_to_cvs_executable -f \
--allow-root=/path_to_cvs_repository pserver

# import the service into smf
$ inetconv -f -i ./cvs_inetd
cvspserver -> /var/svc/manifest/network/cvspserver-tcp.xml
Importing cvspserver-tcp.xml …Done
#Add the following lines to /var/svc/profile/inetd_services.xml
<service name='network/cvspserver-tcp' version='1' type='service'>
<instance name='default' enabled='true'/>
</service>
#Restart the network
$ svcadm restart svc:/network/inetd:default

You're done. Your pserver should be listening on port 2401

#Script to create cvs users

#!/usr/bin/perl

$cvsroot="/path_to_cvs_root";

$user = shift @ARGV || die "cvspasswd user\n";
print "Enter password for $user: ";
system "stty -echo";
chomp ($plain = <>);
system "stty echo";
print "\n";
@chars = ('A'..'Z', 'a'..'z', '0'..'9');
$salt = $chars[rand(@chars)] . $chars[rand(@chars)];
$passwd = crypt($plain, $salt);
open(PASSWD,">>$cvsroot/CVSROOT/passwd") || die("Cannot Open File");
print PASSWD "$user:$passwd:cvs\n";
close PASSWD;
#-End

$ perl createcvspasswd.pl your_cvs_user

New Improve windows networking (especially if hosting webservers) By Patricbensen


First of all, I forgive you for having to use windows to host your web server :)

Now that thats out of the way, here's how you speed up networking performance on windows (especially if you happen to host Apache, IBM HTTP Server, or any other web server on a windows machine)

Create a .reg file (eg: perf.reg) with the contents that follow:


Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters]
"MaxUserPort"=dword:00008000
"TcpTimedWaitDelay"=dword:0000001e
"TcpMaxDataRetransmissions"=dword:00000005

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces]
"TcpAckFrequency"=dword:00000001
"TcpDelAckTicks"=dword:00000000

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters]
"EnableDynamicBacklog"=dword:00000001
"MinimumDynamicBacklog"=dword:00000020
"MaximumDynamicBacklog"=dword:00001000
"DynamicBacklogGrowthDelta"=dword:00000010
"KeepAliveInterval"=dword:00000001

Double click on the file to merge its contents into the registry. Restart the machine.
You're done.


New SSH Port Forwarding, X11 fowarding, RDP tunneling and much more By Patricbensen

The only firewall port you'll ever need opened - PORT 22

SSH Tunneling/Port Forwarding

Pre requisites:

1. Putty (or an equally good ssh client that allows creation of ssh tunnels)
2. Xming (X Server)

3. root access to the ssh server (if you need to modify the /etc/ssh/sshd_config) file

On the server:
Edit /etc/ssh/sshd_config and confirm that the configuration is as below:

AllowTcpForwarding yes
X11Forwarding yes
X11DisplayOffset 10
X11UseLocalhost yes

Close the file and execute the following command (if you’ve changed the f
ile)
$ svcadm restart ssh

SSH Tunneling is a feature that lets you create 'tunnels of TCP traffic' from the client through to the ssh server over your SSH connection.

See the diagram below:



You can create as many 'tunnels' as you like from the client. All you need to create this tunnel is:
1. The local port -> Local end of the tunnel
2. The remote host and port -> Location where you want your TCP packets to finally reach.

Note: The remote end of the tunnel is the SSH server. This implies that your communication channel is encrypted only from your client to your SSH server (which shouldn't be a problem if your SSH server and the servers you want to finally connect to are all on the same trusted network)


Now for some fun:

RDP Tunneling
Lets say you want to access the machine running XP using windows using Remote Desktop client from your local machine that's outside the firewall.

Step 1: CREATE THE TUNNEL

The general syntax is:
D:\>putty –L [local port]:[remote machine]:[remote port] [ssh server]

a. Choose a local port say 30001, for the local end of the tunnel. See that it is not already in use.
b. Execute the command to create the tunnel:
D:\>putty –L 30001:mymac:3389 mysshserver
Enter the username and password in the putty window that pops up.

You're done! You now have an encrypted tunnel from your machine to the ssh server to send tcp packets to the remote machine.

Step 2: USE THE TUNNEL

a. Connect to the remote machine from the local end of the tunnel :
D:\>mstsc –v localhost:30001

If you want to be extra naughty, you can even share you local disk drives with the remote computer ? like so:


X11 forwarding
If you want to do X11 forwarding, its really very simple.
Just ensure that the login on the ssh server doesnt have the DISPLAY environment set (in the .login/.bashrc_profile)

After that you'll need to do the following:





Now, start XMing on your desktop, open the putty session, login and type the following:
$ xclock &

You should see the XWindow pop up on your desktop.

Enjoy!

New WebSphere Process Server - File Adapter errors By Patricbensen

Once you deploy a mediation module containing a file adapter on a websphere process server and turn on global security, things start going bad.

This mess could manifest itself in very many ways, some of which I encountered are listed below along with their solutions



Problem 1:
Error message : SECJ5010E: Could not create default AuthenticationToken during propagation login. The following exception occurred: com.ibm.websphere.security.auth.WSLoginFailedException: Validation of LTPA token failed due to invalid keys or token type.

Fix: Upgrade WAS to at least 6.0.2.11 (WAS is currently at 6.0.2.27)
Create an entry in Admin Console->Global Security->Addition Properties->Custom properties :
com.ibm.ws.security.createTokenSubjectForAsynchLogin=true




Problem 2:
Error message: CWWBF0060E: Cannot find a specific session EJB component.Process for the process

Fix: Go to the resource view in WID, and clean the respective EJB project of the Module. Then go back to the business integration view and 'clean' the entire module.
You might have to shutdown and restart WID after this. Rebuild the project and deploy. The error will go away.




Problem 3:
Error message: com.ibm.websphere.sca.ServiceRuntimeException: caused by: java.lang.IllegalStateException: No implementation or binding handler was found to process this interaction

Fix: Uninstall the following iFix: 6.0.2.0-WS-WPS-IFJR28515.pak
Better still, upgrade to 6.0.2.4

General Warning about iFixes:
Expect every iFix emitted by IBM to break something in the existing product. You'll often hear of iFixes for iFixes and it is not funny, especially if you are in production. Your best bet is to avoid iFixes if possible.
Better still, upgrade to 6.0.2.4



Problem 4
The file adapter (inbound) doesn't work well at all on Solaris (or any unixy systems). The file adapter doesn't know when the file transfer to the inbound folder is completed and starts reading it the moment its poll interval time is up. The adapter works well on windows as windows locks the file during transfer.

Fix: There is none at this time, unless you just want to just transfer the file to another location without parsing it. (Create a 0 byte .done file for file that is placed in the inbound folder and programatically copy the original file to the destination location. The .done file will be transferred to the archive folder (if archiving is turned on))


Check out the following book that could help you work better with WPS:

New Update files in .war and .ear directly By Patricbensen

I have seen many applications (.war and .ear) that have their property files or resource bundles stored within the .war or .ear files.

When the time comes for deploying them into production you usually have to unzip the entire war/ear file, modify the property files or resource bundle file and zip the whole thing back up again. Sometimes, some lazy developers just want to sneak in a .class file too :)
Trust me, this can be a pain.


This is where a utility (open source, of course) called 7-zip (www.7-zip.org) comes in handy. It allows you to do all of the above, plus provides the best compression in this industry, does almost any compression format on the planet and the best-est of all, its free and open source.

Use it. Trust me, its great.



New WebSphere Portal Server migration Issues - Part I By Patricbensen

You've got WebSphere Portal Server 6.x comfortably hooked up to Oracle / Oracle RAC and then someone wants you to move to another Oracle installation (on a different machine possibly).

IBM has told you that all you need to do is export your database and import it into the other installation.


You're confident. You try it. You do a full=y export and do a full=y import into the new database, change your datasources to point to the new oracle instances, check all the connections and everything is fine.... start your server .... and BOOM!



Part I - tells you about this stack trace that you receive:

Unable to locate default library category Error while calling a function retrieveItemsByCMId of PLS data manager.
Unable to locate webContent library category Error while calling a function retrieveItemsByCMId of PLS data manager.
javax.jcr.RepositoryException: Error while calling a function retrieveItemsByCMId of PLS data manager.

What do you do Jack? Don't raise a PMR for one. The answer is simple for this one.
You're DBA has forgotten to check the tablespaces that were involved with the Oracle Instance for the Portal.

You'd need to tell the DBA (should you be so unlucky to have one who couldn't figure this out) to create the following tablespaces BEFORE the import.:


# These are for Oracle RAC. For plain, standalone Oracle, you'd specify the datafile location after the 'datafile' keyword

create tablespace ICMLFQ32 datafile size 300M autoextend on
next 10M maxsize UNLIMITED extent management local autoallocate;


create tablespace ICMLNF32 datafile size 25M autoextend on
next 10M maxsize UNLIMITED extent management local autoallocate;


create tablespace ICMVFQ04 datafile size 25M autoextend on
next 10M maxsize UNLIMITED extent management local autoallocate;


create tablespace ICMSFQ04 datafile size 150M autoextend on
next 10M maxsize UNLIMITED extent management local autoallocate;


create tablespace ICMLSNDX datafile size 10M autoextend on
next 10M maxsize UNLIMITED extent management local autoallocate;


Run the database import again and you'll be fine.


New Little's Law - Verify Performance Test Results By Patricbensen

Here is something I often use (and need to lookup) when I'm analyzing performance test reports.
Most of the time, these reports are nothing but nebulous and I have no choice but to go back to the basics.
Professor John D.C. Little

Here's the simple procedure I use to verify the sanity of the test:

Run a step load test. Get the following data from your load testing tool (averaged) per step:
1. Transactions per second

2. Hits per second
3. Think time
4. Response time

5. Number of virtual users being simulated.
6. Throughput (bytes)

Here's where the math starts:

Using Little's Law, you then then deduce the following:
Actual Number of Users in the System = (Response time + Think time) * Transactions per second

You can also verify the page size:
Page size = Throughput / Hits per second


You can tell if there is something wrong with your test bed If the actual number of users in the system given by Little's Law is different from the number of virtual users being pumped in by your load testing tool. i.e. if the number of users simulated by the testing tool is more than what you deduce by Little's Law, your system is probably just queuing those extra users. You'll also notice your response time will start to 'knee' once this starts to happen.

The main thing here is to do this calculation for an average of all points data points per step change in number of virtual users simulated.

New Change CVS default port on Solaris 10 By Patricbensen

Changing the default port (2401) of CVS on Solaris 10 is real easy.

1. Edit your /etc/services file
Change the following line:
cvspserver 2401/tcp #cvs pserver
to
cvspserver {new port}/tcp #cvs pserver

2. Execute the following commands:
# svcadm disable svc:/network/cvspserver/tcp:default
# svcadm enable svc:/network/cvspserver/tcp:default

and you're done!

Find out how to http://patricbensen.blogspot.com /2008/09/install-and-configure-cvs-on-solaris-10.html">install and configure CVS for Solaris 10 here.

New WebSphere Process Server / Portal Server with Oracle RAC By Patricbensen

If you're thinking that you'll get out-of-the-box Oracle RAC support for an IBM WebSphere Process Server or Portal Server installlation, you're sadly mistaken.

All the scripts that are generated by the installation process (for the oracle database) are for a standalone installation and will fail or make your DBA very angry if they are run on one of the RAC nodes!

Well, there's a way out, but you'd have to edit the scripts that these monstrous products generate.

For example:
You'll find a line like this in Portal server scripts:

create tablespace ICMLFQ32 datafile '/oracle/tb/ICMLFQ32_01.dbf' size 300M reuse autoextend on next 10M maxsize UNLIMITED extent management local autoallocate;

you'll have to change it to :

create tablespace ICMLFQ32 datafile size 300M autoextend on next 10M maxsize UNLIMITED extent management local autoallocate;

i.e. remove the location of the datafile specified.

There's another thing that you'd need to do if your using Oracle RAC as the datastore for WebSphere Process and WebSphere Portal Servers... change your JDBC string.

I got this tip from the an IBM developerworks article on Oracle RAC with Process Server

Change your datasource from:

jdbc:oracle:thin:@{hostname}:{port number}:{DBName}


to:
jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=
(ADDRESS=(PROTOCOL=TCP)(HOST= myoraclehost1.ibm.com)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST= myoraclehost2.ibm.com)(PORT=1521))
(FAILOVER=on)(LOAD_BALANCE=on)
(CONNECT_DATA=(SERVER=DEDICATED)
(SERVICE_NAME=dbservice)))

I should be posting more gotchas with the IBM stack .... check the 'IBM' tags

New Java - Create Zip file in memory By Patricbensen

I find myself writing and rewriting this piece of code whenever I want to zip a set of files (in memory) and return the zipped file back as an object in memory. I often use this when the user requests a download of multiple reports and the deployment environment doesn't allow for disk access.

I thought I'd post it here so that I could copy-paste it the next time I need it :) If you've stumbled upon this page, you're free to use the code below too!



private static byte[] createZip(Map files) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ZipOutputStream zipfile = new ZipOutputStream(bos);
Iterator i = files.keySet().iterator();
String fileName = null;
ZipEntry zipentry = null;
while (i.hasNext()) {
fileName = (String) i.next();
zipentry = new ZipEntry(fileName);
zipfile.putNextEntry(zipentry);
zipfile.write((byte[]) files.get(fileName));
}
zipfile.close();
return bos.toByteArray();
}

New iMac - Dual boot Mac OS X and Win XP with Shared Drive By Patricbensen



You've just got an iMAC; you want to dual boot it with XP; you want a shared partition where both, Mac and XP can read/write;
you've come to the right place!

The following is for the iMAC 300GB Hard disk, but you'd just need to change the numbers for other sized disks.

Here's what I wanted:
Partition 1: EFI (200M) (already present) <-Dont ever blow this up.
Partition 2: Mac (needs to be resized to 100G)
Partition 3: FAT 32 (to be shared between Mac OS and Win XP;size 166G)
Partition 4: Windows XP (FAT 32) (should be <32g,>

STEP 1 :
Install Mac OS X (if you haven't already) with one partition for the whole disk.

STEP 2 :
Create 3 partitions
(a) original JHFS+
(b) any partition that supports >100 G and not MSDOS (I've used HFS+)
(c) MS DOS partition for windows.
Command : sudo diskutil resizeVolume disk0s2 100G "HFS+" "Global" 166G "MS-DOS FAT32" "Windows" 31G

STEP 3 :
Make sure windows thinks it has to format the windows partition
Command : sudo dd if=/dev/zero of=/dev/rdisk0s4 bs=1m count=100

STEP 4:
Plop the win xp installation CD and reboot
Hit the Alt key during reboot and boot from CD
Once the setup enters the Windows Setup stage and lists the partitions that you can choose XP to be installed in, you should see only C:
If you see D:, you've messed up somewhere.
Format C: using FAT (quick format)
Install windows holding the ALT key everytime a reboot is asked for and booting into windows.
Once windows is installed, plop in the first Mac OS X CD and install bootcamp & drivers for all the devices (i-sight, bluetooth, wifi etc). Luckily, this is all automatic.

STEP 5:
Log into Mac OS and launch the Disk Utility program.
Select the volume called 'Global' and click the Erase tab.
Choose ms-dos as Volume Format and format this partition.

After this, you should be able to see the 'Global' partition in both Mac OS and WinXP.

Have fun!
P.S. Thanks to the folks at wiki.onmac.net for this wonderful article from which much of the above has been adapted.
P.P.S. Baigman shared ahttp://patricbensen.blogspot.com /2008/01/imac-dual-boot-mac-os-x-and-win-xp-with.html?showComment=1289876233814#c452012705514538304"> simpler way of doing this. I haven't tried it but let me know if it works well.